From 50abee3cd861dd766885c67d7ee9f15fba046f14 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 11 Jul 2017 07:24:31 -0700 Subject: [PATCH] Never return undefined from `getExportsOfModule` (#17019) --- src/compiler/checker.ts | 6 +++--- .../completionList_getExportsOfModule.ts | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/completionList_getExportsOfModule.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8158e5ecad8..cca5219e82e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1770,7 +1770,7 @@ namespace ts { function getExportsOfModule(moduleSymbol: Symbol): SymbolTable { const links = getSymbolLinks(moduleSymbol); - return links.resolvedExports || (links.resolvedExports = getExportsForModule(moduleSymbol)); + return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol)); } interface ExportCollisionTracker { @@ -1807,13 +1807,13 @@ namespace ts { }); } - function getExportsForModule(moduleSymbol: Symbol): SymbolTable { + function getExportsOfModuleWorker(moduleSymbol: Symbol): SymbolTable { const visitedSymbols: Symbol[] = []; // A module defined by an 'export=' consists on one export that needs to be resolved moduleSymbol = resolveExternalModuleSymbol(moduleSymbol); - return visit(moduleSymbol) || moduleSymbol.exports; + return visit(moduleSymbol) || emptySymbols; // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example, // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error. diff --git a/tests/cases/fourslash/completionList_getExportsOfModule.ts b/tests/cases/fourslash/completionList_getExportsOfModule.ts new file mode 100644 index 00000000000..0f28c3f1618 --- /dev/null +++ b/tests/cases/fourslash/completionList_getExportsOfModule.ts @@ -0,0 +1,16 @@ +/// + +// This used to cause a crash because we would ask for exports on `"x"`, +// which would return undefined and cause a NPE. Now we return emptySymbol instead. +// See GH#16610. + +////declare module "x" { +//// declare var x: number; +//// export = x; +////} +//// +////let y: /**/ + +goTo.marker(); +// This is just a dummy test to cause `getCompletionsAtPosition` to be called. +verify.not.completionListContains("x");