Skip to content

Commit 70d5f9c

Browse files
committed
Merge pull request microsoft#2140 from Microsoft/lsImportResolution
Support new import / export syntax in preProcessFile
2 parents 8abf4ff + 0a8d0a5 commit 70d5f9c

File tree

3 files changed

+168
-16
lines changed

3 files changed

+168
-16
lines changed

src/compiler/checker.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,10 @@ module ts {
745745
forEach(symbol.declarations, node => {
746746
if (node.kind === SyntaxKind.SourceFile || node.kind === SyntaxKind.ModuleDeclaration) {
747747
forEach((<ExportContainer>node).exportStars, exportStar => {
748-
visit(resolveExternalModuleName(exportStar, exportStar.moduleSpecifier));
748+
var moduleSymbol = resolveExternalModuleName(exportStar, exportStar.moduleSpecifier);
749+
if (moduleSymbol) {
750+
visit(moduleSymbol);
751+
}
749752
});
750753
}
751754
});

src/services/services.ts

+120-13
Original file line numberDiff line numberDiff line change
@@ -1795,34 +1795,141 @@ module ts {
17951795
});
17961796
}
17971797

1798+
function recordModuleName() {
1799+
var importPath = scanner.getTokenValue();
1800+
var pos = scanner.getTokenPos();
1801+
importedFiles.push({
1802+
fileName: importPath,
1803+
pos: pos,
1804+
end: pos + importPath.length
1805+
});
1806+
}
1807+
17981808
function processImport(): void {
17991809
scanner.setText(sourceText);
18001810
var token = scanner.scan();
18011811
// Look for:
1802-
// import foo = module("foo");
1812+
// import "mod";
1813+
// import d from "mod"
1814+
// import {a as A } from "mod";
1815+
// import * as NS from "mod"
1816+
// import d, {a, b as B} from "mod"
1817+
// import i = require("mod");
1818+
//
1819+
// export * from "mod"
1820+
// export {a as b} from "mod"
1821+
18031822
while (token !== SyntaxKind.EndOfFileToken) {
18041823
if (token === SyntaxKind.ImportKeyword) {
18051824
token = scanner.scan();
1806-
if (token === SyntaxKind.Identifier) {
1807-
token = scanner.scan();
1808-
if (token === SyntaxKind.EqualsToken) {
1825+
if (token === SyntaxKind.StringLiteral) {
1826+
// import "mod";
1827+
recordModuleName();
1828+
continue;
1829+
}
1830+
else {
1831+
if (token === SyntaxKind.Identifier) {
18091832
token = scanner.scan();
1810-
if (token === SyntaxKind.RequireKeyword) {
1833+
if (token === SyntaxKind.FromKeyword) {
18111834
token = scanner.scan();
1812-
if (token === SyntaxKind.OpenParenToken) {
1835+
if (token === SyntaxKind.StringLiteral) {
1836+
// import d from "mod";
1837+
recordModuleName();
1838+
continue
1839+
}
1840+
}
1841+
else if (token === SyntaxKind.EqualsToken) {
1842+
token = scanner.scan();
1843+
if (token === SyntaxKind.RequireKeyword) {
1844+
token = scanner.scan();
1845+
if (token === SyntaxKind.OpenParenToken) {
1846+
token = scanner.scan();
1847+
if (token === SyntaxKind.StringLiteral) {
1848+
// import i = require("mod");
1849+
recordModuleName();
1850+
continue;
1851+
}
1852+
}
1853+
}
1854+
}
1855+
else if (token === SyntaxKind.CommaToken) {
1856+
// consume comma and keep going
1857+
token = scanner.scan();
1858+
}
1859+
else {
1860+
// unknown syntax
1861+
continue;
1862+
}
1863+
}
1864+
1865+
if (token === SyntaxKind.OpenBraceToken) {
1866+
token = scanner.scan();
1867+
// consume "{ a as B, c, d as D}" clauses
1868+
while (token !== SyntaxKind.CloseBraceToken) {
1869+
token = scanner.scan();
1870+
}
1871+
1872+
if (token === SyntaxKind.CloseBraceToken) {
1873+
token = scanner.scan();
1874+
if (token === SyntaxKind.FromKeyword) {
18131875
token = scanner.scan();
18141876
if (token === SyntaxKind.StringLiteral) {
1815-
var importPath = scanner.getTokenValue();
1816-
var pos = scanner.getTokenPos();
1817-
importedFiles.push({
1818-
fileName: importPath,
1819-
pos: pos,
1820-
end: pos + importPath.length
1821-
});
1877+
// import {a as A} from "mod";
1878+
// import d, {a, b as B} from "mod"
1879+
recordModuleName();
18221880
}
18231881
}
18241882
}
18251883
}
1884+
else if (token === SyntaxKind.AsteriskToken) {
1885+
token = scanner.scan();
1886+
if (token === SyntaxKind.AsKeyword) {
1887+
token = scanner.scan();
1888+
if (token === SyntaxKind.Identifier) {
1889+
token = scanner.scan();
1890+
if (token === SyntaxKind.FromKeyword) {
1891+
token = scanner.scan();
1892+
if (token === SyntaxKind.StringLiteral) {
1893+
// import * as NS from "mod"
1894+
// import d, * as NS from "mod"
1895+
recordModuleName();
1896+
}
1897+
}
1898+
}
1899+
}
1900+
}
1901+
}
1902+
}
1903+
else if (token === SyntaxKind.ExportKeyword) {
1904+
token = scanner.scan();
1905+
if (token === SyntaxKind.OpenBraceToken) {
1906+
token = scanner.scan();
1907+
// consume "{ a as B, c, d as D}" clauses
1908+
while (token !== SyntaxKind.CloseBraceToken) {
1909+
token = scanner.scan();
1910+
}
1911+
1912+
if (token === SyntaxKind.CloseBraceToken) {
1913+
token = scanner.scan();
1914+
if (token === SyntaxKind.FromKeyword) {
1915+
token = scanner.scan();
1916+
if (token === SyntaxKind.StringLiteral) {
1917+
// export {a as A} from "mod";
1918+
// export {a, b as B} from "mod"
1919+
recordModuleName();
1920+
}
1921+
}
1922+
}
1923+
}
1924+
else if (token === SyntaxKind.AsteriskToken) {
1925+
token = scanner.scan();
1926+
if (token === SyntaxKind.FromKeyword) {
1927+
token = scanner.scan();
1928+
if (token === SyntaxKind.StringLiteral) {
1929+
// export * from "mod"
1930+
recordModuleName();
1931+
}
1932+
}
18261933
}
18271934
}
18281935
token = scanner.scan();

tests/cases/unittests/services/preProcessFile.ts

+44-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('PreProcessFile:', function () {
2626
var expectedImportedFile = expectedImportedFiles[i];
2727

2828
assert.equal(resultImportedFile.fileName, expectedImportedFile.fileName, "Imported file path does not match expected. Expected: " + expectedImportedFile.fileName + ". Actual: " + resultImportedFile.fileName + ".");
29-
29+
3030
assert.equal(resultImportedFile.pos, expectedImportedFile.pos, "Imported file position does not match expected. Expected: " + expectedImportedFile.pos + ". Actual: " + resultImportedFile.pos + ".");
3131

3232
assert.equal(resultImportedFile.end, expectedImportedFile.end, "Imported file length does not match expected. Expected: " + expectedImportedFile.end + ". Actual: " + resultImportedFile.end + ".");
@@ -37,7 +37,7 @@ describe('PreProcessFile:', function () {
3737
var expectedReferencedFile = expectedReferencedFiles[i];
3838

3939
assert.equal(resultReferencedFile.fileName, expectedReferencedFile.fileName, "Referenced file path does not match expected. Expected: " + expectedReferencedFile.fileName + ". Actual: " + resultReferencedFile.fileName + ".");
40-
40+
4141
assert.equal(resultReferencedFile.pos, expectedReferencedFile.pos, "Referenced file position does not match expected. Expected: " + expectedReferencedFile.pos + ". Actual: " + resultReferencedFile.pos + ".");
4242

4343
assert.equal(resultReferencedFile.end, expectedReferencedFile.end, "Referenced file length does not match expected. Expected: " + expectedReferencedFile.end + ". Actual: " + resultReferencedFile.end + ".");
@@ -108,6 +108,48 @@ describe('PreProcessFile:', function () {
108108
isLibFile: false
109109
})
110110
});
111+
112+
it("Correctly return ES6 imports", function () {
113+
test("import * as ns from \"m1\";" + "\n" +
114+
"import def, * as ns from \"m2\";" + "\n" +
115+
"import def from \"m3\";" + "\n" +
116+
"import {a} from \"m4\";" + "\n" +
117+
"import {a as A} from \"m5\";" + "\n" +
118+
"import {a as A, b, c as C} from \"m6\";" + "\n" +
119+
"import def , {a, b, c as C} from \"m7\";" + "\n",
120+
true,
121+
{
122+
referencedFiles: [],
123+
importedFiles: [
124+
{ fileName: "m1", pos: 20, end: 22 },
125+
{ fileName: "m2", pos: 51, end: 53 },
126+
{ fileName: "m3", pos: 73, end: 75 },
127+
{ fileName: "m4", pos: 95, end: 97 },
128+
{ fileName: "m5", pos: 122, end: 124 },
129+
{ fileName: "m6", pos: 160, end: 162 },
130+
{ fileName: "m7", pos: 199, end: 201 }
131+
],
132+
isLibFile: false
133+
})
134+
});
135+
136+
it("Correctly return ES6 exports", function () {
137+
test("export * from \"m1\";" + "\n" +
138+
"export {a} from \"m2\";" + "\n" +
139+
"export {a as A} from \"m3\";" + "\n" +
140+
"export {a as A, b, c as C} from \"m4\";" + "\n",
141+
true,
142+
{
143+
referencedFiles: [],
144+
importedFiles: [
145+
{ fileName: "m1", pos: 14, end: 16 },
146+
{ fileName: "m2", pos: 36, end: 38 },
147+
{ fileName: "m3", pos: 63, end: 65 },
148+
{ fileName: "m4", pos: 101, end: 103 },
149+
],
150+
isLibFile: false
151+
})
152+
});
111153
});
112154
});
113155

0 commit comments

Comments
 (0)