mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 18:49:00 +01:00
Add Go To Implementation Api (#18346)
* Add Go To Implementation Api For #10806 Adds a new API for supporting `go to implementation` command for languages. Implements an example for TS * Rename * Cleanup
This commit is contained in:
@@ -5,50 +5,18 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { DefinitionProvider, TextDocument, Position, Range, CancellationToken, Definition, Location } from 'vscode';
|
||||
import { DefinitionProvider, TextDocument, Position, CancellationToken, Definition } from 'vscode';
|
||||
|
||||
import * as Proto from '../protocol';
|
||||
import { ITypescriptServiceClient } from '../typescriptService';
|
||||
import DefinitionProviderBase from './definitionProviderBase';
|
||||
|
||||
export default class TypeScriptDefinitionProvider implements DefinitionProvider {
|
||||
|
||||
private client: ITypescriptServiceClient;
|
||||
|
||||
public tokens: string[] = [];
|
||||
export default class TypeScriptDefinitionProvider extends DefinitionProviderBase implements DefinitionProvider {
|
||||
|
||||
constructor(client: ITypescriptServiceClient) {
|
||||
this.client = client;
|
||||
super(client);
|
||||
}
|
||||
|
||||
public provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Promise<Definition | null> {
|
||||
const filepath = this.client.asAbsolutePath(document.uri);
|
||||
if (!filepath) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
let args: Proto.FileLocationRequestArgs = {
|
||||
file: filepath,
|
||||
line: position.line + 1,
|
||||
offset: position.character + 1
|
||||
};
|
||||
if (!args.file) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
return this.client.execute('definition', args, token).then(response => {
|
||||
let locations: Proto.FileSpan[] = response.body || [];
|
||||
if (!locations || locations.length === 0) {
|
||||
return [] as Definition;
|
||||
}
|
||||
return locations.map(location => {
|
||||
let resource = this.client.asUrl(location.file);
|
||||
if (resource === null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Location(resource, new Range(location.start.line - 1, location.start.offset - 1, location.end.line - 1, location.end.offset - 1));
|
||||
}
|
||||
}).filter(x => x !== null) as Location[];
|
||||
}, (error) => {
|
||||
this.client.error(`'definition' request failed with error.`, error);
|
||||
return [] as Definition;
|
||||
});
|
||||
public provideDefinition(document: TextDocument, position: Position, token: CancellationToken | boolean): Promise<Definition | null> {
|
||||
return this.getSymbolLocations('definition', document, position, token);
|
||||
}
|
||||
}
|
||||
54
extensions/typescript/src/features/definitionProviderBase.ts
Normal file
54
extensions/typescript/src/features/definitionProviderBase.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TextDocument, Position, Range, CancellationToken, Location } from 'vscode';
|
||||
|
||||
import * as Proto from '../protocol';
|
||||
import { ITypescriptServiceClient } from '../typescriptService';
|
||||
|
||||
export default class TypeScriptDefinitionProviderBase {
|
||||
|
||||
private client: ITypescriptServiceClient;
|
||||
|
||||
public tokens: string[] = [];
|
||||
|
||||
constructor(client: ITypescriptServiceClient) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
protected getSymbolLocations(definitionType: 'definition' | 'implementation', document: TextDocument, position: Position, token: CancellationToken | boolean): Promise<Location[] | null> {
|
||||
const filepath = this.client.asAbsolutePath(document.uri);
|
||||
if (!filepath) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
let args: Proto.FileLocationRequestArgs = {
|
||||
file: filepath,
|
||||
line: position.line + 1,
|
||||
offset: position.character + 1
|
||||
};
|
||||
if (!args.file) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
return this.client.execute(definitionType, args, token).then(response => {
|
||||
let locations: Proto.FileSpan[] = (response && response.body) || [];
|
||||
if (!locations || locations.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return locations.map(location => {
|
||||
let resource = this.client.asUrl(location.file);
|
||||
if (resource === null) {
|
||||
return null;
|
||||
} else {
|
||||
return new Location(resource, new Range(location.start.line - 1, location.start.offset - 1, location.end.line - 1, location.end.offset - 1));
|
||||
}
|
||||
}).filter(x => x !== null) as Location[];
|
||||
}, (error) => {
|
||||
this.client.error(`'${definitionType}' request failed with error.`, error);
|
||||
return [];
|
||||
});
|
||||
}
|
||||
}
|
||||
22
extensions/typescript/src/features/typeDefinitionProvider.ts
Normal file
22
extensions/typescript/src/features/typeDefinitionProvider.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TypeDefinitionProvider, TextDocument, Position, CancellationToken, Definition } from 'vscode';
|
||||
|
||||
import { ITypescriptServiceClient } from '../typescriptService';
|
||||
import DefinitionProviderBase from './definitionProviderBase';
|
||||
|
||||
export default class TypeScriptTypeDefinitionProvider extends DefinitionProviderBase implements TypeDefinitionProvider {
|
||||
|
||||
constructor(client: ITypescriptServiceClient) {
|
||||
super(client);
|
||||
}
|
||||
|
||||
public provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken | boolean): Promise<Definition | null> {
|
||||
return this.getSymbolLocations('implementation', document, position, token);
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import { ITypescriptServiceClientHost } from './typescriptService';
|
||||
|
||||
import HoverProvider from './features/hoverProvider';
|
||||
import DefinitionProvider from './features/definitionProvider';
|
||||
import TypeDefinitionProvider from './features/TypeDefinitionProvider';
|
||||
import DocumentHighlightProvider from './features/documentHighlightProvider';
|
||||
import ReferenceProvider from './features/referenceProvider';
|
||||
import DocumentSymbolProvider from './features/documentSymbolProvider';
|
||||
@@ -147,6 +148,7 @@ class LanguageProvider {
|
||||
|
||||
let hoverProvider = new HoverProvider(client);
|
||||
let definitionProvider = new DefinitionProvider(client);
|
||||
let typeDefinitionProvider = new TypeDefinitionProvider(client);
|
||||
let documentHighlightProvider = new DocumentHighlightProvider(client);
|
||||
let referenceProvider = new ReferenceProvider(client);
|
||||
let documentSymbolProvider = new DocumentSymbolProvider(client);
|
||||
@@ -169,6 +171,7 @@ class LanguageProvider {
|
||||
languages.registerCompletionItemProvider(selector, this.completionItemProvider, '.');
|
||||
languages.registerHoverProvider(selector, hoverProvider);
|
||||
languages.registerDefinitionProvider(selector, definitionProvider);
|
||||
languages.registerTypeDefinitionProvider(selector, typeDefinitionProvider);
|
||||
languages.registerDocumentHighlightProvider(selector, documentHighlightProvider);
|
||||
languages.registerReferenceProvider(selector, referenceProvider);
|
||||
languages.registerDocumentSymbolProvider(selector, documentSymbolProvider);
|
||||
|
||||
@@ -87,6 +87,7 @@ export interface ITypescriptServiceClient {
|
||||
execute(commant: 'completionEntryDetails', args: Proto.CompletionDetailsRequestArgs, token?: CancellationToken): Promise<Proto.CompletionDetailsResponse>;
|
||||
execute(commant: 'signatureHelp', args: Proto.SignatureHelpRequestArgs, token?: CancellationToken): Promise<Proto.SignatureHelpResponse>;
|
||||
execute(command: 'definition', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.DefinitionResponse>;
|
||||
execute(command: 'implementation', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.ImplementationResponse>;
|
||||
execute(command: 'references', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.ReferencesResponse>;
|
||||
execute(command: 'navto', args: Proto.NavtoRequestArgs, token?: CancellationToken): Promise<Proto.NavtoResponse>;
|
||||
execute(command: 'navbar', args: Proto.FileRequestArgs, token?: CancellationToken): Promise<Proto.NavBarResponse>;
|
||||
|
||||
Reference in New Issue
Block a user