Skip to content

Commit ef1fd13

Browse files
crisbetoAndrewKushnir
authored andcommitted
fix(compiler): incorrect spans for template literals (#60323)
Fixes that we were producing zero-length spans for template literals and template literal elements. Fixes #60320. Fixes #60319. PR Close #60323
1 parent 35388c1 commit ef1fd13

File tree

2 files changed

+45
-26
lines changed

2 files changed

+45
-26
lines changed

packages/compiler/src/expression_parser/parser.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,9 +1449,10 @@ class _ParseAST {
14491449

14501450
private parseNoInterpolationTemplateLiteral(): TemplateLiteral {
14511451
const text = this.next.strValue;
1452+
const start = this.inputIndex;
14521453
this.advance();
1453-
const span = this.span(this.inputIndex);
1454-
const sourceSpan = this.sourceSpan(this.inputIndex);
1454+
const span = this.span(start);
1455+
const sourceSpan = this.sourceSpan(start);
14551456
return new TemplateLiteral(
14561457
span,
14571458
sourceSpan,
@@ -1474,14 +1475,15 @@ class _ParseAST {
14741475
const token = this.next;
14751476

14761477
if (token.isTemplateLiteralPart() || token.isTemplateLiteralEnd()) {
1478+
const partStart = this.inputIndex;
1479+
this.advance();
14771480
elements.push(
14781481
new TemplateLiteralElement(
1479-
this.span(this.inputIndex),
1480-
this.sourceSpan(this.inputIndex),
1482+
this.span(partStart),
1483+
this.sourceSpan(partStart),
14811484
token.strValue,
14821485
),
14831486
);
1484-
this.advance();
14851487
if (token.isTemplateLiteralEnd()) {
14861488
break;
14871489
}

packages/compiler/test/expression_parser/parser_spec.ts

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
PropertyRead,
1919
TemplateBinding,
2020
VariableBinding,
21+
TemplateLiteral,
2122
} from '@angular/compiler/src/expression_parser/ast';
2223
import {Lexer} from '@angular/compiler/src/expression_parser/lexer';
2324
import {Parser, SplitInterpolation} from '@angular/compiler/src/expression_parser/parser';
@@ -528,18 +529,34 @@ describe('parser', () => {
528529
expect(unparseWithSpan(ast)).toContain(['a.b = c', '[nameSpan] b']);
529530
});
530531

531-
it('should record template literal space', () => {
532+
it('should record spans for untagged template literals with no interpolations', () => {
533+
const ast = parseAction('`hello world`');
534+
const unparsed = unparseWithSpan(ast);
535+
expect(unparsed).toEqual([
536+
['`hello world`', '`hello world`'],
537+
['hello world', '`hello world`'],
538+
]);
539+
});
540+
541+
it('should record spans for untagged template literals with interpolations', () => {
532542
const ast = parseAction('`before ${one} - ${two} - ${three} after`');
533543
const unparsed = unparseWithSpan(ast);
534-
expect(unparsed).toContain(['before ', '']);
535-
expect(unparsed).toContain(['one', 'one']);
536-
expect(unparsed).toContain(['one', '[nameSpan] one']);
537-
expect(unparsed).toContain([' - ', '']);
538-
expect(unparsed).toContain(['two', 'two']);
539-
expect(unparsed).toContain(['two', '[nameSpan] two']);
540-
expect(unparsed).toContain(['three', 'three']);
541-
expect(unparsed).toContain(['three', '[nameSpan] three']);
542-
expect(unparsed).toContain([' after', '']);
544+
expect(unparsed).toEqual([
545+
['`before ${one} - ${two} - ${three} after`', '`before ${one} - ${two} - ${three} after`'],
546+
['before ', '`before '],
547+
['one', 'one'],
548+
['one', '[nameSpan] one'],
549+
['', ''], // Implicit receiver
550+
[' - ', ' - '],
551+
['two', 'two'],
552+
['two', '[nameSpan] two'],
553+
['', ''], // Implicit receiver
554+
[' - ', ' - '],
555+
['three', 'three'],
556+
['three', '[nameSpan] three'],
557+
['', ''], // Implicit receiver
558+
[' after', ' after`'],
559+
]);
543560
});
544561

545562
it('should record spans for tagged template literal with no interpolations', () => {
@@ -549,9 +566,9 @@ describe('parser', () => {
549566
['tag`text`', 'tag`text`'],
550567
['tag', 'tag'],
551568
['tag', '[nameSpan] tag'],
552-
['', ''],
553-
['`text`', ''],
554-
['text', ''],
569+
['', ''], // Implicit receiver
570+
['`text`', '`text`'],
571+
['text', '`text`'],
555572
]);
556573
});
557574

@@ -565,21 +582,21 @@ describe('parser', () => {
565582
],
566583
['tag', 'tag'],
567584
['tag', '[nameSpan] tag'],
568-
['', ''],
585+
['', ''], // Implicit receiver
569586
['`before ${one} - ${two} - ${three} after`', '`before ${one} - ${two} - ${three} after`'],
570-
['before ', ''],
587+
['before ', '`before '],
571588
['one', 'one'],
572589
['one', '[nameSpan] one'],
573-
['', ''],
574-
[' - ', ''],
590+
['', ''], // Implicit receiver
591+
[' - ', ' - '],
575592
['two', 'two'],
576593
['two', '[nameSpan] two'],
577-
['', ''],
578-
[' - ', ''],
594+
['', ''], // Implicit receiver
595+
[' - ', ' - '],
579596
['three', 'three'],
580597
['three', '[nameSpan] three'],
581-
['', ''],
582-
[' after', ''],
598+
['', ''], // Implicit receiver
599+
[' after', ' after`'],
583600
]);
584601
});
585602

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy