diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 41845616bbe4b..0572c756c206d 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -345,6 +345,42 @@ namespace ts { break; } + if (scanner.getToken() === SyntaxKind.TemplateHead) { + const stack = [scanner.getToken()]; + loop: while (true) { + const token = scanner.getToken(); + switch (token) { + case SyntaxKind.EndOfFileToken: + break loop; + case SyntaxKind.ImportKeyword: + tryConsumeImport(); + break; + case SyntaxKind.TemplateHead: + stack.push(token); + break; + case SyntaxKind.OpenBraceToken: + if (length(stack)) { + stack.push(token); + } + break; + case SyntaxKind.CloseBraceToken: + if (length(stack)) { + if (lastOrUndefined(stack) === SyntaxKind.TemplateHead) { + if (scanner.reScanTemplateToken(/* isTaggedTemplate */ false) === SyntaxKind.TemplateTail) { + stack.pop(); + } + } + else { + stack.pop(); + } + } + break; + } + scanner.scan(); + } + nextToken(); + } + // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || tryConsumeImport() || diff --git a/src/testRunner/unittests/services/preProcessFile.ts b/src/testRunner/unittests/services/preProcessFile.ts index fb7a7e62649d4..d12e72af470f0 100644 --- a/src/testRunner/unittests/services/preProcessFile.ts +++ b/src/testRunner/unittests/services/preProcessFile.ts @@ -176,6 +176,117 @@ describe("unittests:: services:: PreProcessFile:", () => { }); }); + it("Correctly ignore commented imports following template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("/**" + "\n" + + " * Before" + "\n" + + " * ```" + "\n" + + " * import * as a from \"a\";" + "\n" + + " * ```" + "\n" + + " */" + "\n" + + "type Foo = `${string}`;" + "\n" + + "/**" + "\n" + + " * After" + "\n" + + " * ```" + "\n" + + " * import { B } from \"b\";" + "\n" + + " * import * as c from \"c\";" + "\n" + + " * ```" + "\n" + + " */", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns imports after a template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("`${foo}`; import \"./foo\";", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ true, + { + referencedFiles: [], + typeReferenceDirectives: [], + libReferenceDirectives: [], + importedFiles: [ + { fileName: "./foo", pos: 17, end: 22 } + ], + ambientExternalModules: undefined, + isLibFile: false + }); + /* eslint-enable no-template-curly-in-string */ + }); + + it("Correctly returns dynamic imports from template expression", () => { + /* eslint-disable no-template-curly-in-string */ + test("`${(