Skip to content

Commit ae135d3

Browse files
committed
fix(client): fix detection of Angular context after string interpolation (#1922)
This probably still has its own issues but seems to be at least an improvement over past scanner issues. It may be good to spend more time on the correctness of this or just `ts.createSourceFile`. This previously wasn't done due to perfomance concerns. fixes #1872 (cherry picked from commit bd6282e)
1 parent 892f796 commit ae135d3

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

client/src/embedded_support.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,23 @@ function isPropertyAssignmentToStringOrStringInArray(
7777
let lastTokenText: string|undefined;
7878
let unclosedBraces = 0;
7979
let unclosedBrackets = 0;
80+
let unclosedTaggedTemplates = 0;
8081
let propertyAssignmentContext = false;
82+
83+
function isTemplateStartOfTaggedTemplate() {
84+
return token === ts.SyntaxKind.NoSubstitutionTemplateLiteral ||
85+
token === ts.SyntaxKind.TemplateHead;
86+
}
87+
8188
while (token !== ts.SyntaxKind.EndOfFileToken && scanner.getStartPos() < offset) {
89+
if (isTemplateStartOfTaggedTemplate()) {
90+
unclosedTaggedTemplates++;
91+
}
92+
if (token === ts.SyntaxKind.CloseBraceToken && unclosedTaggedTemplates > 0) {
93+
// https://github.com/Microsoft/TypeScript/issues/20055
94+
token = scanner.reScanTemplateToken(/*isTaggedTemplate*/ true);
95+
unclosedTaggedTemplates--;
96+
}
8297
if (lastToken === ts.SyntaxKind.Identifier && lastTokenText !== undefined &&
8398
propertyAssignmentNames.includes(lastTokenText) && token === ts.SyntaxKind.ColonToken) {
8499
propertyAssignmentContext = true;

client/src/tests/embedded_support_spec.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,21 @@ describe('embedded language support', () => {
3838
it('at end of template', () => {
3939
test(`template: '<div></div>¦'`, isInsideInlineTemplateRegion, true);
4040
});
41+
42+
it('works for inline templates after a template string', () => {
43+
test(
44+
'const x = `${""}`;\n' +
45+
'template: `hello ¦world`',
46+
isInsideInlineTemplateRegion, true);
47+
});
48+
49+
it('works for inline templates after a tagged template string inside tagged template string',
50+
() => {
51+
test(
52+
'const x = `${`${""}`}`;\n' +
53+
'template: `hello ¦world`',
54+
isInsideInlineTemplateRegion, true);
55+
});
4156
});
4257

4358
describe('isInsideAngularContext', () => {
@@ -112,4 +127,4 @@ function extractCursorInfo(textWithCursor: string): {cursor: number, text: strin
112127
cursor,
113128
text: textWithCursor.substr(0, cursor) + textWithCursor.substr(cursor + 1),
114129
};
115-
}
130+
}

0 commit comments

Comments
 (0)