From 59c014ba32597ab9e9a2cca7f2c7b6767b64ea6f Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 16 Nov 2018 17:03:34 -0800 Subject: [PATCH] Properly set symbolMeanings when calling getSymbolsInScope --- src/services/completions.ts | 15 ++++++++++----- .../completionsIsTypeOnlyCompletion.ts | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/completionsIsTypeOnlyCompletion.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index 488af58a2f0..878b4bcd130 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1021,7 +1021,8 @@ namespace ts.Completions { const scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; isInSnippetScope = isSnippetScope(scopeNode); - const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; + const isTypeOnly = isTypeOnlyCompletion(); + const symbolMeanings = (isTypeOnly ? SymbolFlags.None : SymbolFlags.Value) | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias; symbols = Debug.assertEachDefined(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings), "getSymbolsInScope() should all be defined"); @@ -1070,9 +1071,9 @@ namespace ts.Completions { } function filterGlobalCompletion(symbols: Symbol[]): void { - const isTypeOnlyCompletion = insideJsDocTagTypeExpression || !isContextTokenValueLocation(contextToken) && (isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)); - const allowTypes = isTypeOnlyCompletion || !isContextTokenValueLocation(contextToken) && isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker); - if (isTypeOnlyCompletion) keywordFilters = KeywordCompletionFilters.TypeKeywords; + const isTypeOnly = isTypeOnlyCompletion(); + const allowTypes = isTypeOnly || !isContextTokenValueLocation(contextToken) && isPossiblyTypeArgumentPosition(contextToken, sourceFile, typeChecker); + if (isTypeOnly) keywordFilters = KeywordCompletionFilters.TypeKeywords; filterMutate(symbols, symbol => { if (!isSourceFile(location)) { @@ -1091,7 +1092,7 @@ namespace ts.Completions { if (allowTypes) { // Its a type, but you can reach it by namespace.type as well const symbolAllowedAsType = symbolCanBeReferencedAtTypeLocation(symbol); - if (symbolAllowedAsType || isTypeOnlyCompletion) { + if (symbolAllowedAsType || isTypeOnly) { return symbolAllowedAsType; } } @@ -1102,6 +1103,10 @@ namespace ts.Completions { }); } + function isTypeOnlyCompletion(): boolean { + return insideJsDocTagTypeExpression || !isContextTokenValueLocation(contextToken) && (isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)); + } + function isContextTokenValueLocation(contextToken: Node) { return contextToken && contextToken.kind === SyntaxKind.TypeOfKeyword && diff --git a/tests/cases/fourslash/completionsIsTypeOnlyCompletion.ts b/tests/cases/fourslash/completionsIsTypeOnlyCompletion.ts new file mode 100644 index 00000000000..b14f7bc0efe --- /dev/null +++ b/tests/cases/fourslash/completionsIsTypeOnlyCompletion.ts @@ -0,0 +1,19 @@ +/// + +// @noLib: true + +// @Filename: /abc.ts +////export type Abc = number; + +// @Filename: /user.ts +//// import { Abc } from "./abc"; +////function f(Abc: Ab/**/) {} + +verify.completions({ + marker: "", + // Should not have an import completion for 'Abc', should use the local one + exact: ["Abc", ...completion.typeKeywords], + preferences: { + includeCompletionsForModuleExports: true, + }, +});