From d1f465104b49c75721f7bd7a8a417eefdf3872d0 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 13 Jul 2020 12:19:50 -0700 Subject: [PATCH 1/4] Fix find-all-references on `undefined` --- src/harness/fourslashImpl.ts | 14 +++++++ src/harness/fourslashInterfaceImpl.ts | 4 ++ src/services/findAllReferences.ts | 2 +- .../findAllReferencesUndefined.baseline.jsonc | 42 +++++++++++++++++++ .../fourslash/findAllReferencesUndefined.ts | 5 +++ tests/cases/fourslash/fourslash.ts | 1 + 6 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc create mode 100644 tests/cases/fourslash/findAllReferencesUndefined.ts diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index ca95ff34ebb72..49eb761ef688a 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -1084,6 +1084,20 @@ namespace FourSlash { } } + public verifyBaselineFindAllReferences(markerName: string) { + const marker = this.getMarkerByName(markerName); + const references = this.languageService.findReferences(marker.fileName, marker.position); + const commentEachLine = (source: string) => source.split(/\r?\n/).map(l => "// " + l).join("\n"); + const baselineContent = + commentEachLine( + this.getFileContent(marker.fileName).slice(0, marker.position) + + "/*FIND ALL REFERENCES*/" + + this.getFileContent(marker.fileName).slice(marker.position)) + + "\n\n" + JSON.stringify(references, undefined, 2); + + Harness.Baseline.runBaseline(this.getBaselineFileNameForContainingTestFile(".baseline.jsonc"), baselineContent); + } + public verifyNoReferences(markerNameOrRange?: string | Range) { if (markerNameOrRange !== undefined) this.goToMarkerOrRange(markerNameOrRange); const refs = this.getReferencesAtCaret(); diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index dcbd07b4dbf09..821a3c40ec570 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -316,6 +316,10 @@ namespace FourSlashInterface { this.state.verifyTypeOfSymbolAtLocation(range, symbol, expected); } + public baselineFindAllReferences(markerName: string) { + this.state.verifyBaselineFindAllReferences(markerName); + } + public referenceGroups(starts: ArrayOrSingle | ArrayOrSingle, parts: ReferenceGroup[]) { this.state.verifyReferenceGroups(starts, parts); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 1d7dbb8d66915..e87bbc7b08dd2 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -304,7 +304,7 @@ namespace ts.FindAllReferences { const { symbol } = def; const { displayParts, kind } = getDefinitionKindAndDisplayParts(symbol, checker, originalNode); const name = displayParts.map(p => p.text).join(""); - const declaration = symbol.declarations ? first(symbol.declarations) : undefined; + const declaration = firstOrUndefined(symbol.declarations); return { node: declaration ? getNameOfDeclaration(declaration) || declaration : diff --git a/tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc b/tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc new file mode 100644 index 0000000000000..85de10bea9e75 --- /dev/null +++ b/tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc @@ -0,0 +1,42 @@ +// /*FIND ALL REFERENCES*/undefined; + +[ + { + "definition": { + "containerKind": "", + "containerName": "", + "fileName": "/tests/cases/fourslash/findAllReferencesUndefined.ts", + "kind": "var", + "name": "var undefined", + "textSpan": { + "start": 0, + "length": 9 + }, + "displayParts": [ + { + "text": "var", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "undefined", + "kind": "propertyName" + } + ] + }, + "references": [ + { + "textSpan": { + "start": 0, + "length": 9 + }, + "fileName": "/tests/cases/fourslash/findAllReferencesUndefined.ts", + "isWriteAccess": false, + "isDefinition": false + } + ] + } +] \ No newline at end of file diff --git a/tests/cases/fourslash/findAllReferencesUndefined.ts b/tests/cases/fourslash/findAllReferencesUndefined.ts new file mode 100644 index 0000000000000..12a5331561dc6 --- /dev/null +++ b/tests/cases/fourslash/findAllReferencesUndefined.ts @@ -0,0 +1,5 @@ +/// + +//// /**/undefined; + +verify.baselineFindAllReferences(""); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index a2be4e57a2e0a..6519e27fde00e 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -289,6 +289,7 @@ declare namespace FourSlashInterface { goToType(startMarkerNames: ArrayOrSingle, endMarkerNames: ArrayOrSingle): void; verifyGetEmitOutputForCurrentFile(expected: string): void; verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void; + baselineFindAllReferences(markerName: string): void; noReferences(markerNameOrRange?: string | Range): void; symbolAtLocation(startRange: Range, ...declarationRanges: Range[]): void; typeOfSymbolAtLocation(range: Range, symbol: any, expected: string): void; From 18eaf9b75987a13f3a2c37011a7a733d34556628 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 13 Jul 2020 13:51:01 -0700 Subject: [PATCH 2/4] Show references in input files in baseline --- src/harness/fourslashImpl.ts | 40 +++++++++++++++---- .../findAllReferencesUndefined.baseline.jsonc | 30 ++++++++++++-- .../fourslash/findAllReferencesUndefined.ts | 6 +++ 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 49eb761ef688a..61ad75c06bb30 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -1087,15 +1087,41 @@ namespace FourSlash { public verifyBaselineFindAllReferences(markerName: string) { const marker = this.getMarkerByName(markerName); const references = this.languageService.findReferences(marker.fileName, marker.position); - const commentEachLine = (source: string) => source.split(/\r?\n/).map(l => "// " + l).join("\n"); - const baselineContent = - commentEachLine( - this.getFileContent(marker.fileName).slice(0, marker.position) + - "/*FIND ALL REFERENCES*/" + - this.getFileContent(marker.fileName).slice(marker.position)) + - "\n\n" + JSON.stringify(references, undefined, 2); + const refsByFile = references + ? ts.group(ts.sort(ts.flatMap(references, r => r.references), (a, b) => a.textSpan.start - b.textSpan.start), ref => ref.fileName) + : ts.emptyArray; + // Write input files + let baselineContent = ""; + for (const group of refsByFile) { + baselineContent += getBaselineContentForFile(group[0].fileName, this.getFileContent(group[0].fileName)); + baselineContent += "\n\n"; + } + + // Write response JSON + baselineContent += JSON.stringify(references, undefined, 2); Harness.Baseline.runBaseline(this.getBaselineFileNameForContainingTestFile(".baseline.jsonc"), baselineContent); + + function commentEachLine(source: string) { + return source.split(/\r?\n/).map(l => "// " + l).join("\n"); + } + function getBaselineContentForFile(fileName: string, content: string) { + let newContent = `=== ${fileName} ===\n`; + let pos = 0; + for (const { textSpan } of refsByFile.find(refs => refs[0].fileName === fileName) ?? ts.emptyArray) { + if (fileName === marker.fileName && ts.textSpanContainsPosition(textSpan, marker.position)) { + newContent += "/*FIND ALL REFS*/"; + } + const end = textSpan.start + textSpan.length; + newContent += content.slice(pos, textSpan.start); + newContent += "[|"; + newContent += content.slice(textSpan.start, end); + newContent += "|]"; + pos = end; + } + newContent += content.slice(pos); + return commentEachLine(newContent); + } } public verifyNoReferences(markerNameOrRange?: string | Range) { diff --git a/tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc b/tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc index 85de10bea9e75..e9aa9e9d9bb6e 100644 --- a/tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc +++ b/tests/baselines/reference/findAllReferencesUndefined.baseline.jsonc @@ -1,11 +1,17 @@ -// /*FIND ALL REFERENCES*/undefined; +// === /a.ts === +// /*FIND ALL REFS*/[|undefined|]; +// +// void [|undefined|]; + +// === /b.ts === +// [|undefined|]; [ { "definition": { "containerKind": "", "containerName": "", - "fileName": "/tests/cases/fourslash/findAllReferencesUndefined.ts", + "fileName": "/a.ts", "kind": "var", "name": "var undefined", "textSpan": { @@ -33,7 +39,25 @@ "start": 0, "length": 9 }, - "fileName": "/tests/cases/fourslash/findAllReferencesUndefined.ts", + "fileName": "/a.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 17, + "length": 9 + }, + "fileName": "/a.ts", + "isWriteAccess": false, + "isDefinition": false + }, + { + "textSpan": { + "start": 0, + "length": 9 + }, + "fileName": "/b.ts", "isWriteAccess": false, "isDefinition": false } diff --git a/tests/cases/fourslash/findAllReferencesUndefined.ts b/tests/cases/fourslash/findAllReferencesUndefined.ts index 12a5331561dc6..f129b6d499074 100644 --- a/tests/cases/fourslash/findAllReferencesUndefined.ts +++ b/tests/cases/fourslash/findAllReferencesUndefined.ts @@ -1,5 +1,11 @@ /// +// @Filename: /a.ts //// /**/undefined; +//// +//// void undefined; + +// @Filename: /b.ts +//// undefined; verify.baselineFindAllReferences(""); From 195def6d56a8931e417e34de16062e2670afb916 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 13 Jul 2020 14:34:28 -0700 Subject: [PATCH 3/4] Inline commentEachLine --- src/harness/fourslashImpl.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 61ad75c06bb30..f33768ebb7c58 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -1102,9 +1102,6 @@ namespace FourSlash { baselineContent += JSON.stringify(references, undefined, 2); Harness.Baseline.runBaseline(this.getBaselineFileNameForContainingTestFile(".baseline.jsonc"), baselineContent); - function commentEachLine(source: string) { - return source.split(/\r?\n/).map(l => "// " + l).join("\n"); - } function getBaselineContentForFile(fileName: string, content: string) { let newContent = `=== ${fileName} ===\n`; let pos = 0; @@ -1120,7 +1117,7 @@ namespace FourSlash { pos = end; } newContent += content.slice(pos); - return commentEachLine(newContent); + return newContent.split(/\r?\n/).map(l => "// " + l).join("\n"); } } From 77b32b1b31dc776fd3690862222fd2eac3c284a7 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 13 Jul 2020 16:19:47 -0700 Subject: [PATCH 4/4] =?UTF-8?q?firstOrUndefined=20doesn=E2=80=99t=20take?= =?UTF-8?q?=20undefined?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/findAllReferences.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index e87bbc7b08dd2..158b16d00c7f1 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -304,7 +304,7 @@ namespace ts.FindAllReferences { const { symbol } = def; const { displayParts, kind } = getDefinitionKindAndDisplayParts(symbol, checker, originalNode); const name = displayParts.map(p => p.text).join(""); - const declaration = firstOrUndefined(symbol.declarations); + const declaration = symbol.declarations && firstOrUndefined(symbol.declarations); return { node: declaration ? getNameOfDeclaration(declaration) || declaration :