diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 41845616bbe4b..561fa1b41d817 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -16,6 +16,7 @@ namespace ts { let lastToken: SyntaxKind; let currentToken: SyntaxKind; let braceNesting = 0; + let templateNesting = 0; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations let externalModule = false; @@ -23,12 +24,23 @@ namespace ts { function nextToken() { lastToken = currentToken; currentToken = scanner.scan(); - if (currentToken === SyntaxKind.OpenBraceToken) { + if (currentToken === SyntaxKind.CloseBraceToken && templateNesting > 0) { + currentToken = scanner.reScanTemplateToken(/* isTaggedTemplate */ true); + } + + if (currentToken === SyntaxKind.TemplateHead) { + templateNesting++; + } + else if (currentToken === SyntaxKind.TemplateTail) { + templateNesting--; + } + else if (currentToken === SyntaxKind.OpenBraceToken) { braceNesting++; } else if (currentToken === SyntaxKind.CloseBraceToken) { braceNesting--; } + return currentToken; } diff --git a/src/testRunner/unittests/services/preProcessFile.ts b/src/testRunner/unittests/services/preProcessFile.ts index c5f5672640144..64c18fd0e71de 100644 --- a/src/testRunner/unittests/services/preProcessFile.ts +++ b/src/testRunner/unittests/services/preProcessFile.ts @@ -659,5 +659,49 @@ describe("unittests:: services:: PreProcessFile:", () => { isLibFile: false }); }); + + it("Correctly ignores ES6 imports in string templates", () => { + test("`import def from 'm1'`;", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ false, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [], + ambientExternalModules: undefined, + isLibFile: false + }); + }); + it("Correctly ignores ES6 imports in string templates following another template", () => { + // eslint-disable-next-line no-template-curly-in-string + test("`${foo}`;\n`import def from 'm1'`;", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ false, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [], + ambientExternalModules: undefined, + isLibFile: false + }); + }); + it("Correctly recognizes ES6 imports after template", () => { + // eslint-disable-next-line no-template-curly-in-string + test("`${foo}`;\nimport def from 'm1';", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ false, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "m1", pos: 26, end: 28 }, + ], + ambientExternalModules: undefined, + isLibFile: false + }); + }); }); });