Skip to content

Commit 3c91133

Browse files
authored
Fix find-all-references on undefined (#39591)
* Fix find-all-references on `undefined` * Show references in input files in baseline * Inline commentEachLine * firstOrUndefined doesn’t take undefined
1 parent 1e7d089 commit 3c91133

File tree

6 files changed

+120
-1
lines changed

6 files changed

+120
-1
lines changed

src/harness/fourslashImpl.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,43 @@ namespace FourSlash {
10841084
}
10851085
}
10861086

1087+
public verifyBaselineFindAllReferences(markerName: string) {
1088+
const marker = this.getMarkerByName(markerName);
1089+
const references = this.languageService.findReferences(marker.fileName, marker.position);
1090+
const refsByFile = references
1091+
? ts.group(ts.sort(ts.flatMap(references, r => r.references), (a, b) => a.textSpan.start - b.textSpan.start), ref => ref.fileName)
1092+
: ts.emptyArray;
1093+
1094+
// Write input files
1095+
let baselineContent = "";
1096+
for (const group of refsByFile) {
1097+
baselineContent += getBaselineContentForFile(group[0].fileName, this.getFileContent(group[0].fileName));
1098+
baselineContent += "\n\n";
1099+
}
1100+
1101+
// Write response JSON
1102+
baselineContent += JSON.stringify(references, undefined, 2);
1103+
Harness.Baseline.runBaseline(this.getBaselineFileNameForContainingTestFile(".baseline.jsonc"), baselineContent);
1104+
1105+
function getBaselineContentForFile(fileName: string, content: string) {
1106+
let newContent = `=== ${fileName} ===\n`;
1107+
let pos = 0;
1108+
for (const { textSpan } of refsByFile.find(refs => refs[0].fileName === fileName) ?? ts.emptyArray) {
1109+
if (fileName === marker.fileName && ts.textSpanContainsPosition(textSpan, marker.position)) {
1110+
newContent += "/*FIND ALL REFS*/";
1111+
}
1112+
const end = textSpan.start + textSpan.length;
1113+
newContent += content.slice(pos, textSpan.start);
1114+
newContent += "[|";
1115+
newContent += content.slice(textSpan.start, end);
1116+
newContent += "|]";
1117+
pos = end;
1118+
}
1119+
newContent += content.slice(pos);
1120+
return newContent.split(/\r?\n/).map(l => "// " + l).join("\n");
1121+
}
1122+
}
1123+
10871124
public verifyNoReferences(markerNameOrRange?: string | Range) {
10881125
if (markerNameOrRange !== undefined) this.goToMarkerOrRange(markerNameOrRange);
10891126
const refs = this.getReferencesAtCaret();

src/harness/fourslashInterfaceImpl.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ namespace FourSlashInterface {
316316
this.state.verifyTypeOfSymbolAtLocation(range, symbol, expected);
317317
}
318318

319+
public baselineFindAllReferences(markerName: string) {
320+
this.state.verifyBaselineFindAllReferences(markerName);
321+
}
322+
319323
public referenceGroups(starts: ArrayOrSingle<string> | ArrayOrSingle<FourSlash.Range>, parts: ReferenceGroup[]) {
320324
this.state.verifyReferenceGroups(starts, parts);
321325
}

src/services/findAllReferences.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ namespace ts.FindAllReferences {
304304
const { symbol } = def;
305305
const { displayParts, kind } = getDefinitionKindAndDisplayParts(symbol, checker, originalNode);
306306
const name = displayParts.map(p => p.text).join("");
307-
const declaration = symbol.declarations ? first(symbol.declarations) : undefined;
307+
const declaration = symbol.declarations && firstOrUndefined(symbol.declarations);
308308
return {
309309
node: declaration ?
310310
getNameOfDeclaration(declaration) || declaration :
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// === /a.ts ===
2+
// /*FIND ALL REFS*/[|undefined|];
3+
//
4+
// void [|undefined|];
5+
6+
// === /b.ts ===
7+
// [|undefined|];
8+
9+
[
10+
{
11+
"definition": {
12+
"containerKind": "",
13+
"containerName": "",
14+
"fileName": "/a.ts",
15+
"kind": "var",
16+
"name": "var undefined",
17+
"textSpan": {
18+
"start": 0,
19+
"length": 9
20+
},
21+
"displayParts": [
22+
{
23+
"text": "var",
24+
"kind": "keyword"
25+
},
26+
{
27+
"text": " ",
28+
"kind": "space"
29+
},
30+
{
31+
"text": "undefined",
32+
"kind": "propertyName"
33+
}
34+
]
35+
},
36+
"references": [
37+
{
38+
"textSpan": {
39+
"start": 0,
40+
"length": 9
41+
},
42+
"fileName": "/a.ts",
43+
"isWriteAccess": false,
44+
"isDefinition": false
45+
},
46+
{
47+
"textSpan": {
48+
"start": 17,
49+
"length": 9
50+
},
51+
"fileName": "/a.ts",
52+
"isWriteAccess": false,
53+
"isDefinition": false
54+
},
55+
{
56+
"textSpan": {
57+
"start": 0,
58+
"length": 9
59+
},
60+
"fileName": "/b.ts",
61+
"isWriteAccess": false,
62+
"isDefinition": false
63+
}
64+
]
65+
}
66+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: /a.ts
4+
//// /**/undefined;
5+
////
6+
//// void undefined;
7+
8+
// @Filename: /b.ts
9+
//// undefined;
10+
11+
verify.baselineFindAllReferences("");

tests/cases/fourslash/fourslash.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ declare namespace FourSlashInterface {
289289
goToType(startMarkerNames: ArrayOrSingle<string>, endMarkerNames: ArrayOrSingle<string>): void;
290290
verifyGetEmitOutputForCurrentFile(expected: string): void;
291291
verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void;
292+
baselineFindAllReferences(markerName: string): void;
292293
noReferences(markerNameOrRange?: string | Range): void;
293294
symbolAtLocation(startRange: Range, ...declarationRanges: Range[]): void;
294295
typeOfSymbolAtLocation(range: Range, symbol: any, expected: string): void;

0 commit comments

Comments
 (0)