Return string completions for indexed access types
This commit is contained in:
parent
4eb633e0d9
commit
25c5e57091
5 changed files with 31 additions and 8 deletions
|
@ -4403,7 +4403,7 @@ namespace ts {
|
||||||
return node.kind === SyntaxKind.RegularExpressionLiteral;
|
return node.kind === SyntaxKind.RegularExpressionLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression {
|
export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral {
|
||||||
return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,8 @@ namespace ts.Completions {
|
||||||
// }
|
// }
|
||||||
// let a: A;
|
// let a: A;
|
||||||
// a['/*completion position*/']
|
// a['/*completion position*/']
|
||||||
return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log);
|
const type = typeChecker.getTypeAtLocation(node.parent.expression);
|
||||||
|
return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log);
|
||||||
}
|
}
|
||||||
else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration
|
else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration
|
||||||
|| isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent)
|
|| isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent)
|
||||||
|
@ -278,6 +279,16 @@ namespace ts.Completions {
|
||||||
const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker);
|
const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker);
|
||||||
return pathCompletionsInfo(entries);
|
return pathCompletionsInfo(entries);
|
||||||
}
|
}
|
||||||
|
else if (isIndexedAccessTypeNode(node.parent.parent)) {
|
||||||
|
// Get all apparent property names
|
||||||
|
// i.e. interface Foo {
|
||||||
|
// foo: string;
|
||||||
|
// bar: string;
|
||||||
|
// }
|
||||||
|
// let x: Foo["/*completion position*/"]
|
||||||
|
const type = typeChecker.getTypeFromTypeNode(node.parent.parent.objectType);
|
||||||
|
return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, type, typeChecker, compilerOptions.target, log);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||||
if (argumentInfo) {
|
if (argumentInfo) {
|
||||||
|
@ -334,11 +345,10 @@ namespace ts.Completions {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringLiteralCompletionEntriesFromElementAccess(node: ElementAccessExpression, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined {
|
function getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(stringLiteralNode: StringLiteral | NoSubstitutionTemplateLiteral, type: Type, typeChecker: TypeChecker, target: ScriptTarget, log: Log): CompletionInfo | undefined {
|
||||||
const type = typeChecker.getTypeAtLocation(node.expression);
|
|
||||||
const entries: CompletionEntry[] = [];
|
const entries: CompletionEntry[] = [];
|
||||||
if (type) {
|
if (type) {
|
||||||
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
|
getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, stringLiteralNode, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true);
|
||||||
if (entries.length) {
|
if (entries.length) {
|
||||||
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
|
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries };
|
||||||
}
|
}
|
||||||
|
@ -1583,7 +1593,7 @@ namespace ts.Completions {
|
||||||
switch (contextToken.kind) {
|
switch (contextToken.kind) {
|
||||||
case SyntaxKind.OpenParenToken:
|
case SyntaxKind.OpenParenToken:
|
||||||
case SyntaxKind.CommaToken:
|
case SyntaxKind.CommaToken:
|
||||||
return isConstructorDeclaration(contextToken.parent) && contextToken.parent;
|
return isConstructorDeclaration(contextToken.parent) && contextToken.parent;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (isConstructorParameterCompletion(contextToken)) {
|
if (isConstructorParameterCompletion(contextToken)) {
|
||||||
|
|
|
@ -2911,7 +2911,7 @@ declare namespace ts {
|
||||||
function isStringLiteral(node: Node): node is StringLiteral;
|
function isStringLiteral(node: Node): node is StringLiteral;
|
||||||
function isJsxText(node: Node): node is JsxText;
|
function isJsxText(node: Node): node is JsxText;
|
||||||
function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral;
|
function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral;
|
||||||
function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression;
|
function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral;
|
||||||
function isTemplateHead(node: Node): node is TemplateHead;
|
function isTemplateHead(node: Node): node is TemplateHead;
|
||||||
function isTemplateMiddle(node: Node): node is TemplateMiddle;
|
function isTemplateMiddle(node: Node): node is TemplateMiddle;
|
||||||
function isTemplateTail(node: Node): node is TemplateTail;
|
function isTemplateTail(node: Node): node is TemplateTail;
|
||||||
|
|
|
@ -2964,7 +2964,7 @@ declare namespace ts {
|
||||||
function isStringLiteral(node: Node): node is StringLiteral;
|
function isStringLiteral(node: Node): node is StringLiteral;
|
||||||
function isJsxText(node: Node): node is JsxText;
|
function isJsxText(node: Node): node is JsxText;
|
||||||
function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral;
|
function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral;
|
||||||
function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression;
|
function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral;
|
||||||
function isTemplateHead(node: Node): node is TemplateHead;
|
function isTemplateHead(node: Node): node is TemplateHead;
|
||||||
function isTemplateMiddle(node: Node): node is TemplateMiddle;
|
function isTemplateMiddle(node: Node): node is TemplateMiddle;
|
||||||
function isTemplateTail(node: Node): node is TemplateTail;
|
function isTemplateTail(node: Node): node is TemplateTail;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
/// <reference path='fourslash.ts'/>
|
||||||
|
|
||||||
|
////interface Foo {
|
||||||
|
//// foo: string;
|
||||||
|
//// bar: string;
|
||||||
|
////}
|
||||||
|
////
|
||||||
|
////let x: Foo["/*1*/"]
|
||||||
|
|
||||||
|
goTo.marker("1");
|
||||||
|
verify.completionListContains("foo");
|
||||||
|
verify.completionListContains("bar");
|
||||||
|
verify.completionListCount(2);
|
Loading…
Reference in a new issue