Go to definition: pass unverified through server (#43483)

* Pass `unverified` through server

* Update protocol baseline

* Fix unit tests

* Fix other tests
This commit is contained in:
Andrew Branch
2021-04-05 13:42:25 -07:00
committed by GitHub
parent 4b556e37db
commit ffe925ddd5
12 changed files with 39 additions and 26 deletions
+2 -1
View File
@@ -306,7 +306,8 @@ namespace ts.server {
fileName: entry.file,
textSpan: this.decodeSpan(entry),
kind: ScriptElementKind.unknown,
name: ""
name: "",
unverified: entry.unverified,
})),
textSpan: this.decodeSpan(body.textSpan, request.arguments.file)
};
+21 -10
View File
@@ -685,10 +685,10 @@ namespace FourSlash {
}
public verifyGoToDefinitionIs(endMarker: ArrayOrSingle<string>) {
this.verifyGoToXWorker(toArray(endMarker), () => this.getGoToDefinition());
this.verifyGoToXWorker(/*startMarker*/ undefined, toArray(endMarker), () => this.getGoToDefinition());
}
public verifyGoToDefinition(arg0: any, endMarkerNames?: ArrayOrSingle<string> | { file: string }) {
public verifyGoToDefinition(arg0: any, endMarkerNames?: ArrayOrSingle<string | { marker: string, unverified?: boolean }> | { file: string, unverified?: boolean }) {
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan());
}
@@ -705,7 +705,7 @@ namespace FourSlash {
this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition));
}
private verifyGoToX(arg0: any, endMarkerNames: ArrayOrSingle<string> | { file: string } | undefined, getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToX(arg0: any, endMarkerNames: ArrayOrSingle<string | { marker: string, unverified?: boolean }> | { file: string, unverified?: boolean } | undefined, getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
if (endMarkerNames) {
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
}
@@ -725,7 +725,7 @@ namespace FourSlash {
}
}
private verifyGoToXPlain(startMarkerNames: ArrayOrSingle<string>, endMarkerNames: ArrayOrSingle<string> | { file: string }, getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToXPlain(startMarkerNames: ArrayOrSingle<string>, endMarkerNames: ArrayOrSingle<string | { marker: string, unverified?: boolean }> | { file: string, unverified?: boolean }, getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
for (const start of toArray(startMarkerNames)) {
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
}
@@ -737,12 +737,12 @@ namespace FourSlash {
}
}
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: ArrayOrSingle<string> | { file: string }, getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: ArrayOrSingle<string | { marker: string, unverified?: boolean }> | { file: string, unverified?: boolean }, getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
this.goToMarker(startMarkerName);
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName);
this.verifyGoToXWorker(startMarkerName, toArray(endMarkerNames), getDefs, startMarkerName);
}
private verifyGoToXWorker(endMarkers: readonly (string | { file: string })[], getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) {
private verifyGoToXWorker(startMarker: string | undefined, endMarkers: readonly (string | { marker?: string, file?: string, unverified?: boolean })[], getDefs: () => readonly ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) {
const defs = getDefs();
let definitions: readonly ts.DefinitionInfo[];
let testName: string;
@@ -763,8 +763,11 @@ namespace FourSlash {
}
ts.zipWith(endMarkers, definitions, (endMarkerOrFileResult, definition, i) => {
const expectedFileName = typeof endMarkerOrFileResult === "string" ? this.getMarkerByName(endMarkerOrFileResult).fileName : endMarkerOrFileResult.file;
const expectedPosition = typeof endMarkerOrFileResult === "string" ? this.getMarkerByName(endMarkerOrFileResult).position : 0;
const markerName = typeof endMarkerOrFileResult === "string" ? endMarkerOrFileResult : endMarkerOrFileResult.marker;
const marker = markerName !== undefined ? this.getMarkerByName(markerName) : undefined;
const expectedFileName = marker?.fileName || typeof endMarkerOrFileResult !== "string" && endMarkerOrFileResult.file;
ts.Debug.assert(typeof expectedFileName === "string");
const expectedPosition = marker?.position || 0;
if (ts.comparePaths(expectedFileName, definition.fileName, /*ignoreCase*/ true) !== ts.Comparison.EqualTo || expectedPosition !== definition.textSpan.start) {
const filesToDisplay = ts.deduplicate([expectedFileName, definition.fileName], ts.equateValues);
const markers = [{ text: "EXPECTED", fileName: expectedFileName, position: expectedPosition }, { text: "ACTUAL", fileName: definition.fileName, position: definition.textSpan.start }];
@@ -777,7 +780,15 @@ namespace FourSlash {
return `// @Filename: ${fileName}\n${fileContent}`;
}).join("\n\n");
this.raiseError(`${testName} failed for definition ${endMarkerOrFileResult} (${i}): expected ${expectedFileName} at ${expectedPosition}, got ${definition.fileName} at ${definition.textSpan.start}\n\n${text}\n`);
this.raiseError(`${testName} failed for definition ${markerName || expectedFileName} (${i}): expected ${expectedFileName} at ${expectedPosition}, got ${definition.fileName} at ${definition.textSpan.start}\n\n${text}\n`);
}
if (definition.unverified && (typeof endMarkerOrFileResult === "string" || !endMarkerOrFileResult.unverified)) {
const isFileResult = typeof endMarkerOrFileResult !== "string" && !!endMarkerOrFileResult.file;
this.raiseError(
`${testName} failed for definition ${markerName || expectedFileName} (${i}): The actual definition was an \`unverified\` result. Use:\n\n` +
` verify.goToDefinition(${startMarker === undefined ? "startMarker" : `"${startMarker}"`}, { ${isFileResult ? `file: "${expectedFileName}"` : `marker: "${markerName}"`}, unverified: true })\n\n` +
`if this is expected.`
);
}
});
}
+1 -1
View File
@@ -1013,7 +1013,7 @@ namespace ts.server.protocol {
* Definition response message. Gives text range for definition.
*/
export interface DefinitionResponse extends Response {
body?: FileSpanWithContext[];
body?: DefinitionInfo[];
}
export interface DefinitionInfoAndBoundSpanResponse extends Response {
+3 -2
View File
@@ -1224,6 +1224,7 @@ namespace ts.server {
containerName: info.containerName,
kind: info.kind,
name: info.name,
...info.unverified && { unverified: info.unverified },
};
});
}
@@ -1300,8 +1301,8 @@ namespace ts.server {
}));
}
private mapDefinitionInfo(definitions: readonly DefinitionInfo[], project: Project): readonly protocol.FileSpanWithContext[] {
return definitions.map(def => this.toFileSpanWithContext(def.fileName, def.textSpan, def.contextSpan, project));
private mapDefinitionInfo(definitions: readonly DefinitionInfo[], project: Project): readonly protocol.DefinitionInfo[] {
return definitions.map(def => ({ ...this.toFileSpanWithContext(def.fileName, def.textSpan, def.contextSpan, project), ...def.unverified && { unverified: def.unverified } }));
}
/*
+1 -1
View File
@@ -146,7 +146,7 @@ namespace ts.GoToDefinition {
end: node.getEnd(),
fileName: node.text
},
unverified: !!verifiedFileName,
unverified: !verifiedFileName,
};
}
}
@@ -218,7 +218,7 @@ function fooB() { }`
assert.deepEqual(response.definitions, [{
file: file2.path,
start: { line: 1, offset: 1 },
end: { line: 1, offset: 1 }
end: { line: 1, offset: 1 },
}]);
});
});
@@ -4436,4 +4436,4 @@ ${dependencyTs.content}`);
});
});
});
}
}
+1 -1
View File
@@ -7403,7 +7403,7 @@ declare namespace ts.server.protocol {
* Definition response message. Gives text range for definition.
*/
interface DefinitionResponse extends Response {
body?: FileSpanWithContext[];
body?: DefinitionInfo[];
}
interface DefinitionInfoAndBoundSpanResponse extends Response {
body?: DefinitionInfoAndBoundSpan;
+2 -2
View File
@@ -286,8 +286,8 @@ declare namespace FourSlashInterface {
* `verify.goToDefinition(["a", "aa"], "b");` verifies that markers "a" and "aa" have the same definition "b".
* `verify.goToDefinition("a", ["b", "bb"]);` verifies that "a" has multiple definitions available.
*/
goToDefinition(startMarkerNames: ArrayOrSingle<string>, fileResult: { file: string }): void;
goToDefinition(startMarkerNames: ArrayOrSingle<string>, endMarkerNames: ArrayOrSingle<string>): void;
goToDefinition(startMarkerNames: ArrayOrSingle<string>, fileResult: { file: string, unverified?: boolean }): void;
goToDefinition(startMarkerNames: ArrayOrSingle<string>, endMarkerNames: ArrayOrSingle<string | { marker: string, unverified?: boolean }>): void;
goToDefinition(startMarkerNames: ArrayOrSingle<string>, endMarkerNames: ArrayOrSingle<string>, range: Range): void;
/** Performs `goToDefinition` for each pair. */
goToDefinition(startsAndEnds: [ArrayOrSingle<string>, ArrayOrSingle<string>][]): void;
@@ -14,4 +14,4 @@
// @Filename: index.ts
//// import styles from [|/*1*/"./index.css"|];
verify.goToDefinition("1", ["2a", "2b"]);
verify.goToDefinition("1", [{ marker: "2a", unverified: true }, "2b"]);
@@ -16,5 +16,5 @@
// not JS/TS, but if we can, you should be able to jump to it.
//// import [|/*2*/"./stylez.css"|];
verify.goToDefinition("1", "1d");
verify.goToDefinition("2", "2d");
verify.goToDefinition("1", { marker: "1d", unverified: true });
verify.goToDefinition("2", { marker: "2d", unverified: true });
@@ -19,6 +19,6 @@
// does not exist, but should return a response to it anyway so an editor can create it.
//// import [|/*3*/"./foo.txt"|];
verify.goToDefinition("1", "1d");
verify.goToDefinition("2", "2d");
verify.goToDefinition("3", { file: "/foo.txt" });
verify.goToDefinition("1", { marker: "1d", unverified: true });
verify.goToDefinition("2", { marker: "2d", unverified: true });
verify.goToDefinition("3", { file: "/foo.txt", unverified: true });