Support parameter properties in getRelatedSymbol
(#20202)
This commit is contained in:
parent
185f15d2af
commit
bbb56fed11
|
@ -1427,10 +1427,7 @@ namespace ts.FindAllReferences.Core {
|
|||
// we should include both parameter declaration symbol and property declaration symbol
|
||||
// Parameter Declaration symbol is only visible within function scope, so the symbol is stored in constructor.locals.
|
||||
// Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members
|
||||
if (symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.Parameter &&
|
||||
isParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration)) {
|
||||
addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.name));
|
||||
}
|
||||
addRange(result, getParameterPropertySymbols(symbol, checker));
|
||||
|
||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||
// Include the property in the search
|
||||
|
@ -1460,6 +1457,12 @@ namespace ts.FindAllReferences.Core {
|
|||
}
|
||||
}
|
||||
|
||||
function getParameterPropertySymbols(symbol: Symbol, checker: TypeChecker): Symbol[] {
|
||||
return symbol.valueDeclaration && isParameter(symbol.valueDeclaration) && isParameterPropertyDeclaration(symbol.valueDeclaration)
|
||||
? checker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find symbol of the given property-name and add the symbol to the given result array
|
||||
* @param symbol a symbol to start searching for the given propertyName
|
||||
|
@ -1519,17 +1522,26 @@ namespace ts.FindAllReferences.Core {
|
|||
}
|
||||
|
||||
function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): Symbol | undefined {
|
||||
const { checker } = state;
|
||||
if (search.includes(referenceSymbol)) {
|
||||
return referenceSymbol;
|
||||
}
|
||||
|
||||
if (referenceSymbol.flags & SymbolFlags.FunctionScopedVariable) {
|
||||
Debug.assert(!(referenceSymbol.flags & SymbolFlags.Property));
|
||||
const paramProps = getParameterPropertySymbols(referenceSymbol, checker);
|
||||
if (paramProps) {
|
||||
return getRelatedSymbol(search, find(paramProps, x => !!(x.flags & SymbolFlags.Property))!, referenceLocation, state);
|
||||
}
|
||||
}
|
||||
|
||||
// If the reference location is in an object literal, try to get the contextual type for the
|
||||
// object literal, lookup the property symbol in the contextual type, and use this symbol to
|
||||
// compare to our searchSymbol
|
||||
const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation);
|
||||
if (containingObjectLiteralElement) {
|
||||
const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, state.checker), contextualSymbol =>
|
||||
find(state.checker.getRootSymbols(contextualSymbol), search.includes));
|
||||
const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol =>
|
||||
find(checker.getRootSymbols(contextualSymbol), search.includes));
|
||||
|
||||
if (contextualSymbol) {
|
||||
return contextualSymbol;
|
||||
|
@ -1539,7 +1551,7 @@ namespace ts.FindAllReferences.Core {
|
|||
// Get the property symbol from the object literal's type and look if thats the search symbol
|
||||
// In below eg. get 'property' from type of elems iterating type
|
||||
// for ( { property: p2 } of elems) { }
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, state.checker);
|
||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, checker);
|
||||
if (propertySymbol && search.includes(propertySymbol)) {
|
||||
return propertySymbol;
|
||||
}
|
||||
|
@ -1548,7 +1560,7 @@ namespace ts.FindAllReferences.Core {
|
|||
// If the reference location is the binding element and doesn't have property name
|
||||
// then include the binding element in the related symbols
|
||||
// let { a } : { a };
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, state.checker);
|
||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, checker);
|
||||
if (bindingElementPropertySymbol) {
|
||||
const fromBindingElement = findRootSymbol(bindingElementPropertySymbol);
|
||||
if (fromBindingElement) return fromBindingElement;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class C {
|
||||
//// constructor(public [|{| "isWriteAccess": true, "isDefinition": true |}x|]: string) {
|
||||
//// [|x|];
|
||||
//// }
|
||||
////}
|
||||
////class D extends C {
|
||||
//// constructor(public [|{| "isWriteAccess": true, "isDefinition": true |}x|]: string) {
|
||||
//// super([|x|]);
|
||||
//// }
|
||||
////}
|
||||
|
||||
const [r0, r1, r2, r3] = test.ranges();
|
||||
verify.referenceGroups(r0, [
|
||||
{ definition: "(property) C.x: string", ranges: [r0, r2, r3] },
|
||||
{ definition: "(parameter) x: string", ranges: [r1] },
|
||||
]);
|
||||
verify.referenceGroups(r1, [
|
||||
{ definition: "(property) C.x: string", ranges: [r0] },
|
||||
{ definition: "(parameter) x: string", ranges: [r1] },
|
||||
]);
|
||||
verify.referenceGroups(r2, [
|
||||
{ definition: "(property) C.x: string", ranges: [r0, r1] },
|
||||
{ definition: "(property) D.x: string", ranges: [r2] },
|
||||
{ definition: "(parameter) x: string", ranges: [r3] },
|
||||
]);
|
||||
verify.referenceGroups(r3, [
|
||||
{ definition: "(property) D.x: string", ranges: [r2] },
|
||||
{ definition: "(parameter) x: string", ranges: [r3] },
|
||||
]);
|
Loading…
Reference in a new issue