Skip to content

Commit d900dba

Browse files
thePunderWomankirjs
authored andcommitted
Revert "refactor(compiler): Remove the interpolation config (#64071)" (#64110)
This reverts commit 768a09d. PR Close #64110
1 parent 71cde35 commit d900dba

File tree

34 files changed

+339
-74
lines changed

34 files changed

+339
-74
lines changed

packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_component_linker_1.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import {
1010
compileComponentFromMetadata,
1111
ConstantPool,
1212
DeclarationListEmitMode,
13+
DEFAULT_INTERPOLATION_CONFIG,
1314
DeferBlockDepsEmitMode,
1415
ForwardRefHandling,
16+
InterpolationConfig,
1517
makeBindingParser,
1618
outputAst as o,
1719
ParsedTemplate,
@@ -93,6 +95,7 @@ export class PartialComponentLinkerVersion1<TStatement, TExpression>
9395
metaObj: AstObject<R3DeclareComponentMetadata, TExpression>,
9496
version: string,
9597
): R3ComponentMetadata<R3TemplateDependencyMetadata> {
98+
const interpolation = parseInterpolationConfig(metaObj);
9699
const templateSource = metaObj.getValue('template');
97100
const isInline = metaObj.has('isInline') ? metaObj.getBoolean('isInline') : false;
98101
const templateInfo = this.getTemplateInfo(templateSource, isInline);
@@ -106,6 +109,7 @@ export class PartialComponentLinkerVersion1<TStatement, TExpression>
106109

107110
const template = parseTemplate(templateInfo.code, templateInfo.sourceUrl, {
108111
escapedString: templateInfo.isEscaped,
112+
interpolationConfig: interpolation,
109113
range: templateInfo.range,
110114
enableI18nLegacyMessageIdFormat: false,
111115
preserveWhitespaces: metaObj.has('preserveWhitespaces')
@@ -240,6 +244,7 @@ export class PartialComponentLinkerVersion1<TStatement, TExpression>
240244
encapsulation: metaObj.has('encapsulation')
241245
? parseEncapsulation(metaObj.getValue('encapsulation'))
242246
: ViewEncapsulation.Emulated,
247+
interpolation,
243248
changeDetection: metaObj.has('changeDetection')
244249
? parseChangeDetectionStrategy(metaObj.getValue('changeDetection'))
245250
: ChangeDetectionStrategy.Default,
@@ -375,6 +380,27 @@ interface TemplateInfo {
375380
isEscaped: boolean;
376381
}
377382

383+
/**
384+
* Extract an `InterpolationConfig` from the component declaration.
385+
*/
386+
function parseInterpolationConfig<TExpression>(
387+
metaObj: AstObject<R3DeclareComponentMetadata, TExpression>,
388+
): InterpolationConfig {
389+
if (!metaObj.has('interpolation')) {
390+
return DEFAULT_INTERPOLATION_CONFIG;
391+
}
392+
393+
const interpolationExpr = metaObj.getValue('interpolation');
394+
const values = interpolationExpr.getArray().map((entry) => entry.getString());
395+
if (values.length !== 2) {
396+
throw new FatalLinkerError(
397+
interpolationExpr.expression,
398+
'Unsupported interpolation config, expected an array containing exactly two strings',
399+
);
400+
}
401+
return InterpolationConfig.fromArray(values as [string, string]);
402+
}
403+
378404
/**
379405
* Determines the `ViewEncapsulation` mode from the AST value's symbol name.
380406
*/

packages/compiler-cli/src/ngtsc/annotations/component/src/handler.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
CssSelector,
2121
DeclarationListEmitMode,
2222
DeclareComponentTemplateInfo,
23+
DEFAULT_INTERPOLATION_CONFIG,
2324
DeferBlockDepsEmitMode,
2425
DomElementSchemaRegistry,
2526
ExternalExpr,
@@ -950,6 +951,7 @@ export class ComponentDecoratorHandler
950951
template,
951952
encapsulation,
952953
changeDetection,
954+
interpolation: template.interpolationConfig ?? DEFAULT_INTERPOLATION_CONFIG,
953955
styles,
954956
externalStyles,
955957
// These will be replaced during the compilation step, after all `NgModule`s have been
@@ -1343,6 +1345,7 @@ export class ComponentDecoratorHandler
13431345
ctx.updateFromTemplate(
13441346
analysis.template.content,
13451347
analysis.template.declaration.resolvedTemplateUrl,
1348+
analysis.template.interpolationConfig ?? DEFAULT_INTERPOLATION_CONFIG,
13461349
);
13471350
}
13481351

@@ -2466,7 +2469,7 @@ export class ComponentDecoratorHandler
24662469

24672470
/** Creates a new binding parser. */
24682471
private getNewBindingParser() {
2469-
return makeBindingParser(this.enableSelectorless);
2472+
return makeBindingParser(undefined, this.enableSelectorless);
24702473
}
24712474
}
24722475

packages/compiler-cli/src/ngtsc/annotations/component/src/resources.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
*/
88

99
import {
10+
DEFAULT_INTERPOLATION_CONFIG,
11+
InterpolationConfig,
1012
LexerRange,
1113
ParsedTemplate,
1214
ParseSourceFile,
@@ -89,6 +91,7 @@ export interface ParsedTemplateWithSource extends ParsedComponentTemplate {
8991
*/
9092
interface CommonTemplateDeclaration {
9193
preserveWhitespaces: boolean;
94+
interpolationConfig: InterpolationConfig;
9295
templateUrl: string;
9396
resolvedTemplateUrl: string;
9497
}
@@ -281,13 +284,15 @@ export function createEmptyTemplate(
281284
declaration: templateUrl
282285
? {
283286
isInline: false,
287+
interpolationConfig: InterpolationConfig.fromArray(null),
284288
preserveWhitespaces: false,
285289
templateUrlExpression: templateUrl,
286290
templateUrl: 'missing.ng.html',
287291
resolvedTemplateUrl: '/missing.ng.html',
288292
}
289293
: {
290294
isInline: true,
295+
interpolationConfig: InterpolationConfig.fromArray(null),
291296
preserveWhitespaces: false,
292297
expression: template!,
293298
templateUrl: containingFile,
@@ -307,6 +312,7 @@ function parseExtractedTemplate(
307312
// We always normalize line endings if the template has been escaped (i.e. is inline).
308313
const i18nNormalizeLineEndingsInICUs = escapedString || options.i18nNormalizeLineEndingsInICUs;
309314
const commonParseOptions: ParseTemplateOptions = {
315+
interpolationConfig: template.interpolationConfig,
310316
range: sourceParseRange ?? undefined,
311317
enableI18nLegacyMessageIdFormat: options.enableI18nLegacyMessageIdFormat,
312318
i18nNormalizeLineEndingsInICUs,
@@ -373,6 +379,7 @@ export function parseTemplateDeclaration(
373379
preserveWhitespaces = value;
374380
}
375381

382+
let interpolationConfig = DEFAULT_INTERPOLATION_CONFIG;
376383
if (component.has('interpolation')) {
377384
const expr = component.get('interpolation')!;
378385
const value = evaluator.evaluate(expr);
@@ -387,6 +394,7 @@ export function parseTemplateDeclaration(
387394
'interpolation must be an array with 2 elements of string type',
388395
);
389396
}
397+
interpolationConfig = InterpolationConfig.fromArray(value as [string, string]);
390398
}
391399

392400
if (component.has('templateUrl')) {
@@ -403,6 +411,7 @@ export function parseTemplateDeclaration(
403411
const resourceUrl = resourceLoader.resolve(templateUrl, containingFile);
404412
return {
405413
isInline: false,
414+
interpolationConfig,
406415
preserveWhitespaces,
407416
templateUrl,
408417
templateUrlExpression: templateUrlExpr,
@@ -424,6 +433,7 @@ export function parseTemplateDeclaration(
424433
} else if (component.has('template')) {
425434
return {
426435
isInline: true,
436+
interpolationConfig,
427437
preserveWhitespaces,
428438
expression: component.get('template')!,
429439
templateUrl: containingFile,

packages/compiler-cli/src/ngtsc/xi18n/src/context.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9+
import {InterpolationConfig} from '@angular/compiler';
10+
911
/**
1012
* Captures template information intended for extraction of i18n messages from a template.
1113
*
@@ -21,5 +23,5 @@ export interface Xi18nContext {
2123
* the return type is declared as `void` for simplicity, since any parse errors would be reported
2224
* as diagnostics anyway.
2325
*/
24-
updateFromTemplate(html: string, url: string): void;
26+
updateFromTemplate(html: string, url: string, interpolationConfig: InterpolationConfig): void;
2527
}

packages/compiler/src/compiler_facade_interface.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
214214
styles: string[];
215215
encapsulation: ViewEncapsulation;
216216
viewProviders: Provider[] | null;
217+
interpolation?: [string, string];
217218
changeDetection?: ChangeDetectionStrategy;
218219
hasDirectiveDependencies: boolean;
219220
}
@@ -276,6 +277,7 @@ export interface R3DeclareComponentFacade extends R3DeclareDirectiveFacade {
276277
animations?: OpaqueValue;
277278
changeDetection?: ChangeDetectionStrategy;
278279
encapsulation?: ViewEncapsulation;
280+
interpolation?: [string, string];
279281
preserveWhitespaces?: boolean;
280282
}
281283

packages/compiler/src/expression_parser/parser.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import * as chars from '../chars';
10+
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../ml_parser/defaults';
1011
import {
1112
InterpolatedAttributeToken,
1213
InterpolatedTextToken,
@@ -101,9 +102,10 @@ export class Parser {
101102
input: string,
102103
parseSourceSpan: ParseSourceSpan,
103104
absoluteOffset: number,
105+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
104106
): ASTWithSource {
105107
const errors: ParseError[] = [];
106-
this._checkNoInterpolation(errors, input, parseSourceSpan);
108+
this._checkNoInterpolation(errors, input, parseSourceSpan, interpolationConfig);
107109
const {stripped: sourceToLex} = this._stripComments(input);
108110
const tokens = this._lexer.tokenize(sourceToLex);
109111
const ast = new _ParseAST(
@@ -124,9 +126,16 @@ export class Parser {
124126
input: string,
125127
parseSourceSpan: ParseSourceSpan,
126128
absoluteOffset: number,
129+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
127130
): ASTWithSource {
128131
const errors: ParseError[] = [];
129-
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, errors);
132+
const ast = this._parseBindingAst(
133+
input,
134+
parseSourceSpan,
135+
absoluteOffset,
136+
interpolationConfig,
137+
errors,
138+
);
130139
return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
131140
}
132141

@@ -141,9 +150,16 @@ export class Parser {
141150
input: string,
142151
parseSourceSpan: ParseSourceSpan,
143152
absoluteOffset: number,
153+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
144154
): ASTWithSource {
145155
const errors: ParseError[] = [];
146-
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, errors);
156+
const ast = this._parseBindingAst(
157+
input,
158+
parseSourceSpan,
159+
absoluteOffset,
160+
interpolationConfig,
161+
errors,
162+
);
147163
const simplExpressionErrors = this.checkSimpleExpression(ast);
148164

149165
if (simplExpressionErrors.length > 0) {
@@ -163,9 +179,10 @@ export class Parser {
163179
input: string,
164180
parseSourceSpan: ParseSourceSpan,
165181
absoluteOffset: number,
182+
interpolationConfig: InterpolationConfig,
166183
errors: ParseError[],
167184
): AST {
168-
this._checkNoInterpolation(errors, input, parseSourceSpan);
185+
this._checkNoInterpolation(errors, input, parseSourceSpan, interpolationConfig);
169186
const {stripped: sourceToLex} = this._stripComments(input);
170187
const tokens = this._lexer.tokenize(sourceToLex);
171188
return new _ParseAST(
@@ -236,13 +253,15 @@ export class Parser {
236253
parseSourceSpan: ParseSourceSpan,
237254
absoluteOffset: number,
238255
interpolatedTokens: InterpolatedAttributeToken[] | InterpolatedTextToken[] | null,
256+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
239257
): ASTWithSource | null {
240258
const errors: ParseError[] = [];
241259
const {strings, expressions, offsets} = this.splitInterpolation(
242260
input,
243261
parseSourceSpan,
244262
errors,
245263
interpolatedTokens,
264+
interpolationConfig,
246265
);
247266
if (expressions.length === 0) return null;
248267

@@ -357,6 +376,7 @@ export class Parser {
357376
parseSourceSpan: ParseSourceSpan,
358377
errors: ParseError[],
359378
interpolatedTokens: InterpolatedAttributeToken[] | InterpolatedTextToken[] | null,
379+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
360380
): SplitInterpolation {
361381
const strings: InterpolationPiece[] = [];
362382
const expressions: InterpolationPiece[] = [];
@@ -367,8 +387,7 @@ export class Parser {
367387
let i = 0;
368388
let atInterpolation = false;
369389
let extendLastString = false;
370-
const interpStart = '{{';
371-
const interpEnd = '}}';
390+
let {start: interpStart, end: interpEnd} = interpolationConfig;
372391
while (i < input.length) {
373392
if (!atInterpolation) {
374393
// parse until starting {{
@@ -473,17 +492,18 @@ export class Parser {
473492
errors: ParseError[],
474493
input: string,
475494
parseSourceSpan: ParseSourceSpan,
495+
{start, end}: InterpolationConfig,
476496
): void {
477497
let startIndex = -1;
478498
let endIndex = -1;
479499

480500
for (const charIndex of this._forEachUnquotedChar(input, 0)) {
481501
if (startIndex === -1) {
482-
if (input.startsWith('{{')) {
502+
if (input.startsWith(start)) {
483503
startIndex = charIndex;
484504
}
485505
} else {
486-
endIndex = this._getInterpolationEndIndex(input, '}}', charIndex);
506+
endIndex = this._getInterpolationEndIndex(input, end, charIndex);
487507
if (endIndex > -1) {
488508
break;
489509
}
@@ -493,7 +513,7 @@ export class Parser {
493513
if (startIndex > -1 && endIndex > -1) {
494514
errors.push(
495515
getParseError(
496-
`Got interpolation ({{}}) where expression was expected`,
516+
`Got interpolation (${start}${end}) where expression was expected`,
497517
input,
498518
`at column ${startIndex} in`,
499519
parseSourceSpan,

0 commit comments

Comments
 (0)