Support parameter properties in getRelatedSymbol
(#20202)
This commit is contained in:
parent
185f15d2af
commit
bbb56fed11
2 changed files with 51 additions and 8 deletions
|
@ -1427,10 +1427,7 @@ namespace ts.FindAllReferences.Core {
|
||||||
// we should include both parameter declaration symbol and property declaration symbol
|
// 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.
|
// 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
|
// 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 &&
|
addRange(result, getParameterPropertySymbols(symbol, checker));
|
||||||
isParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration)) {
|
|
||||||
addRange(result, checker.getSymbolsOfParameterPropertyDeclaration(<ParameterDeclaration>symbol.valueDeclaration, symbol.name));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
// If this is symbol of binding element without propertyName declaration in Object binding pattern
|
||||||
// Include the property in the search
|
// 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
|
* 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
|
* @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 {
|
function getRelatedSymbol(search: Search, referenceSymbol: Symbol, referenceLocation: Node, state: State): Symbol | undefined {
|
||||||
|
const { checker } = state;
|
||||||
if (search.includes(referenceSymbol)) {
|
if (search.includes(referenceSymbol)) {
|
||||||
return 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
|
// 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
|
// object literal, lookup the property symbol in the contextual type, and use this symbol to
|
||||||
// compare to our searchSymbol
|
// compare to our searchSymbol
|
||||||
const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation);
|
const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation);
|
||||||
if (containingObjectLiteralElement) {
|
if (containingObjectLiteralElement) {
|
||||||
const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, state.checker), contextualSymbol =>
|
const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol =>
|
||||||
find(state.checker.getRootSymbols(contextualSymbol), search.includes));
|
find(checker.getRootSymbols(contextualSymbol), search.includes));
|
||||||
|
|
||||||
if (contextualSymbol) {
|
if (contextualSymbol) {
|
||||||
return 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
|
// 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
|
// In below eg. get 'property' from type of elems iterating type
|
||||||
// for ( { property: p2 } of elems) { }
|
// for ( { property: p2 } of elems) { }
|
||||||
const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, state.checker);
|
const propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, checker);
|
||||||
if (propertySymbol && search.includes(propertySymbol)) {
|
if (propertySymbol && search.includes(propertySymbol)) {
|
||||||
return 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
|
// If the reference location is the binding element and doesn't have property name
|
||||||
// then include the binding element in the related symbols
|
// then include the binding element in the related symbols
|
||||||
// let { a } : { a };
|
// let { a } : { a };
|
||||||
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, state.checker);
|
const bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, checker);
|
||||||
if (bindingElementPropertySymbol) {
|
if (bindingElementPropertySymbol) {
|
||||||
const fromBindingElement = findRootSymbol(bindingElementPropertySymbol);
|
const fromBindingElement = findRootSymbol(bindingElementPropertySymbol);
|
||||||
if (fromBindingElement) return fromBindingElement;
|
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