Skip to content

Commit 221d568

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

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,
@@ -954,6 +955,7 @@ export class ComponentDecoratorHandler
954955
template,
955956
encapsulation,
956957
changeDetection,
958+
interpolation: template.interpolationConfig ?? DEFAULT_INTERPOLATION_CONFIG,
957959
styles,
958960
externalStyles,
959961
// These will be replaced during the compilation step, after all `NgModule`s have been
@@ -1347,6 +1349,7 @@ export class ComponentDecoratorHandler
13471349
ctx.updateFromTemplate(
13481350
analysis.template.content,
13491351
analysis.template.declaration.resolvedTemplateUrl,
1352+
analysis.template.interpolationConfig ?? DEFAULT_INTERPOLATION_CONFIG,
13501353
);
13511354
}
13521355

@@ -2470,7 +2473,7 @@ export class ComponentDecoratorHandler
24702473

24712474
/** Creates a new binding parser. */
24722475
private getNewBindingParser() {
2473-
return makeBindingParser(this.enableSelectorless);
2476+
return makeBindingParser(undefined, this.enableSelectorless);
24742477
}
24752478
}
24762479

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,
@@ -102,9 +103,10 @@ export class Parser {
102103
input: string,
103104
parseSourceSpan: ParseSourceSpan,
104105
absoluteOffset: number,
106+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
105107
): ASTWithSource {
106108
const errors: ParseError[] = [];
107-
this._checkNoInterpolation(errors, input, parseSourceSpan);
109+
this._checkNoInterpolation(errors, input, parseSourceSpan, interpolationConfig);
108110
const {stripped: sourceToLex} = this._stripComments(input);
109111
const tokens = this._lexer.tokenize(sourceToLex);
110112
const ast = new _ParseAST(
@@ -125,9 +127,16 @@ export class Parser {
125127
input: string,
126128
parseSourceSpan: ParseSourceSpan,
127129
absoluteOffset: number,
130+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
128131
): ASTWithSource {
129132
const errors: ParseError[] = [];
130-
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, errors);
133+
const ast = this._parseBindingAst(
134+
input,
135+
parseSourceSpan,
136+
absoluteOffset,
137+
interpolationConfig,
138+
errors,
139+
);
131140
return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
132141
}
133142

@@ -142,9 +151,16 @@ export class Parser {
142151
input: string,
143152
parseSourceSpan: ParseSourceSpan,
144153
absoluteOffset: number,
154+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
145155
): ASTWithSource {
146156
const errors: ParseError[] = [];
147-
const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, errors);
157+
const ast = this._parseBindingAst(
158+
input,
159+
parseSourceSpan,
160+
absoluteOffset,
161+
interpolationConfig,
162+
errors,
163+
);
148164
const simplExpressionErrors = this.checkSimpleExpression(ast);
149165

150166
if (simplExpressionErrors.length > 0) {
@@ -164,9 +180,10 @@ export class Parser {
164180
input: string,
165181
parseSourceSpan: ParseSourceSpan,
166182
absoluteOffset: number,
183+
interpolationConfig: InterpolationConfig,
167184
errors: ParseError[],
168185
): AST {
169-
this._checkNoInterpolation(errors, input, parseSourceSpan);
186+
this._checkNoInterpolation(errors, input, parseSourceSpan, interpolationConfig);
170187
const {stripped: sourceToLex} = this._stripComments(input);
171188
const tokens = this._lexer.tokenize(sourceToLex);
172189
return new _ParseAST(
@@ -237,13 +254,15 @@ export class Parser {
237254
parseSourceSpan: ParseSourceSpan,
238255
absoluteOffset: number,
239256
interpolatedTokens: InterpolatedAttributeToken[] | InterpolatedTextToken[] | null,
257+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
240258
): ASTWithSource | null {
241259
const errors: ParseError[] = [];
242260
const {strings, expressions, offsets} = this.splitInterpolation(
243261
input,
244262
parseSourceSpan,
245263
errors,
246264
interpolatedTokens,
265+
interpolationConfig,
247266
);
248267
if (expressions.length === 0) return null;
249268

@@ -358,6 +377,7 @@ export class Parser {
358377
parseSourceSpan: ParseSourceSpan,
359378
errors: ParseError[],
360379
interpolatedTokens: InterpolatedAttributeToken[] | InterpolatedTextToken[] | null,
380+
interpolationConfig: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG,
361381
): SplitInterpolation {
362382
const strings: InterpolationPiece[] = [];
363383
const expressions: InterpolationPiece[] = [];
@@ -368,8 +388,7 @@ export class Parser {
368388
let i = 0;
369389
let atInterpolation = false;
370390
let extendLastString = false;
371-
const interpStart = '{{';
372-
const interpEnd = '}}';
391+
let {start: interpStart, end: interpEnd} = interpolationConfig;
373392
while (i < input.length) {
374393
if (!atInterpolation) {
375394
// parse until starting {{
@@ -474,17 +493,18 @@ export class Parser {
474493
errors: ParseError[],
475494
input: string,
476495
parseSourceSpan: ParseSourceSpan,
496+
{start, end}: InterpolationConfig,
477497
): void {
478498
let startIndex = -1;
479499
let endIndex = -1;
480500

481501
for (const charIndex of this._forEachUnquotedChar(input, 0)) {
482502
if (startIndex === -1) {
483-
if (input.startsWith('{{')) {
503+
if (input.startsWith(start)) {
484504
startIndex = charIndex;
485505
}
486506
} else {
487-
endIndex = this._getInterpolationEndIndex(input, '}}', charIndex);
507+
endIndex = this._getInterpolationEndIndex(input, end, charIndex);
488508
if (endIndex > -1) {
489509
break;
490510
}
@@ -494,7 +514,7 @@ export class Parser {
494514
if (startIndex > -1 && endIndex > -1) {
495515
errors.push(
496516
getParseError(
497-
`Got interpolation ({{}}) where expression was expected`,
517+
`Got interpolation (${start}${end}) where expression was expected`,
498518
input,
499519
`at column ${startIndex} in`,
500520
parseSourceSpan,

0 commit comments

Comments
 (0)