From 60df5377ad5a23b020417fa6e7ead98273e72ddc Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 4 Dec 2019 11:54:26 -0800 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20auto-import=20undefined?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/harness/fourslash.ts | 6 +-- src/services/completions.ts | 9 ++-- .../importSuggestionsCache_exportUndefined.ts | 43 +++++++++++++++++++ 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/server/importSuggestionsCache_exportUndefined.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 1123b0eb13a8e..4895a553bb459 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -854,9 +854,9 @@ namespace FourSlash { } } - assert.equal(actual.hasAction, hasAction); - assert.equal(actual.isRecommended, isRecommended); - assert.equal(actual.source, source); + assert.equal(actual.hasAction, hasAction, `Expected 'hasAction' value '${actual.hasAction}' to equal '${hasAction}'`); + assert.equal(actual.isRecommended, isRecommended, `Expected 'isRecommended' value '${actual.source}' to equal '${isRecommended}'`); + assert.equal(actual.source, source, `Expected 'source' value '${actual.source}' to equal '${source}'`); assert.equal(actual.sortText, sortText || ts.Completions.SortText.LocationPriority, this.messageAtLastKnownMarker(`Actual entry: ${JSON.stringify(actual)}`)); if (text !== undefined) { diff --git a/src/services/completions.ts b/src/services/completions.ts index e05baddbda34a..7a2eb40df033b 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -117,12 +117,12 @@ namespace ts.Completions { // If the symbol/moduleSymbol was a merged symbol, it will have a new identity // in the checker, even though the symbols to merge are the same (guaranteed by // cache invalidation in synchronizeHostData). - if (suggestion.symbol.declarations) { + if (suggestion.symbol.declarations?.length) { suggestion.symbol = checker.getMergedSymbol(suggestion.origin.isDefaultExport - ? suggestion.symbol.declarations[0].localSymbol || suggestion.symbol.declarations[0].symbol + ? suggestion.symbol.declarations[0].localSymbol ?? suggestion.symbol.declarations[0].symbol : suggestion.symbol.declarations[0].symbol); } - if (suggestion.origin.moduleSymbol.declarations) { + if (suggestion.origin.moduleSymbol.declarations?.length) { suggestion.origin.moduleSymbol = checker.getMergedSymbol(suggestion.origin.moduleSymbol.declarations[0].symbol); } }); @@ -1624,6 +1624,9 @@ namespace ts.Completions { if (isDefaultExport) { symbol = getLocalSymbolForExportDefault(symbol) || symbol; } + if (typeChecker.isUndefinedSymbol(symbol)) { + return; + } addToSeen(resultSymbolIds, getSymbolId(symbol)); const origin: SymbolOriginInfoExport = { kind: SymbolOriginInfoKind.Export, moduleSymbol, isDefaultExport }; results.push({ diff --git a/tests/cases/fourslash/server/importSuggestionsCache_exportUndefined.ts b/tests/cases/fourslash/server/importSuggestionsCache_exportUndefined.ts new file mode 100644 index 0000000000000..937eb15f09a35 --- /dev/null +++ b/tests/cases/fourslash/server/importSuggestionsCache_exportUndefined.ts @@ -0,0 +1,43 @@ +/// + +// @Filename: /tsconfig.json +////{ "compilerOptions": { "module": "esnext" } } + +// @Filename: /undefined.ts +////export = undefined; + +// @Filename: /undefinedAlias.ts +////const x = undefined; +////export = x; + +// @Filename: /index.ts +//// /**/ + +// Would throw error if undefined appears twice +goTo.marker(""); +verify.completions({ + includes: [{ + name: "x", + hasAction: true, + sortText: completion.SortText.AutoImportSuggestions, + source: "/undefinedAlias" + }], + preferences: { + includeCompletionsForModuleExports: true, + includeInsertTextCompletions: true + } +}); + +// Do it again for cache test +verify.completions({ + includes: [{ + name: "x", + hasAction: true, + sortText: completion.SortText.AutoImportSuggestions, + source: "/undefinedAlias" + }], + preferences: { + includeCompletionsForModuleExports: true, + includeInsertTextCompletions: true + } +}); \ No newline at end of file