Merge pull request #13806 from Microsoft/Fix13789

Get string literal completions from the other operand of `==` operators
This commit is contained in:
Mohamed Hegazy 2017-02-01 09:44:43 -08:00 committed by GitHub
commit ddb6d99221
4 changed files with 63 additions and 3 deletions

View File

@ -173,6 +173,18 @@ namespace ts.Completions {
// var y = require("/*completion position*/");
return getStringLiteralCompletionEntriesFromModuleNames(<StringLiteral>node, compilerOptions, host, typeChecker);
}
else if (isEqualityExpression(node.parent)) {
// Get completions from the type of the other operand
// i.e. switch (a) {
// case '/*completion position*/'
// }
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker);
}
else if (isCaseOrDefaultClause(node.parent)) {
// Get completions from the type of the switch expression
// i.e. x === '/*completion position'
return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation((<SwitchStatement>node.parent.parent.parent).expression), typeChecker);
}
else {
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
if (argumentInfo) {
@ -184,7 +196,7 @@ namespace ts.Completions {
// Get completion for string literal from string literal type
// i.e. var x: "hi" | "hello" = "/*completion position*/"
return getStringLiteralCompletionEntriesFromContextualType(<StringLiteral>node, typeChecker);
return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(<StringLiteral>node), typeChecker);
}
}
@ -228,8 +240,7 @@ namespace ts.Completions {
return undefined;
}
function getStringLiteralCompletionEntriesFromContextualType(node: StringLiteral, typeChecker: TypeChecker): CompletionInfo | undefined {
const type = typeChecker.getContextualType(node);
function getStringLiteralCompletionEntriesFromType(type: Type, typeChecker: TypeChecker): CompletionInfo | undefined {
if (type) {
const entries: CompletionEntry[] = [];
addStringLiteralCompletionsFromType(type, entries, typeChecker);
@ -1756,4 +1767,15 @@ namespace ts.Completions {
catch (e) {}
return undefined;
}
function isEqualityExpression(node: Node): node is BinaryExpression {
return isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind);
}
function isEqualityOperatorKind(kind: SyntaxKind) {
return kind == SyntaxKind.EqualsEqualsToken ||
kind === SyntaxKind.ExclamationEqualsToken ||
kind === SyntaxKind.EqualsEqualsEqualsToken ||
kind === SyntaxKind.ExclamationEqualsEqualsToken;
}
}

View File

@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////type As = 'arf' | 'abacus' | 'abaddon';
////let a: As;
////if ('/**/' != a
goTo.marker();
verify.completionListContains("arf");
verify.completionListContains("abacus");
verify.completionListContains("abaddon");
verify.completionListCount(3);

View File

@ -0,0 +1,14 @@
/// <reference path='fourslash.ts'/>
////type As = 'arf' | 'abacus' | 'abaddon';
////let a: As;
////switch (a) {
//// case '/**/
////}
goTo.marker();
verify.completionListContains("arf");
verify.completionListContains("abacus");
verify.completionListContains("abaddon");
verify.completionListCount(3);

View File

@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////type As = 'arf' | 'abacus' | 'abaddon';
////let a: As;
////if (a === '/**/
goTo.marker();
verify.completionListContains("arf");
verify.completionListContains("abacus");
verify.completionListContains("abaddon");
verify.completionListCount(3);