Content-Length: 411854 | pFad | https://github.com/angular/angular/commit/8b990a31c3f9b27e096c4ac63a7fa1873fadbe72

A5 fix(compiler): error if rawText isn't estimated correctly (#60529) · angular/angular@8b990a3 · GitHub
Skip to content

Commit 8b990a3

Browse files
crisbetoalxhub
authored andcommitted
fix(compiler): error if rawText isn't estimated correctly (#60529)
The `TemplateLiteralElementExpr` has some logic where it tries to estimate the `rawText` if one isn't provided by looking at the node's source span. The problem with this approach is that we have some long-standing issues with our expression AST parser (see #60267 (comment)) where it might not produce accurate spans if escape sequences are involved. This in turn can lead to unrecoverable errors, because TypeScript will throw an error if the raw string doesn't match the cooked one when constructing a TypeScript AST node. These changes remove the logic that depends on the source span and relies purely on the secondary fallback that inserts escaped characters manually. It's also worth noting that the `rawText` doesn't seem to matter much at this point, because the main usage of it is when downlevelling template literals to ES5 which we no longer support. Fixes #60528. PR Close #60529
1 parent d1510da commit 8b990a3

File tree

4 files changed

+13
-8
lines changed

4 files changed

+13
-8
lines changed

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "0.0.0-
750750
<div>No interpolations: {{ \`hello world \` }}</div>
751751
<span>With interpolations: {{ \`hello \${name}, it is currently \${timeOfDay}!\` }}</span>
752752
<p>With pipe: {{\`hello \${name}\` | uppercase}}</p>
753+
<h4>@let insideLet = \`Hello \${name}\`; Inside let: {{insideLet}}</h4>
753754
`, isInline: true, dependencies: [{ kind: "pipe", type: UppercasePipe, name: "uppercase" }] });
754755
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDER", ngImport: i0, type: MyApp, decorators: [{
755756
type: Component,
@@ -759,6 +760,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "0.0.0-PLACEHOLDE
759760
<div>No interpolations: {{ \`hello world \` }}</div>
760761
<span>With interpolations: {{ \`hello \${name}, it is currently \${timeOfDay}!\` }}</span>
761762
<p>With pipe: {{\`hello \${name}\` | uppercase}}</p>
763+
<h4>@let insideLet = \`Hello \${name}\`; Inside let: {{insideLet}}</h4>
762764
`,
763765
imports: [UppercasePipe],
764766
}]

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/template_literals.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ if (rf & 2) {
44
$r3$.ɵɵadvance(2);
55
$r3$.ɵɵtextInterpolate1("With interpolations: ", `hello ${ctx.name}, it is currently ${ctx.timeOfDay}!`);
66
$r3$.ɵɵadvance(2);
7-
$r3$.ɵɵtextInterpolate1("With pipe: ", $r3$.ɵɵpipeBind1(6, 3, `hello ${ctx.name}`));
7+
$r3$.ɵɵtextInterpolate1("With pipe: ", $r3$.ɵɵpipeBind1(6, 4, `hello ${ctx.name}`));
8+
const $insideLet_r1$ = `Hello ${ctx.name}`;
9+
$r3$.ɵɵadvance(4);
10+
$r3$.ɵɵtextInterpolate1(" Inside let: ", $insideLet_r1$);
811
}

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/template_literals.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class UppercasePipe {
1313
<div>No interpolations: {{ \`hello world \` }}</div>
1414
<span>With interpolations: {{ \`hello \${name}, it is currently \${timeOfDay}!\` }}</span>
1515
<p>With pipe: {{\`hello \${name}\` | uppercase}}</p>
16+
<h4>@let insideLet = \`Hello \${name}\`; Inside let: {{insideLet}}</h4>
1617
`,
1718
imports: [UppercasePipe],
1819
})

packages/compiler/src/output/output_ast.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -705,23 +705,22 @@ export class TemplateLiteralExpr extends Expression {
705705
}
706706
}
707707
export class TemplateLiteralElementExpr extends Expression {
708-
rawText: string;
708+
readonly rawText: string;
709709

710710
constructor(
711-
public text: string,
711+
readonly text: string,
712712
sourceSpan?: ParseSourceSpan | null,
713713
rawText?: string,
714714
) {
715715
super(STRING_TYPE, sourceSpan);
716716

717-
// If `rawText` is not provided, try to extract the raw string from its
718-
// associated `sourceSpan`. If that is also not available, "fake" the raw
719-
// string instead by escaping the following control sequences:
717+
// If `rawText` is not provided, "fake" the raw string by escaping the following sequences:
720718
// - "\" would otherwise indicate that the next character is a control character.
721719
// - "`" and "${" are template string control sequences that would otherwise prematurely
722720
// indicate the end of the template literal element.
723-
this.rawText =
724-
rawText ?? sourceSpan?.toString() ?? escapeForTemplateLiteral(escapeSlashes(text));
721+
// Note that we can't rely on the `sourceSpan` here, because it may be incorrect (see
722+
// https://github.com/angular/angular/pull/60267#discussion_r1986402524).
723+
this.rawText = rawText ?? escapeForTemplateLiteral(escapeSlashes(text));
725724
}
726725

727726
override visitExpression(visitor: ExpressionVisitor, context: any) {

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/angular/angular/commit/8b990a31c3f9b27e096c4ac63a7fa1873fadbe72

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy