Skip to content

Commit 4e59096

Browse files
author
Andy
authored
Exclude keywords from import completions (#28114)
* Exclude keywords from import completions * Still allow contextual keywords * Add excludes tests
1 parent afbf89e commit 4e59096

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

src/compiler/utilities.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,6 +2586,10 @@ namespace ts {
25862586
return token !== undefined && isNonContextualKeyword(token);
25872587
}
25882588

2589+
export function isIdentifierANonContextualKeyword({ originalKeywordKind }: Identifier): boolean {
2590+
return !!originalKeywordKind && !isContextualKeyword(originalKeywordKind);
2591+
}
2592+
25892593
export type TriviaKind = SyntaxKind.SingleLineCommentTrivia
25902594
| SyntaxKind.MultiLineCommentTrivia
25912595
| SyntaxKind.NewLineTrivia

src/services/completions.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,14 +1167,16 @@ namespace ts.Completions {
11671167
// The actual import fix might end up coming from a re-export -- we don't compute that until getting completion details.
11681168
// This is just to avoid adding duplicate completion entries.
11691169
//
1170-
// If `symbol.parent !== ...`, this comes from an `export * from "foo"` re-export. Those don't create new symbols.
1171-
// If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check).
1170+
// If `symbol.parent !== ...`, this is an `export * from "foo"` re-export. Those don't create new symbols.
11721171
if (typeChecker.getMergedSymbol(symbol.parent!) !== resolvedModuleSymbol
1173-
|| some(symbol.declarations, d => isExportSpecifier(d) && !d.propertyName && !!d.parent.parent.moduleSpecifier)) {
1172+
|| some(symbol.declarations, d =>
1173+
// If `!!d.name.originalKeywordKind`, this is `export { _break as break };` -- skip this and prefer the keyword completion.
1174+
// 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).
1175+
isExportSpecifier(d) && (d.propertyName ? isIdentifierANonContextualKeyword(d.name) : !!d.parent.parent.moduleSpecifier))) {
11741176
continue;
11751177
}
11761178

1177-
const isDefaultExport = symbol.name === InternalSymbolName.Default;
1179+
const isDefaultExport = symbol.escapedName === InternalSymbolName.Default;
11781180
if (isDefaultExport) {
11791181
symbol = getLocalSymbolForExportDefault(symbol) || symbol;
11801182
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: /a.ts
4+
////const _break = 0;
5+
////export { _break as break };
6+
////const _implements = 0;
7+
////export { _implements as implements };
8+
////const _unique = 0;
9+
////export { _unique as unique };
10+
11+
// Note: `export const unique = 0;` is legal,
12+
// but we want to test that we don't block an import completion of 'unique' just because it appears in an ExportSpecifier.
13+
14+
// @Filename: /b.ts
15+
////br/*break*/
16+
////im/*implements*/
17+
////un/*unique*/
18+
19+
const preferences: FourSlashInterface.UserPreferences = { includeCompletionsForModuleExports: true };
20+
verify.completions(
21+
// no reserved words
22+
{
23+
marker: "break",
24+
includes: { name: "break", text: "break", kind: "keyword" },
25+
excludes: { name: "break", source: "/a" },
26+
preferences,
27+
},
28+
// no strict mode reserved words
29+
{
30+
marker: "implements",
31+
includes: { name: "implements", text: "implements", kind: "keyword" },
32+
excludes: { name: "implements", source: "/a" },
33+
preferences,
34+
},
35+
// yes contextual keywords
36+
{
37+
marker: "unique",
38+
includes: { name: "unique", source: "/a", sourceDisplay: "./a", text: "(alias) const unique: 0\nexport unique", hasAction: true },
39+
excludes: { name: "unique", source: undefined },
40+
preferences,
41+
},
42+
);

0 commit comments

Comments
 (0)