Fix and add tests for export * re-exports

This commit is contained in:
Andrew Branch committed 2019-07-29 10:21:34 -07:00
1 parent 670c8f6e47
commit 23daffe2ef
3 files changed
+111 -7

No files matched your search

+6 -7
View File
@@ -1349,18 +1349,17 @@ namespace ts.Completions {
}
for (const symbol of typeChecker.getExportsOfModule(moduleSymbol)) {
// If `symbol.parent !== ...`, this is an `export * from "foo"` re-export. Those don't create new symbols.
if (typeChecker.getMergedSymbol(symbol.parent!) !== resolvedModuleSymbol) {
continue;
}
// If this is `export { _break as break };` (a keyword) -- skip this and prefer the keyword completion.
if (some(symbol.declarations, d => isExportSpecifier(d) && !!d.propertyName && isIdentifierANonContextualKeyword(d.name))) {
continue;
}
// If `symbol.parent !== moduleSymbol`, this is an `export * from "foo"` re-export. Those don't create new symbols.
const isExportStarFromReExport = typeChecker.getMergedSymbol(symbol.parent!) !== resolvedModuleSymbol;
// If `!!d.parent.parent.moduleSpecifier`, this is `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check).
if (some(symbol.declarations, d => isExportSpecifier(d) && !d.propertyName && !!d.parent.parent.moduleSpecifier)) {
// Walk the export chain back one module (step 1 or 2 in diagrammed example)
const nearestExportSymbolId = getSymbolId(Debug.assertDefined(getNearestExportSymbol(symbol)));
if (isExportStarFromReExport || some(symbol.declarations, d => isExportSpecifier(d) && !d.propertyName && !!d.parent.parent.moduleSpecifier)) {
// Walk the export chain back one module (step 1 or 2 in diagrammed example).
// Or, in the case of `export * from "foo"`, `symbol` already points to the original export, so just use that.
const nearestExportSymbolId = getSymbolId(isExportStarFromReExport ? symbol : Debug.assertDefined(getNearestExportSymbol(symbol)));
const symbolHasBeenSeen = !!symbolToOriginInfoMap[nearestExportSymbolId] || aliasesToAlreadyIncludedSymbols.has(nearestExportSymbolId.toString());
if (!symbolHasBeenSeen) {
aliasesToReturnIfOriginalsAreMissing.set(nearestExportSymbolId.toString(), { alias: symbol, moduleSymbol });
@@ -0,0 +1,48 @@
/// <reference path="fourslash.ts" />
//@noEmit: true
//@Filename: /package.json
////{
//// "dependencies": {
//// "b": "*",
//// }
////}
//@Filename: /node_modules/a/index.d.ts
////export const foo = 0;
//@Filename: /node_modules/a/package.json
////{
//// "name": "a",
//// "types": "./index.d.ts"
////}
//@Filename: /node_modules/b/index.d.ts
////export * from "a";
//@Filename: /node_modules/b/package.json
////{
//// "name": "b",
//// "types": "./index.d.ts"
////}
//@Filename: /src/index.ts
////fo/**/
verify.completions({
marker: test.marker(""),
includes: [
completion.undefinedVarEntry,
{
name: "foo",
source: "/node_modules/b/index",
hasAction: true,
sortText: completion.SortText.AutoImportSuggestions
},
...completion.statementKeywordsWithTypes
],
preferences: {
includeCompletionsForModuleExports: true
}
});
@@ -0,0 +1,57 @@
/// <reference path="fourslash.ts" />
//@noEmit: true
//@Filename: /package.json
////{
//// "dependencies": {
//// "c": "*",
//// }
////}
//@Filename: /node_modules/a/index.d.ts
////export const foo = 0;
//@Filename: /node_modules/a/package.json
////{
//// "name": "a",
//// "types": "./index.d.ts"
////}
//@Filename: /node_modules/b/index.d.ts
////export * from "a";
//@Filename: /node_modules/b/package.json
////{
//// "name": "b",
//// "types": "./index.d.ts"
////}
//@Filename: /node_modules/c/index.d.ts
////export * from "a";
//@Filename: /node_modules/c/package.json
////{
//// "name": "c",
//// "types": "./index.d.ts"
////}
//@Filename: /src/index.ts
////fo/**/
verify.completions({
marker: test.marker(""),
includes: [
completion.undefinedVarEntry,
{
name: "foo",
source: "/node_modules/c/index",
hasAction: true,
sortText: completion.SortText.AutoImportSuggestions
},
...completion.statementKeywordsWithTypes
],
preferences: {
includeCompletionsForModuleExports: true
}
});