Handle indexed access types in getSymbolAtLocation and findAllReferences (#17787)

This commit is contained in:
Andy 2017-08-29 07:53:22 -07:00 committed by GitHub
parent 3ea031cf1c
commit 30b3cb0f68
5 changed files with 60 additions and 30 deletions

View file

@ -22905,7 +22905,7 @@ namespace ts {
return undefined;
}
function getSymbolAtLocation(node: Node) {
function getSymbolAtLocation(node: Node): Symbol | undefined {
if (node.kind === SyntaxKind.SourceFile) {
return isExternalModule(<SourceFile>node) ? getMergedSymbol(node.symbol) : undefined;
}
@ -22983,9 +22983,21 @@ namespace ts {
case SyntaxKind.NumericLiteral:
// index access
if (node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).argumentExpression === node) {
const objectType = getTypeOfExpression((<ElementAccessExpression>node.parent).expression);
return getPropertyOfType(objectType, (<NumericLiteral>node).text as __String);
switch (node.parent.kind) {
case SyntaxKind.ElementAccessExpression: {
if ((<ElementAccessExpression>node.parent).argumentExpression !== node) {
return undefined;
}
const objectType = getTypeOfExpression((<ElementAccessExpression>node.parent).expression);
return getPropertyOfType(objectType, (<NumericLiteral>node).text as __String);
}
case SyntaxKind.LiteralType: {
if (!isIndexedAccessTypeNode(node.parent.parent)) {
return undefined;
}
const objectType = getTypeFromTypeNode(node.parent.parent.objectType);
return getPropertyOfType(objectType, escapeLeadingUnderscores((node as StringLiteral | NumericLiteral).text));
}
}
break;
}

View file

@ -748,11 +748,11 @@ namespace ts.FindAllReferences.Core {
return (node as Identifier).text.length === searchSymbolName.length;
case SyntaxKind.StringLiteral:
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) &&
return (isLiteralNameOfPropertyDeclarationOrIndexAccess(node as StringLiteral) || isNameOfExternalModuleImportOrDeclaration(node)) &&
(node as StringLiteral).text.length === searchSymbolName.length;
case SyntaxKind.NumericLiteral:
return isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && (node as NumericLiteral).text.length === searchSymbolName.length;
return isLiteralNameOfPropertyDeclarationOrIndexAccess(node as NumericLiteral) && (node as NumericLiteral).text.length === searchSymbolName.length;
default:
return false;

View file

@ -89,9 +89,15 @@ namespace ts.Rename {
}
function nodeIsEligibleForRename(node: Node): boolean {
return node.kind === ts.SyntaxKind.Identifier ||
node.kind === SyntaxKind.StringLiteral ||
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
isThis(node);
switch (node.kind) {
case SyntaxKind.Identifier:
case SyntaxKind.StringLiteral:
case SyntaxKind.ThisKeyword:
return true;
case SyntaxKind.NumericLiteral:
return isLiteralNameOfPropertyDeclarationOrIndexAccess(node as NumericLiteral);
default:
return false;
}
}
}

View file

@ -244,27 +244,25 @@ namespace ts {
isFunctionLike(node.parent) && (<FunctionLikeDeclaration>node.parent).name === node;
}
export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: Node): boolean {
if (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.NumericLiteral) {
switch (node.parent.kind) {
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.EnumMember:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.ModuleDeclaration:
return getNameOfDeclaration(<Declaration>node.parent) === node;
case SyntaxKind.ElementAccessExpression:
return (<ElementAccessExpression>node.parent).argumentExpression === node;
case SyntaxKind.ComputedPropertyName:
return true;
}
export function isLiteralNameOfPropertyDeclarationOrIndexAccess(node: StringLiteral | NumericLiteral): boolean {
switch (node.parent.kind) {
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.EnumMember:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.ModuleDeclaration:
return getNameOfDeclaration(<Declaration>node.parent) === node;
case SyntaxKind.ElementAccessExpression:
return (<ElementAccessExpression>node.parent).argumentExpression === node;
case SyntaxKind.ComputedPropertyName:
return true;
case SyntaxKind.LiteralType:
return node.parent.parent.kind === SyntaxKind.IndexedAccessType;
}
return false;
}
export function isExpressionOfExternalModuleImportEqualsDeclaration(node: Node) {

View file

@ -0,0 +1,14 @@
/// <reference path='fourslash.ts' />
////interface I {
//// [|{| "isDefinition": true, "isWriteAccess": true |}0|]: number;
//// [|{| "isDefinition": true, "isWriteAccess": true |}s|]: string;
////}
////interface J {
//// a: I[[|0|]],
//// b: I["[|s|]"],
////}
const [n0, s0, n1, s1] = test.ranges();
verify.singleReferenceGroup("(property) I[0]: number", [n0, n1]);
verify.singleReferenceGroup("(property) I.s: string", [s0, s1]);