Skip to content

Commit ddb6d99

Browse files
authored
Merge pull request #13806 from Microsoft/Fix13789
Get string literal completions from the other operand of `==` operators
2 parents cf20850 + a39c14e commit ddb6d99

File tree

4 files changed

+63
-3
lines changed

4 files changed

+63
-3
lines changed

src/services/completions.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,18 @@ namespace ts.Completions {
173173
// var y = require("/*completion position*/");
174174
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
175175
}
176+
else if (isEqualityExpression(node.parent)) {
177+
// Get completions from the type of the other operand
178+
// i.e. switch (a) {
179+
// case '/*completion position*/'
180+
// }
181+
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker);
182+
}
183+
else if (isCaseOrDefaultClause(node.parent)) {
184+
// Get completions from the type of the switch expression
185+
// i.e. x === '/*completion position'
186+
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((<SwitchStatement>node.parent.parent.parent).expression), typeChecker);
187+
}
176188
else {
177189
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
178190
if (argumentInfo) {
@@ -184,7 +196,7 @@ namespace ts.Completions {
184196

185197
// Get completion for string literal from string literal type
186198
// i.e. var x: "hi" | "hello" = "/*completion position*/"
187-
return getStringLiteralCompletionEntriesFromContextualType(<StringLiteral>node, typeChecker);
199+
return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(<StringLiteral>node), typeChecker);
188200
}
189201
}
190202

@@ -228,8 +240,7 @@ namespace ts.Completions {
228240
return undefined;
229241
}
230242

231-
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral, typeChecker: TypeChecker): CompletionInfo | undefined {
232-
const type = typeChecker.getContextualType(node);
243+
function getStringLiteralCompletionEntriesFromType(type: Type, typeChecker: TypeChecker): CompletionInfo | undefined {
233244
if (type) {
234245
const entries: CompletionEntry[] = [];
235246
addStringLiteralCompletionsFromType(type, entries, typeChecker);
@@ -1756,4 +1767,15 @@ namespace ts.Completions {
17561767
catch (e) {}
17571768
return undefined;
17581769
}
1770+
1771+
function isEqualityExpression(node: Node): node is BinaryExpression {
1772+
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
1773+
}
1774+
1775+
function isEqualityOperatorKind(kind: SyntaxKind) {
1776+
return kind == SyntaxKind.EqualsEqualsToken ||
1777+
kind === SyntaxKind.ExclamationEqualsToken ||
1778+
kind === SyntaxKind.EqualsEqualsEqualsToken ||
1779+
kind === SyntaxKind.ExclamationEqualsEqualsToken;
1780+
}
17591781
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////type As = 'arf' | 'abacus' | 'abaddon';
4+
////let a: As;
5+
////if ('/**/' != a
6+
7+
goTo.marker();
8+
verify.completionListContains("arf");
9+
verify.completionListContains("abacus");
10+
verify.completionListContains("abaddon");
11+
verify.completionListCount(3);
12+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////type As = 'arf' | 'abacus' | 'abaddon';
4+
////let a: As;
5+
////switch (a) {
6+
//// case '/**/
7+
////}
8+
9+
goTo.marker();
10+
verify.completionListContains("arf");
11+
verify.completionListContains("abacus");
12+
verify.completionListContains("abaddon");
13+
verify.completionListCount(3);
14+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts'/>
2+
3+
////type As = 'arf' | 'abacus' | 'abaddon';
4+
////let a: As;
5+
////if (a === '/**/
6+
7+
goTo.marker();
8+
verify.completionListContains("arf");
9+
verify.completionListContains("abacus");
10+
verify.completionListContains("abaddon");
11+
verify.completionListCount(3);
12+

0 commit comments

Comments
 (0)