Missing import code fix - include export assignment properties when looking for module exports (#17376)

* Include export assignment properties when looking for module exports

* Create new API function for tryGetMemberInModuleExportsAndProperties

* Cleanup based on review feedback
This commit is contained in:
Mine Starks
2017-07-26 16:17:01 -07:00
committed by GitHub
parent cc8399dc41
commit 89994111bd
4 changed files with 34 additions and 1 deletions

View File

@@ -212,6 +212,7 @@ namespace ts {
return node ? isOptionalParameter(node) : false;
},
tryGetMemberInModuleExports: (name, symbol) => tryGetMemberInModuleExports(escapeLeadingUnderscores(name), symbol),
tryGetMemberInModuleExportsAndProperties: (name, symbol) => tryGetMemberInModuleExportsAndProperties(escapeLeadingUnderscores(name), symbol),
tryFindAmbientModuleWithoutAugmentations: moduleName => {
// we deliberately exclude augmentations
// since we are only interested in declarations of the module itself
@@ -1776,6 +1777,17 @@ namespace ts {
}
}
function tryGetMemberInModuleExportsAndProperties(memberName: __String, moduleSymbol: Symbol): Symbol | undefined {
const symbol = tryGetMemberInModuleExports(memberName, moduleSymbol);
if (!symbol) {
const exportEquals = resolveExternalModuleSymbol(moduleSymbol);
if (exportEquals !== moduleSymbol) {
return getPropertyOfType(getTypeOfSymbol(exportEquals), memberName);
}
}
return symbol;
}
function getExportsOfSymbol(symbol: Symbol): SymbolTable {
return symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : symbol.exports || emptySymbols;
}

View File

@@ -2581,6 +2581,8 @@ namespace ts {
getAmbientModules(): Symbol[];
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
/** Unlike `tryGetMemberInModuleExports`, this includes properties of an `export =` value. */
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
getApparentType(type: Type): Type;
getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined;
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;

View File

@@ -178,8 +178,11 @@ namespace ts.codefix {
}
}
// "default" is a keyword and not a legal identifier for the import, so we don't expect it here
Debug.assert(name !== "default");
// check exports with the same name
const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExports(name, moduleSymbol);
const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(name, moduleSymbol);
if (exportSymbolWithIdenticalName && checkSymbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
const symbolId = getUniqueSymbolId(exportSymbolWithIdenticalName);
symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, name));

View File

@@ -0,0 +1,16 @@
/// <reference path="fourslash.ts" />
//// [|bar/*0*/();|]
// @Filename: foo.ts
//// interface MyStatic {
//// bar(): void;
//// }
//// declare var x: MyStatic;
//// export = x;
verify.importFixAtPosition([
`import { bar } from "./foo";
bar();`
]);