also return classes when caling goToDef on a constructor call (#59421)

This commit is contained in:
Isabel Duan
2024-08-16 13:58:29 -07:00
committed by GitHub
parent f025a5b879
commit 26c4320757
9 changed files with 602 additions and 27 deletions
+15 -9
View File
@@ -46,6 +46,7 @@ import {
isBindingElement,
isCallLikeExpression,
isCallOrNewExpressionTarget,
isClassDeclaration,
isClassElement,
isClassExpression,
isClassLike,
@@ -228,16 +229,20 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
// Don't go to the component constructor definition for a JSX element, just go to the component definition.
if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isJsxConstructorLike(calledDeclaration))) {
const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration, failedAliasResolution);
// For a function, if this is the original function definition, return just sigInfo.
// If this is the original constructor definition, parent is the class.
// Here, we filter declarations to not duplicate returned definitions.
let declarationFilter: (d: Declaration) => boolean = d => d !== calledDeclaration;
if (typeChecker.getRootSymbols(symbol).some(s => symbolMatchesSignature(s, calledDeclaration))) {
return [sigInfo];
}
else {
const defs = getDefinitionFromSymbol(typeChecker, symbol, node, failedAliasResolution, calledDeclaration) || emptyArray;
// For a 'super()' call, put the signature first, else put the variable first.
return node.kind === SyntaxKind.SuperKeyword ? [sigInfo, ...defs] : [...defs, sigInfo];
if (!isConstructorDeclaration(calledDeclaration)) return [sigInfo];
// If we found a constructor declaration, we also look for class declarations as definitions
declarationFilter = (d: Declaration) => d !== calledDeclaration && (isClassDeclaration(d) || isClassExpression(d));
}
const defs = getDefinitionFromSymbol(typeChecker, symbol, node, failedAliasResolution, declarationFilter) || emptyArray;
// For a 'super()' call, put the signature first, else put the variable first.
return node.kind === SyntaxKind.SuperKeyword ? [sigInfo, ...defs] : [...defs, sigInfo];
}
// Because name in short-hand property assignment has two different meanings: property name and property value,
@@ -584,9 +589,10 @@ function isExpandoDeclaration(node: Declaration): boolean {
return !!containingAssignment && getAssignmentDeclarationKind(containingAssignment) === AssignmentDeclarationKind.Property;
}
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node, failedAliasResolution?: boolean, excludeDeclaration?: Node): DefinitionInfo[] | undefined {
const filteredDeclarations = filter(symbol.declarations, d => d !== excludeDeclaration);
const signatureDefinition = getConstructSignatureDefinition() || getCallSignatureDefinition();
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node, failedAliasResolution?: boolean, declarationFilter?: (d: Declaration) => boolean): DefinitionInfo[] | undefined {
const filteredDeclarations = declarationFilter !== undefined ? filter(symbol.declarations, declarationFilter) : symbol.declarations;
// If we have a declaration filter, we are looking for specific declaration(s), so we should not return prematurely.
const signatureDefinition = !declarationFilter && (getConstructSignatureDefinition() || getCallSignatureDefinition());
if (signatureDefinition) {
return signatureDefinition;
}