@@ -36,7 +36,7 @@ import {I18nContext} from './i18n/context';
36
36
import { createGoogleGetMsgStatements } from './i18n/get_msg_utils' ;
37
37
import { createLocalizeStatements } from './i18n/localize_utils' ;
38
38
import { I18nMetaVisitor } from './i18n/meta' ;
39
- import { assembleBoundTextPlaceholders , assembleI18nBoundString , declareI18nVariable , getTranslationConstPrefix , hasI18nMeta , I18N_ICU_MAPPING_PREFIX , i18nFormatPlaceholderNames , icuFromI18nMessage , isI18nRootNode , isSingleI18nIcu , placeholdersToParams , TRANSLATION_PREFIX , wrapI18nPlaceholder } from './i18n/util' ;
39
+ import { assembleBoundTextPlaceholders , assembleI18nBoundString , declareI18nVariable , getTranslationConstPrefix , hasI18nMeta , I18N_ICU_MAPPING_PREFIX , i18nFormatPlaceholderNames , icuFromI18nMessage , isI18nRootNode , isSingleI18nIcu , placeholdersToParams , TRANSLATION_VAR_PREFIX , wrapI18nPlaceholder } from './i18n/util' ;
40
40
import { StylingBuilder , StylingInstruction } from './styling_builder' ;
41
41
import { asLiteral , chainedInstruction , CONTEXT_NAME , getAttrsForDirectiveMatching , getInterpolationArgsLength , IMPLICIT_REFERENCE , invalid , NON_BINDABLE_ATTR , REFERENCE_PREFIX , RENDER_FLAGS , trimTrailingNulls , unsupported } from './util' ;
42
42
@@ -103,6 +103,18 @@ export function prepareEventListenerParameters(
103
103
return params ;
104
104
}
105
105
106
+ // Collects information needed to generate `consts` field of the ComponentDef.
107
+ // When a constant requires some pre-processing, the `prepareStatements` section
108
+ // contains corresponding statements.
109
+ export interface ComponentDefConsts {
110
+ prepareStatements : o . Statement [ ] ;
111
+ constExpressions : o . Expression [ ] ;
112
+ }
113
+
114
+ function createComponentDefConsts ( ) : ComponentDefConsts {
115
+ return { prepareStatements : [ ] , constExpressions : [ ] } ;
116
+ }
117
+
106
118
export class TemplateDefinitionBuilder implements t . Visitor < void > , LocalResolver {
107
119
private _dataIndex = 0 ;
108
120
private _bindingContext = 0 ;
@@ -171,7 +183,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
171
183
private directiveMatcher : SelectorMatcher | null , private directives : Set < o . Expression > ,
172
184
private pipeTypeByName : Map < string , o . Expression > , private pipes : Set < o . Expression > ,
173
185
private _namespace : o . ExternalReference , relativeContextFilePath : string ,
174
- private i18nUseExternalIds : boolean , private _constants : o . Expression [ ] = [ ] ) {
186
+ private i18nUseExternalIds : boolean ,
187
+ private _constants : ComponentDefConsts = createComponentDefConsts ( ) ) {
175
188
this . _bindingScope = parentBindingScope . nestedScope ( level ) ;
176
189
177
190
// Turn the relative context file path into an identifier by replacing non-alphanumeric
@@ -307,12 +320,12 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
307
320
private i18nTranslate (
308
321
message : i18n . Message , params : { [ name : string ] : o . Expression } = { } , ref ?: o . ReadVarExpr ,
309
322
transformFn ?: ( raw : o . ReadVarExpr ) => o . Expression ) : o . ReadVarExpr {
310
- const _ref = ref || o . variable ( this . constantPool . uniqueName ( TRANSLATION_PREFIX ) ) ;
323
+ const _ref = ref || this . i18nGenerateMainBlockVar ( ) ;
311
324
// Closure Compiler requires const names to start with `MSG_` but disallows any other const to
312
325
// start with `MSG_`. We define a variable starting with `MSG_` just for the `goog.getMsg` call
313
326
const closureVar = this . i18nGenerateClosureVar ( message . id ) ;
314
327
const statements = getTranslationDeclStmts ( message , _ref , closureVar , params , transformFn ) ;
315
- this . constantPool . statements . push ( ...statements ) ;
328
+ this . _constants . prepareStatements . push ( ...statements ) ;
316
329
return _ref ;
317
330
}
318
331
@@ -364,6 +377,12 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
364
377
return bound ;
365
378
}
366
379
380
+ // Generates top level vars for i18n blocks (i.e. `i18n_N`).
381
+ private i18nGenerateMainBlockVar ( ) : o . ReadVarExpr {
382
+ return o . variable ( this . constantPool . uniqueName ( TRANSLATION_VAR_PREFIX ) ) ;
383
+ }
384
+
385
+ // Generates vars with Closure-specific names for i18n blocks (i.e. `MSG_XXX`).
367
386
private i18nGenerateClosureVar ( messageId : string ) : o . ReadVarExpr {
368
387
let name : string ;
369
388
const suffix = this . fileBasedI18nSuffix . toUpperCase ( ) ;
@@ -426,16 +445,13 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
426
445
private i18nStart ( span : ParseSourceSpan | null = null , meta : i18n . I18nMeta , selfClosing ?: boolean ) :
427
446
void {
428
447
const index = this . allocateDataSlot ( ) ;
429
- if ( this . i18nContext ) {
430
- this . i18n = this . i18nContext . forkChildContext ( index , this . templateIndex ! , meta ) ;
431
- } else {
432
- const ref = o . variable ( this . constantPool . uniqueName ( TRANSLATION_PREFIX ) ) ;
433
- this . i18n = new I18nContext ( index , ref , 0 , this . templateIndex , meta ) ;
434
- }
448
+ this . i18n = this . i18nContext ?
449
+ this . i18nContext . forkChildContext ( index , this . templateIndex ! , meta ) :
450
+ new I18nContext ( index , this . i18nGenerateMainBlockVar ( ) , 0 , this . templateIndex , meta ) ;
435
451
436
452
// generate i18nStart instruction
437
453
const { id, ref} = this . i18n ;
438
- const params : o . Expression [ ] = [ o . literal ( index ) , ref ] ;
454
+ const params : o . Expression [ ] = [ o . literal ( index ) , this . addToConsts ( ref ) ] ;
439
455
if ( id > 0 ) {
440
456
// do not push 3rd argument (sub-block id)
441
457
// into i18nStart call for top level i18n context
@@ -507,8 +523,8 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
507
523
}
508
524
if ( i18nAttrArgs . length > 0 ) {
509
525
const index : o . Expression = o . literal ( this . allocateDataSlot ( ) ) ;
510
- const args = this . constantPool . getConstLiteral ( o . literalArr ( i18nAttrArgs ) , true ) ;
511
- this . creationInstruction ( sourceSpan , R3 . i18nAttributes , [ index , args ] ) ;
526
+ const constIndex = this . addToConsts ( o . literalArr ( i18nAttrArgs ) ) ;
527
+ this . creationInstruction ( sourceSpan , R3 . i18nAttributes , [ index , constIndex ] ) ;
512
528
if ( hasBindings ) {
513
529
this . updateInstruction ( sourceSpan , R3 . i18nApply , [ index ] ) ;
514
530
}
@@ -1028,7 +1044,7 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
1028
1044
return this . _pureFunctionSlots ;
1029
1045
}
1030
1046
1031
- getConsts ( ) {
1047
+ getConsts ( ) : ComponentDefConsts {
1032
1048
return this . _constants ;
1033
1049
}
1034
1050
@@ -1352,14 +1368,16 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
1352
1368
return o . TYPED_NULL_EXPR ;
1353
1369
}
1354
1370
1371
+ const consts = this . _constants . constExpressions ;
1372
+
1355
1373
// Try to reuse a literal that's already in the array, if possible.
1356
- for ( let i = 0 ; i < this . _constants . length ; i ++ ) {
1357
- if ( this . _constants [ i ] . isEquivalent ( expression ) ) {
1374
+ for ( let i = 0 ; i < consts . length ; i ++ ) {
1375
+ if ( consts [ i ] . isEquivalent ( expression ) ) {
1358
1376
return o . literal ( i ) ;
1359
1377
}
1360
1378
}
1361
1379
1362
- return o . literal ( this . _constants . push ( expression ) - 1 ) ;
1380
+ return o . literal ( consts . push ( expression ) - 1 ) ;
1363
1381
}
1364
1382
1365
1383
private addAttrsToConsts ( attrs : o . Expression [ ] ) : o . LiteralExpr {
0 commit comments