Skip to content

Commit c6cfd66

Browse files
authored
Support template literals in preProcess (fixes microsoft#33680) (microsoft#33688)
1 parent 0426e48 commit c6cfd66

File tree

2 files changed

+70
-7
lines changed

2 files changed

+70
-7
lines changed

src/services/preProcess.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ namespace ts {
8989
token = nextToken();
9090
if (token === SyntaxKind.OpenParenToken) {
9191
token = nextToken();
92-
if (token === SyntaxKind.StringLiteral) {
92+
if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NoSubstitutionTemplateLiteral) {
9393
// import("mod");
9494
recordModuleName();
9595
return true;
@@ -224,13 +224,14 @@ namespace ts {
224224
return false;
225225
}
226226

227-
function tryConsumeRequireCall(skipCurrentToken: boolean): boolean {
227+
function tryConsumeRequireCall(skipCurrentToken: boolean, allowTemplateLiterals = false): boolean {
228228
let token = skipCurrentToken ? nextToken() : scanner.getToken();
229229
if (token === SyntaxKind.RequireKeyword) {
230230
token = nextToken();
231231
if (token === SyntaxKind.OpenParenToken) {
232232
token = nextToken();
233-
if (token === SyntaxKind.StringLiteral) {
233+
if (token === SyntaxKind.StringLiteral ||
234+
allowTemplateLiterals && token === SyntaxKind.NoSubstitutionTemplateLiteral) {
234235
// require("mod");
235236
recordModuleName();
236237
}
@@ -249,7 +250,7 @@ namespace ts {
249250
}
250251

251252
token = nextToken();
252-
if (token === SyntaxKind.StringLiteral) {
253+
if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NoSubstitutionTemplateLiteral) {
253254
// looks like define ("modname", ... - skip string literal and comma
254255
token = nextToken();
255256
if (token === SyntaxKind.CommaToken) {
@@ -271,7 +272,7 @@ namespace ts {
271272
// scan until ']' or EOF
272273
while (token !== SyntaxKind.CloseBracketToken && token !== SyntaxKind.EndOfFileToken) {
273274
// record string literals as module names
274-
if (token === SyntaxKind.StringLiteral) {
275+
if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NoSubstitutionTemplateLiteral) {
275276
recordModuleName();
276277
}
277278

@@ -313,7 +314,10 @@ namespace ts {
313314
if (tryConsumeDeclare() ||
314315
tryConsumeImport() ||
315316
tryConsumeExport() ||
316-
(detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) {
317+
(detectJavaScriptImports && (
318+
tryConsumeRequireCall(/*skipCurrentToken*/ false, /*allowTemplateLiterals*/ true) ||
319+
tryConsumeDefine()
320+
))) {
317321
continue;
318322
}
319323
else {

src/testRunner/unittests/services/preProcessFile.ts

+60-1
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,65 @@ describe("unittests:: services:: PreProcessFile:", () => {
530530
isLibFile: false
531531
});
532532
});
533+
534+
it("Correctly handles dynamic imports with template literals", () => {
535+
test("const m1 = import('mod1');" + "\n" +
536+
"const m2 = import(`mod2`);" + "\n" +
537+
"Promise.all([import('mod3'), import(`mod4`)]);" + "\n" +
538+
"import(/* webpackChunkName: 'module5' */ `mod5`);" + "\n",
539+
/*readImportFile*/ true,
540+
/*detectJavaScriptImports*/ false,
541+
{
542+
referencedFiles: [],
543+
typeReferenceDirectives: [],
544+
libReferenceDirectives: [],
545+
importedFiles: [
546+
{ fileName: "mod1", pos: 18, end: 22 },
547+
{ fileName: "mod2", pos: 45, end: 49 },
548+
{ fileName: "mod3", pos: 74, end: 78 },
549+
{ fileName: "mod4", pos: 90, end: 94 },
550+
{ fileName: "mod5", pos: 142, end: 146 }
551+
],
552+
ambientExternalModules: undefined,
553+
isLibFile: false
554+
});
555+
});
556+
557+
it("Correctly handles require calls with template literals in JS files", () => {
558+
test("const m1 = require(`mod1`);" + "\n" +
559+
"f(require(`mod2`));" + "\n" +
560+
"const a = { x: require(`mod3`) };" + "\n",
561+
/*readImportFile*/ true,
562+
/*detectJavaScriptImports*/ true,
563+
{
564+
referencedFiles: [],
565+
typeReferenceDirectives: [],
566+
libReferenceDirectives: [],
567+
importedFiles: [
568+
{ fileName: "mod1", pos: 19, end: 23 },
569+
{ fileName: "mod2", pos: 38, end: 42 },
570+
{ fileName: "mod3", pos: 71, end: 75 }
571+
],
572+
ambientExternalModules: undefined,
573+
isLibFile: false
574+
});
575+
});
576+
577+
it("Correctly handles dependency lists in define(modName, [deplist]) calls with template literals in JS files", () => {
578+
test("define(`mod`, [`mod1`, `mod2`], (m1, m2) => {});",
579+
/*readImportFile*/ true,
580+
/*detectJavaScriptImports*/ true,
581+
{
582+
referencedFiles: [],
583+
typeReferenceDirectives: [],
584+
libReferenceDirectives: [],
585+
importedFiles: [
586+
{ fileName: "mod1", pos: 15, end: 19 },
587+
{ fileName: "mod2", pos: 23, end: 27 },
588+
],
589+
ambientExternalModules: undefined,
590+
isLibFile: false
591+
});
592+
});
533593
});
534594
});
535-

0 commit comments

Comments
 (0)