Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions src/services/preProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ namespace ts {
}
}

function isStringLiteralLike(token: SyntaxKind) {
return token === SyntaxKind.StringLiteral
|| token === SyntaxKind.NoSubstitutionTemplateLiteral;
}

/**
* Returns true if at least one token was consumed from the stream
*/
Expand Down Expand Up @@ -89,14 +94,16 @@ namespace ts {
token = nextToken();
if (token === SyntaxKind.OpenParenToken) {
token = nextToken();
if (token === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(token)) {
// import("mod");
// import(`mod`);
recordModuleName();
return true;
}
}
else if (token === SyntaxKind.StringLiteral) {
else if (isStringLiteralLike(token)) {
// import "mod";
// import `mod`;
recordModuleName();
return true;
}
Expand All @@ -105,8 +112,9 @@ namespace ts {
token = nextToken();
if (token === SyntaxKind.FromKeyword) {
token = nextToken();
if (token === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(token)) {
// import d from "mod";
// import d from `mod`
recordModuleName();
return true;
}
Expand Down Expand Up @@ -138,9 +146,10 @@ namespace ts {
token = nextToken();
if (token === SyntaxKind.FromKeyword) {
token = nextToken();
if (token === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(token)) {
// import {a as A} from "mod";
// import d, {a, b as B} from "mod"
// import d, {a, b as B} from `mod`
recordModuleName();
}
}
Expand All @@ -154,9 +163,10 @@ namespace ts {
token = nextToken();
if (token === SyntaxKind.FromKeyword) {
token = nextToken();
if (token === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(token)) {
// import * as NS from "mod"
// import d, * as NS from "mod"
// import d, * as NS from `mod`
recordModuleName();
}
}
Expand Down Expand Up @@ -188,9 +198,10 @@ namespace ts {
token = nextToken();
if (token === SyntaxKind.FromKeyword) {
token = nextToken();
if (token === SyntaxKind.StringLiteral) {
// export {a as A} from "mod";
if (isStringLiteralLike(token)) {
// export {a as A} from "mod"
// export {a, b as B} from "mod"
// export {a, b as B} from `mod`
recordModuleName();
}
}
Expand All @@ -200,8 +211,9 @@ namespace ts {
token = nextToken();
if (token === SyntaxKind.FromKeyword) {
token = nextToken();
if (token === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(token)) {
// export * from "mod"
// export * from `mod`
recordModuleName();
}
}
Expand Down Expand Up @@ -230,8 +242,9 @@ namespace ts {
token = nextToken();
if (token === SyntaxKind.OpenParenToken) {
token = nextToken();
if (token === SyntaxKind.StringLiteral) {
if (isStringLiteralLike(token)) {
// require("mod");
// require(`mod`);
recordModuleName();
}
}
Expand Down Expand Up @@ -294,15 +307,19 @@ namespace ts {
// import d, {a, b as B} from "mod"
// import i = require("mod");
// import("mod");
// import(`mod`);


// export * from "mod"
// export {a as b} from "mod"
// export import i = require("mod")
// (for JavaScript files) require("mod")
// (for JavaScript files) require(`mod`);

// Do not look for:
// AnySymbol.import("mod")
// AnySymbol.nested.import("mod")
// `import * as doh from 'ooops';`;

while (true) {
if (scanner.getToken() === SyntaxKind.EndOfFileToken) {
Expand Down
66 changes: 66 additions & 0 deletions src/testRunner/unittests/services/preProcessFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,72 @@ describe("unittests:: services:: PreProcessFile:", () => {
});
});

// https://github.com/microsoft/TypeScript/issues/33680#issue-500399194
it("Correctly return dynamically imported files using string literals", () => {
test("import(`r1.ts`);",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
libReferenceDirectives: [],
importedFiles: [{ fileName: "r1.ts", pos: 7, end: 12 }],
ambientExternalModules: undefined,
isLibFile: false
});
});

// https://github.com/microsoft/TypeScript/issues/33680#issue-500399194
it("Correctly return required files using string literals in JS", () => {
test("require(`r1.ts`);",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ true,
{
referencedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
libReferenceDirectives: [],
importedFiles: [{ fileName: "r1.ts", pos: 8, end: 13 }],
ambientExternalModules: undefined,
isLibFile: false
});
});

// https://github.com/microsoft/TypeScript/issues/33680#issue-500399194
it("Correctly return required files using string literals", () => {
test("import i = require(`r1.ts`);",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
libReferenceDirectives: [],
importedFiles: [{ fileName: "r1.ts", pos: 19, end: 24 }],
ambientExternalModules: undefined,
isLibFile: false
});
});

// https://github.com/microsoft/TypeScript/issues/33680#issue-500399194
it("Correctly return static imports using string literals", () => {
test("import d from `r1.ts`; import d, {a, b as B} from `r2.ts`; import d, * as NS from `r3.ts`; export {a, b as B} from `r4.ts`; export * from `r5.ts`;",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not valid JS/TS (#29318) should it be parsed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the only thing blocking the rest of the PR I am happy to roll the change back and open it in a separate request where we can then have the discussion?

Copy link
Contributor

@IllusionMH IllusionMH Jan 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then how's different from #33688 with previous roll back removed string literal detection removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logically they are very similar - I don't completely understand the reason for the introduction of https://github.com/microsoft/TypeScript/pull/33688/files#diff-23f96e78fc240e5f0198a9ffef3a69e4R227; however, I believe the way I structured the tests, updated the comments and implemented the union for literal likes is more in line with the rest of the codebase. When I opened the PR unfortunately I didn't see #33688, otherwise I could have based it on top.

Copy link
Contributor

@IllusionMH IllusionMH Feb 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because import mod = require(`mod`); is error in TS String literal expected. (Spec)
They have same validation as import mod from `mod`;

/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
libReferenceDirectives: [],
importedFiles: [
{ fileName: "r1.ts", pos: 14, end: 19 },
{ fileName: "r2.ts", pos: 50, end: 55 },
{ fileName: "r3.ts", pos: 82, end: 87 },
{ fileName: "r4.ts", pos: 115, end:120 },
{ fileName: "r5.ts", pos: 138, end:143 }
],
ambientExternalModules: undefined,
isLibFile: false
});
});

it("Correctly return imported files", () => {
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
/*readImportFile*/ true,
Expand Down