Skip to content

Commit cf2bdf8

Browse files
authored
Merge pull request microsoft#19175 from armanio123/AddDefinitionAndBoundSpan
Added DefinitionAndBoundSpan command
2 parents deb9488 + d5c18a6 commit cf2bdf8

File tree

90 files changed

+360
-199
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+360
-199
lines changed

src/harness/fourslash.ts

+45-9
Original file line numberDiff line numberDiff line change
@@ -616,19 +616,23 @@ namespace FourSlash {
616616
}
617617

618618
public verifyGoToDefinition(arg0: any, endMarkerNames?: string | string[]) {
619-
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinition());
619+
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan());
620620
}
621621

622622
private getGoToDefinition(): ts.DefinitionInfo[] {
623623
return this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
624624
}
625625

626+
private getGoToDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan {
627+
return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition);
628+
}
629+
626630
public verifyGoToType(arg0: any, endMarkerNames?: string | string[]) {
627631
this.verifyGoToX(arg0, endMarkerNames, () =>
628632
this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition));
629633
}
630634

631-
private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | undefined) {
635+
private verifyGoToX(arg0: any, endMarkerNames: string | string[] | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
632636
if (endMarkerNames) {
633637
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
634638
}
@@ -648,7 +652,7 @@ namespace FourSlash {
648652
}
649653
}
650654

651-
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
655+
private verifyGoToXPlain(startMarkerNames: string | string[], endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
652656
for (const start of toArray(startMarkerNames)) {
653657
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
654658
}
@@ -660,26 +664,57 @@ namespace FourSlash {
660664
}
661665
}
662666

663-
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
667+
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: string | string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
664668
this.goToMarker(startMarkerName);
665-
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs);
669+
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName);
666670
}
667671

668-
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | undefined) {
669-
const definitions = getDefs() || [];
672+
private verifyGoToXWorker(endMarkers: string[], getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined, startMarkerName?: string) {
673+
const defs = getDefs();
674+
let definitions: ts.DefinitionInfo[] | ReadonlyArray<ts.DefinitionInfo>;
675+
let testName: string;
676+
677+
if (!defs || Array.isArray(defs)) {
678+
definitions = defs as ts.DefinitionInfo[] || [];
679+
testName = "goToDefinitions";
680+
}
681+
else {
682+
this.verifyDefinitionTextSpan(defs, startMarkerName);
683+
684+
definitions = defs.definitions;
685+
testName = "goToDefinitionsAndBoundSpan";
686+
}
670687

671688
if (endMarkers.length !== definitions.length) {
672-
this.raiseError(`goToDefinitions failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
689+
this.raiseError(`${testName} failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
673690
}
674691

675692
ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => {
676693
const marker = this.getMarkerByName(endMarker);
677694
if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) {
678-
this.raiseError(`goToDefinition failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
695+
this.raiseError(`${testName} failed for definition ${endMarker} (${i}): expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
679696
}
680697
});
681698
}
682699

700+
private verifyDefinitionTextSpan(defs: ts.DefinitionInfoAndBoundSpan, startMarkerName: string) {
701+
const range = this.testData.ranges.find(range => this.markerName(range.marker) === startMarkerName);
702+
703+
if (!range && !defs.textSpan) {
704+
return;
705+
}
706+
707+
if (!range) {
708+
this.raiseError(`goToDefinitionsAndBoundSpan failed - found a TextSpan ${JSON.stringify(defs.textSpan)} when it wasn't expected.`);
709+
}
710+
else if (defs.textSpan.start !== range.start || defs.textSpan.length !== range.end - range.start) {
711+
const expected: ts.TextSpan = {
712+
start: range.start, length: range.end - range.start
713+
};
714+
this.raiseError(`goToDefinitionsAndBoundSpan failed - expected to find TextSpan ${JSON.stringify(expected)} but got ${JSON.stringify(defs.textSpan)}`);
715+
}
716+
}
717+
683718
public verifyGetEmitOutputForCurrentFile(expected: string): void {
684719
const emit = this.languageService.getEmitOutput(this.activeFile.fileName);
685720
if (emit.outputFiles.length !== 1) {
@@ -3933,6 +3968,7 @@ namespace FourSlashInterface {
39333968
}
39343969

39353970
public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[]): void;
3971+
public goToDefinition(startMarkerName: string | string[], endMarkerName: string | string[], range: FourSlash.Range): void;
39363972
public goToDefinition(startsAndEnds: [string | string[], string | string[]][]): void;
39373973
public goToDefinition(startsAndEnds: { [startMarkerName: string]: string | string[] }): void;
39383974
public goToDefinition(arg0: any, endMarkerName?: string | string[]) {

src/harness/harnessLanguageService.ts

+3
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,9 @@ namespace Harness.LanguageService {
443443
getDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
444444
return unwrapJSONCallResult(this.shim.getDefinitionAtPosition(fileName, position));
445445
}
446+
getDefinitionAndBoundSpan(fileName: string, position: number): ts.DefinitionInfoAndBoundSpan {
447+
return unwrapJSONCallResult(this.shim.getDefinitionAndBoundSpan(fileName, position));
448+
}
446449
getTypeDefinitionAtPosition(fileName: string, position: number): ts.DefinitionInfo[] {
447450
return unwrapJSONCallResult(this.shim.getTypeDefinitionAtPosition(fileName, position));
448451
}

src/harness/unittests/session.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ namespace ts.server {
128128
body: undefined
129129
});
130130
});
131-
it ("should handle literal types in request", () => {
131+
it("should handle literal types in request", () => {
132132
const configureRequest: protocol.ConfigureRequest = {
133133
command: CommandNames.Configure,
134134
seq: 0,
@@ -186,6 +186,8 @@ namespace ts.server {
186186
CommandNames.Configure,
187187
CommandNames.Definition,
188188
CommandNames.DefinitionFull,
189+
CommandNames.DefinitionAndBoundSpan,
190+
CommandNames.DefinitionAndBoundSpanFull,
189191
CommandNames.Implementation,
190192
CommandNames.ImplementationFull,
191193
CommandNames.Exit,
@@ -352,7 +354,7 @@ namespace ts.server {
352354
session.addProtocolHandler(command, () => resp);
353355

354356
expect(() => session.addProtocolHandler(command, () => resp))
355-
.to.throw(`Protocol handler already exists for command "${command}"`);
357+
.to.throw(`Protocol handler already exists for command "${command}"`);
356358
});
357359
});
358360

src/server/client.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,25 @@ namespace ts.server {
270270
}));
271271
}
272272

273+
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan {
274+
const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position);
275+
276+
const request = this.processRequest<protocol.DefinitionRequest>(CommandNames.DefinitionAndBoundSpan, args);
277+
const response = this.processResponse<protocol.DefinitionInfoAndBoundSpanReponse>(request);
278+
279+
return {
280+
definitions: response.body.definitions.map(entry => ({
281+
containerKind: ScriptElementKind.unknown,
282+
containerName: "",
283+
fileName: entry.file,
284+
textSpan: this.decodeSpan(entry),
285+
kind: ScriptElementKind.unknown,
286+
name: ""
287+
})),
288+
textSpan: this.decodeSpan(response.body.textSpan, request.arguments.file)
289+
};
290+
}
291+
273292
getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] {
274293
const args: protocol.FileLocationRequestArgs = this.createFileLocationRequestArgs(fileName, position);
275294

@@ -324,7 +343,7 @@ namespace ts.server {
324343
}
325344

326345
getSyntacticDiagnostics(file: string): Diagnostic[] {
327-
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true };
346+
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file, includeLinePosition: true };
328347

329348
const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest>(CommandNames.SyntacticDiagnosticsSync, args);
330349
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse>(request);

src/server/protocol.ts

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ namespace ts.server.protocol {
2121
Definition = "definition",
2222
/* @internal */
2323
DefinitionFull = "definition-full",
24+
DefinitionAndBoundSpan = "definitionAndBoundSpan",
25+
/* @internal */
26+
DefinitionAndBoundSpanFull = "definitionAndBoundSpan-full",
2427
Implementation = "implementation",
2528
/* @internal */
2629
ImplementationFull = "implementation-full",
@@ -708,13 +711,22 @@ namespace ts.server.protocol {
708711
file: string;
709712
}
710713

714+
export interface DefinitionInfoAndBoundSpan {
715+
definitions: ReadonlyArray<FileSpan>;
716+
textSpan: TextSpan;
717+
}
718+
711719
/**
712720
* Definition response message. Gives text range for definition.
713721
*/
714722
export interface DefinitionResponse extends Response {
715723
body?: FileSpan[];
716724
}
717725

726+
export interface DefinitionInfoAndBoundSpanReponse extends Response {
727+
body?: DefinitionInfoAndBoundSpan;
728+
}
729+
718730
/**
719731
* Definition response message. Gives text range for definition.
720732
*/

0 commit comments

Comments
 (0)