Skip to content

Commit f61f126

Browse files
author
Andy
authored
findAllReferences: Be consistent how we handle unions in root symobls (microsoft#23002)
1 parent 4f80fbd commit f61f126

2 files changed

Lines changed: 14 additions & 25 deletions

File tree

src/services/findAllReferences.ts

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,32 +1535,25 @@ namespace ts.FindAllReferences.Core {
15351535
function findRootSymbol(sym: Symbol): Symbol | undefined {
15361536
// Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
15371537
// Or a union property, use its underlying unioned symbols
1538-
return firstDefined(checker.getRootSymbols(sym), rootSymbol => {
1539-
// if it is in the list, then we are done
1540-
if (search.includes(rootSymbol)) {
1538+
return firstDefined(checker.getRootSymbols(sym), rootSymbol =>
1539+
isMatchingRootSymbol(search, rootSymbol, state.inheritsFromCache, checker)
15411540
// For a root symbol that is a component of a union or intersection, use the original (union/intersection) symbol.
15421541
// That we when a symbol references the whole union we avoid claiming it references some particular member of the union.
15431542
// For a transient symbol we want to use the root symbol instead.
1544-
return getCheckFlags(sym) & CheckFlags.Synthetic ? sym : rootSymbol;
1545-
}
1546-
1547-
// Finally, try all properties with the same name in any type the containing type extended or implemented, and
1548-
// see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the
1549-
// parent symbol
1550-
if (rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
1551-
// Parents will only be defined if implementations is true
1552-
if (search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))) {
1553-
return undefined;
1554-
}
1555-
1556-
return getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker).some(search.includes) ? rootSymbol : undefined;
1557-
}
1558-
1559-
return undefined;
1560-
});
1543+
? getCheckFlags(sym) & CheckFlags.Synthetic ? sym : rootSymbol
1544+
: undefined);
15611545
}
15621546
}
15631547

1548+
function isMatchingRootSymbol(search: Search, rootSymbol: Symbol, inheritsFromCache: Map<boolean>, checker: TypeChecker): boolean {
1549+
return search.includes(rootSymbol)
1550+
|| rootSymbol.parent && rootSymbol.parent.flags & (SymbolFlags.Class | SymbolFlags.Interface)
1551+
// If we were passed a parent symbol (if 'implementations' set), only include types that are subtypes of the parent symbol.
1552+
&& !(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent, parent, inheritsFromCache, checker)))
1553+
// Try all properties with the same name in any type the containing type extended or implemented.
1554+
&& getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, checker).some(search.includes);
1555+
}
1556+
15641557
/** Gets all symbols for one property. Does not get symbols for every property. */
15651558
function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): ReadonlyArray<Symbol> {
15661559
const contextualType = checker.getContextualType(<ObjectLiteralExpression>node.parent);

tests/cases/fourslash/referencesForUnionProperties.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@ verify.referenceGroups(one, [
2727
{ definition: "(property) a: number", ranges: [one] },
2828
{ definition: "(property) a: string | number", ranges: [x] },
2929
]);
30-
verify.referenceGroups(base, [
31-
{ definition: "(property) Base.a: string", ranges: [base] },
32-
{ definition: "(property) HasAOrB.a: string", ranges: [hasAOrB, x] },
33-
]);
34-
verify.referenceGroups(hasAOrB, [
30+
verify.referenceGroups([base, hasAOrB], [
3531
{ definition: "(property) Base.a: string", ranges: [base] },
3632
{ definition: "(property) HasAOrB.a: string", ranges: [hasAOrB] },
3733
{ definition: "(property) a: string | number", ranges: [x] },

0 commit comments

Comments
 (0)