Skip to content

Commit c7215a1

Browse files
author
Andy
authored
findAllRefs: give entry for union its own definition (microsoft#22694)
1 parent 76fefdd commit c7215a1

21 files changed

+143
-156
lines changed

src/harness/fourslash.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,10 +1100,10 @@ namespace FourSlash {
11001100
references: ranges.map<ts.ReferenceEntry>(r => {
11011101
const { isWriteAccess = false, isDefinition = false, isInString } = (r.marker && r.marker.data || {}) as { isWriteAccess?: boolean, isDefinition?: boolean, isInString?: true };
11021102
return {
1103-
isWriteAccess,
1104-
isDefinition,
11051103
fileName: r.fileName,
11061104
textSpan: ts.createTextSpanFromRange(r),
1105+
isWriteAccess,
1106+
isDefinition,
11071107
...(isInString ? { isInString: true } : undefined),
11081108
};
11091109
}),
@@ -1119,7 +1119,7 @@ namespace FourSlash {
11191119
const fullActual = ts.map<ts.ReferencedSymbol, ReferenceGroupJson>(this.findReferencesAtCaret(), ({ definition, references }, i) => {
11201120
const text = definition.displayParts.map(d => d.text).join("");
11211121
return {
1122-
definition: typeof fullExpected[i].definition === "string" ? text : { text, range: definition.textSpan },
1122+
definition: fullExpected.length > i && typeof fullExpected[i].definition === "string" ? text : { text, range: definition.textSpan },
11231123
references,
11241124
};
11251125
});

src/services/findAllReferences.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,10 @@ namespace ts.FindAllReferences.Core {
15991599
return firstDefined(checker.getRootSymbols(sym), rootSymbol => {
16001600
// if it is in the list, then we are done
16011601
if (search.includes(rootSymbol)) {
1602-
return rootSymbol;
1602+
// For a root symbol that is a component of a union or intersection, use the original (union/intersection) symbol.
1603+
// That we when a symbol references the whole union we avoid claiming it references some particular member of the union.
1604+
// For a transient symbol we want to use the root symbol instead.
1605+
return getCheckFlags(sym) & CheckFlags.Synthetic ? sym : rootSymbol;
16031606
}
16041607

16051608
// Finally, try all properties with the same name in any type the containing type extended or implemented, and
@@ -1613,7 +1616,7 @@ namespace ts.FindAllReferences.Core {
16131616

16141617
const result: Symbol[] = [];
16151618
getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ createSymbolTable(), checker);
1616-
return find(result, search.includes);
1619+
return result.some(search.includes) ? rootSymbol : undefined;
16171620
}
16181621

16191622
return undefined;
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
/// <reference path='fourslash.ts'/>
22

33
////interface I {
4-
//// ["[|{| "isDefinition": true |}prop1|]"]: () => void;
4+
//// [|["[|{| "isDefinition": true |}prop1|]"]|]: () => void;
55
////}
66
////
77
////class C implements I {
8-
//// ["[|{| "isDefinition": true |}prop1|]"]: any;
8+
//// [|["[|{| "isDefinition": true |}prop1|]"]|]: any;
99
////}
1010
////
1111
////var x: I = {
12-
//// ["[|{| "isDefinition": true |}prop1|]"]: function () { },
12+
//// [|["[|{| "isDefinition": true |}prop1|]"]|]: function () { },
1313
////}
1414

15-
const ranges = test.ranges();
16-
const [r0, r1, r2] = ranges;
17-
verify.referenceGroups(r0, [{ definition: '(property) I["prop1"]: () => void', ranges }]);
18-
verify.referenceGroups(r1, [
19-
{ definition: '(property) I["prop1"]: () => void', ranges: [r0, r2] },
20-
{ definition: '(property) C["prop1"]: any', ranges: [r1] }
15+
// TODO: GH#22690
16+
const [r0Big, r0, r1Big, r1, r2Big, r2] = test.ranges();
17+
verify.referenceGroups([r0, r1], [
18+
{ definition: { text: '(property) I["prop1"]: () => void', range: r0Big }, ranges: [r0, r2] },
19+
{ definition: { text: '(property) C["prop1"]: any', range: r1Big }, ranges: [r1] },
2120
]);
2221
verify.referenceGroups(r2, [
23-
{ definition: '(property) I["prop1"]: () => void', ranges: [r0, r1] },
24-
{ definition: '(property) ["prop1"]: () => void', ranges: [r2] }
22+
{ definition: { text: '(property) I["prop1"]: () => void', range: r0Big }, ranges: [r0] },
23+
{ definition: { text: '(property) C["prop1"]: any', range: r1Big }, ranges: [r1] },
24+
{ definition: { text: '(property) ["prop1"]: () => void', range: r2Big }, ranges: [r2] },
2525
]);
26-
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
/// <reference path='fourslash.ts'/>
22

33
////interface I {
4-
//// [[|{| "isDefinition": true |}42|]](): void;
4+
//// [|[[|{| "isDefinition": true |}42|]]|](): void;
55
////}
66
////
77
////class C implements I {
8-
//// [[|{| "isDefinition": true |}42|]]: any;
8+
//// [|[[|{| "isDefinition": true |}42|]]|]: any;
99
////}
1010
////
1111
////var x: I = {
12-
//// ["[|{| "isDefinition": true |}42|]"]: function () { }
12+
//// [|["[|{| "isDefinition": true |}42|]"]|]: function () { }
1313
////}
1414

15-
const ranges = test.ranges();
16-
const [r0, r1, r2] = ranges;
17-
verify.referenceGroups(r0, [{ definition: "(method) I[42](): void", ranges }]);
18-
verify.referenceGroups(r1, [
19-
{ definition: "(method) I[42](): void", ranges: [r0, r2] },
20-
{ definition: "(property) C[42]: any", ranges: [r1] }
15+
// TODO: GH#22690
16+
const [r0Big, r0, r1Big, r1, r2Big, r2] = test.ranges();
17+
verify.referenceGroups([r0, r1], [
18+
{ definition: { text: '(method) I[42](): void', range: r0Big }, ranges: [r0, r2] },
19+
{ definition: { text: '(property) C[42]: any', range: r1Big }, ranges: [r1] },
2120
]);
2221
verify.referenceGroups(r2, [
23-
{ definition: "(method) I[42](): void", ranges: [r0, r1] },
24-
{ definition: '(property) ["42"]: () => void', ranges: [r2] }
22+
{ definition: { text: '(method) I[42](): void', range: r0Big }, ranges: [r0] },
23+
{ definition: { text: '(property) C[42]: any', range: r1Big }, ranges: [r1] },
24+
{ definition: { text: '(property) ["42"]: () => void', range: r2Big }, ranges: [r2] },
2525
]);

tests/cases/fourslash/findAllRefsInClassExpression.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
//// [|{| "isWriteAccess": true, "isDefinition": true |}boom|](){}
66
////}
77

8-
const ranges = test.ranges();
9-
const [r0, r1] = ranges;
10-
verify.referenceGroups(r0, [{ definition: "(method) I.boom(): void", ranges }]);
11-
verify.referenceGroups(r1, [
8+
const [r0, r1] = test.ranges();
9+
verify.referenceGroups([r0, r1], [
1210
{ definition: "(method) I.boom(): void", ranges: [r0] },
1311
{ definition: "(method) C.boom(): void", ranges: [r1] }
1412
]);

tests/cases/fourslash/findAllRefsInheritedProperties3.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,22 @@
1818
//// v.[|propName|]; // r7
1919

2020
const [r0, r1, r2, r3, r4, r5, r6, r7] = test.ranges();
21-
verify.referenceGroups(r0, [{ definition: "(method) class1.doStuff(): void", ranges: [r0, r4, r6] }]);
22-
verify.referenceGroups(r1, [{ definition: "(property) class1.propName: string", ranges: [r1, r5, r7] }]);
23-
verify.referenceGroups(r2, [{ definition: "(method) interface1.doStuff(): void", ranges: [r2, r4, r6] }]);
24-
verify.referenceGroups(r3, [{ definition: "(property) interface1.propName: string", ranges: [r3, r5, r7] }]);
21+
verify.referenceGroups(r0, [
22+
{ definition: "(method) class1.doStuff(): void", ranges: [r0] },
23+
{ definition: "(method) class2.doStuff(): void", ranges: [r4, r6] },
24+
]);
25+
verify.referenceGroups(r1, [
26+
{ definition: "(property) class1.propName: string", ranges: [r1] },
27+
{ definition: "(property) class2.propName: string", ranges: [r5, r7] },
28+
]);
29+
verify.referenceGroups(r2, [
30+
{ definition: "(method) interface1.doStuff(): void", ranges: [r2] },
31+
{ definition: "(method) class2.doStuff(): void", ranges: [r4, r6] },
32+
]);
33+
verify.referenceGroups(r3, [
34+
{ definition: "(property) interface1.propName: string", ranges: [r3] },
35+
{ definition: "(property) class2.propName: string", ranges: [r5, r7] },
36+
]);
2537
verify.referenceGroups([r4, r6], [
2638
{ definition: "(method) class1.doStuff(): void", ranges: [r0] },
2739
{ definition: "(method) interface1.doStuff(): void", ranges: [r2] },

tests/cases/fourslash/findAllRefsParameterPropertyDeclaration_inheritance.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
const [r0, r1, r2, r3] = test.ranges();
1515
verify.referenceGroups(r0, [
16-
{ definition: "(property) C.x: string", ranges: [r0, r2, r3] },
16+
{ definition: "(property) C.x: string", ranges: [r0] },
1717
{ definition: "(parameter) x: string", ranges: [r1] },
18+
{ definition: "(property) D.x: string", ranges: [r2, r3] },
1819
]);
1920
verify.referenceGroups(r1, [
2021
{ definition: "(property) C.x: string", ranges: [r0] },

tests/cases/fourslash/findAllRefsRedeclaredPropertyInDerivedInterface.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
////const b: B = { [|{| "isWriteAccess": true, "isDefinition": true |}x|]: 0 };
1313

1414
const [r0, r1, r2, r3] = test.ranges();
15-
verify.referenceGroups(r0, [
16-
{ definition: "(property) A.x: string | number", ranges: [r0, r1, r2, r3] },
17-
]);
18-
verify.referenceGroups(r1, [
15+
verify.referenceGroups([r0, r1], [
1916
{ definition: "(property) A.x: string | number", ranges: [r0, r2] },
2017
{ definition: "(property) B.x: number", ranges: [r1, r3] },
2118
]);
2219
verify.referenceGroups(r2, [
23-
{ definition: "(property) A.x: string | number", ranges: [r0, r1, r3] },
20+
{ definition: "(property) A.x: string | number", ranges: [r0] },
21+
{ definition: "(property) B.x: number", ranges: [r1, r3] },
2422
{ definition: "(property) x: number", ranges: [r2] },
2523
]);
2624
verify.referenceGroups(r3, [

tests/cases/fourslash/findAllRefsRootSymbols.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
////o.[|x|];
77

88
const [r0, r1, r2, r3] = test.ranges();
9-
verify.referenceGroups(r0, [{ definition: "(property) I.x: {}", ranges: [r0, r3] }]);
10-
verify.referenceGroups(r1, [{ definition: "(property) J.x: {}", ranges: [r1, r3] }]);
11-
verify.referenceGroups(r2, [{ definition: "(property) x: string", ranges: [r2, r3] }]);
12-
verify.referenceGroups(r3, [
13-
{ definition: "(property) I.x: {}", ranges: [r0, r3] },
14-
{ definition: "(property) J.x: {}", ranges: [r1] },
15-
{ definition: "(property) x: string", ranges: [r2] },
16-
]);
9+
const i = { definition: "(property) I.x: {}", ranges: [r0] };
10+
const j = { definition: "(property) J.x: {}", ranges: [r1] };
11+
const anon = { definition: "(property) x: string", ranges: [r2] };
12+
const intersect = { definition: "(property) x: string & {}", ranges: [r3] };
13+
verify.referenceGroups(r0, [i, intersect]);
14+
verify.referenceGroups(r1, [j, intersect]);
15+
verify.referenceGroups(r2, [anon, intersect]);
16+
verify.referenceGroups(r3, [i, j, anon, intersect]);

tests/cases/fourslash/findAllRefsUnionProperty.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
//// | { [|{| "isWriteAccess": true, "isDefinition": true |}type|]: "a" }
55
//// | { [|{| "isWriteAccess": true, "isDefinition": true |}type|]: "b" };
66
////declare const t: T;
7-
////if (t.[|type|] !== "failure") {
7+
////if (t.[|type|] === "a") {
8+
//// t.[|type|];
9+
////} else {
810
//// t.[|type|];
911
////}
1012

1113
const ranges = test.ranges();
12-
const [r0, r1, r2, r3] = ranges;
14+
const [r0, r1, r2, r3, r4] = ranges;
1315
verify.referenceGroups(ranges, [
14-
{ definition: '(property) type: "a"', ranges: [r0, r2, r3] }, // TODO: this have type `"a" | "b"`
15-
{ definition: '(property) type: "b"', ranges: [r1] },
16+
{ definition: { text: '(property) type: "a"', range: r0 }, ranges: [r0, r3] },
17+
{ definition: { text: '(property) type: "b"', range: r1 }, ranges: [r1, r4] },
18+
{ definition: { text: '(property) type: "a" | "b"', range: r0 }, ranges: [r2] },
1619
]);

0 commit comments

Comments
 (0)