mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 21:36:50 -05:00
Improve find-all-references for redeclared property in a derived interface (#21002)
This commit is contained in:
@@ -876,6 +876,8 @@ namespace ts.FindAllReferences.Core {
|
||||
case SpecialSearchKind.Class:
|
||||
addClassStaticThisReferences(referenceLocation, search, state);
|
||||
break;
|
||||
default:
|
||||
Debug.assertNever(state.specialSearchKind);
|
||||
}
|
||||
|
||||
getImportOrExportReferences(referenceLocation, referenceSymbol, search, state);
|
||||
@@ -1436,7 +1438,7 @@ namespace ts.FindAllReferences.Core {
|
||||
// This is not needed when searching for re-exports.
|
||||
function populateSearchSymbolSet(symbol: Symbol, location: Node, checker: TypeChecker, implementations: boolean): Symbol[] {
|
||||
// The search set contains at least the current symbol
|
||||
const result = [symbol];
|
||||
const result: Symbol[] = [];
|
||||
|
||||
const containingObjectLiteralElement = getContainingObjectLiteralElement(location);
|
||||
if (containingObjectLiteralElement) {
|
||||
@@ -1453,9 +1455,9 @@ namespace ts.FindAllReferences.Core {
|
||||
// If the location is in a context sensitive location (i.e. in an object literal) try
|
||||
// to get a contextual type for it, and add the property symbol from the contextual
|
||||
// type to the search set
|
||||
forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol => {
|
||||
addRange(result, checker.getRootSymbols(contextualSymbol));
|
||||
});
|
||||
for (const contextualSymbol of getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker)) {
|
||||
addRootSymbols(contextualSymbol);
|
||||
}
|
||||
|
||||
/* Because in short-hand property assignment, location has two meaning : property name and as value of the property
|
||||
* When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of
|
||||
@@ -1496,9 +1498,7 @@ namespace ts.FindAllReferences.Core {
|
||||
// If this is a union property, add all the symbols from all its source symbols in all unioned types.
|
||||
// If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
|
||||
for (const rootSymbol of checker.getRootSymbols(sym)) {
|
||||
if (rootSymbol !== sym) {
|
||||
result.push(rootSymbol);
|
||||
}
|
||||
result.push(rootSymbol);
|
||||
|
||||
// Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
|
||||
if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
@@ -1522,7 +1522,7 @@ namespace ts.FindAllReferences.Core {
|
||||
* @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol.
|
||||
* The value of previousIterationSymbol is undefined when the function is first called.
|
||||
*/
|
||||
function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Symbol[], previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void {
|
||||
function getPropertySymbolsFromBaseTypes(symbol: Symbol, propertyName: string, result: Push<Symbol>, previousIterationSymbolsCache: SymbolTable, checker: TypeChecker): void {
|
||||
if (!symbol) {
|
||||
return;
|
||||
}
|
||||
@@ -1591,9 +1591,7 @@ namespace ts.FindAllReferences.Core {
|
||||
// compare to our searchSymbol
|
||||
const containingObjectLiteralElement = getContainingObjectLiteralElement(referenceLocation);
|
||||
if (containingObjectLiteralElement) {
|
||||
const contextualSymbol = forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), contextualSymbol =>
|
||||
find(checker.getRootSymbols(contextualSymbol), search.includes));
|
||||
|
||||
const contextualSymbol = firstDefined(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), findRootSymbol);
|
||||
if (contextualSymbol) {
|
||||
return contextualSymbol;
|
||||
}
|
||||
@@ -1622,7 +1620,7 @@ namespace ts.FindAllReferences.Core {
|
||||
function findRootSymbol(sym: Symbol): Symbol | undefined {
|
||||
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
|
||||
// Or a union property, use its underlying unioned symbols
|
||||
return forEach(state.checker.getRootSymbols(sym), rootSymbol => {
|
||||
return firstDefined(checker.getRootSymbols(sym), rootSymbol => {
|
||||
// if it is in the list, then we are done
|
||||
if (search.includes(rootSymbol)) {
|
||||
return rootSymbol;
|
||||
@@ -1633,12 +1631,12 @@ namespace ts.FindAllReferences.Core {
|
||||
// parent symbol
|
||||
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
|
||||
// Parents will only be defined if implementations is true
|
||||
if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker))) {
|
||||
if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result: Symbol[] = [];
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), state.checker);
|
||||
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
|
||||
return find(result, search.includes);
|
||||
}
|
||||
|
||||
@@ -1660,28 +1658,12 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Gets all symbols for one property. Does not get symbols for every property. */
|
||||
function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): Symbol[] | undefined {
|
||||
const objectLiteral = <ObjectLiteralExpression>node.parent;
|
||||
const contextualType = checker.getContextualType(objectLiteral);
|
||||
function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): ReadonlyArray<Symbol> {
|
||||
const contextualType = checker.getContextualType(<ObjectLiteralExpression>node.parent);
|
||||
const name = getNameFromObjectLiteralElement(node);
|
||||
if (name && contextualType) {
|
||||
const result: Symbol[] = [];
|
||||
const symbol = contextualType.getProperty(name);
|
||||
if (symbol) {
|
||||
result.push(symbol);
|
||||
}
|
||||
|
||||
if (contextualType.flags & TypeFlags.Union) {
|
||||
forEach((<UnionType>contextualType).types, t => {
|
||||
const symbol = t.getProperty(name);
|
||||
if (symbol) {
|
||||
result.push(symbol);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return undefined;
|
||||
const symbol = contextualType && name && contextualType.getProperty(name);
|
||||
return symbol ? [symbol] :
|
||||
contextualType && contextualType.flags & TypeFlags.Union ? mapDefined((<UnionType>contextualType).types, t => t.getProperty(name)) : emptyArray;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user