From 44cd521ced3927ceef696028bd5d63ca977d9b8b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 18 Jul 2018 16:32:27 -0700 Subject: [PATCH] Finalize definition link (#54424) Finalize the definition link api - Gives fields more explicit names (target and origin) - Moves api to vscode.d.ts - Makes other definition providers (such as type definition provider and implementation provider) also return definition links Fixes #54101 --- .../src/features/definitions.ts | 16 ++--- src/vs/editor/common/modes.ts | 4 +- src/vs/monaco.d.ts | 4 +- src/vs/vscode.d.ts | 41 ++++++++++++- src/vs/vscode.proposed.d.ts | 43 -------------- .../mainThreadLanguageFeatures.ts | 4 +- src/vs/workbench/api/node/extHost.protocol.ts | 4 +- .../api/node/extHostLanguageFeatures.ts | 59 +++++-------------- .../api/node/extHostTypeConverters.ts | 17 ++++++ 9 files changed, 85 insertions(+), 107 deletions(-) diff --git a/extensions/typescript-language-features/src/features/definitions.ts b/extensions/typescript-language-features/src/features/definitions.ts index 9ff840cdab4..99b9c366247 100644 --- a/extensions/typescript-language-features/src/features/definitions.ts +++ b/extensions/typescript-language-features/src/features/definitions.ts @@ -17,12 +17,7 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase super(client); } - public async provideDefinition() { - // Implemented by provideDefinition2 - return undefined; - } - - public async provideDefinition2( + public async provideDefinition( document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken | boolean @@ -44,10 +39,11 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase const span = response.body.textSpan ? typeConverters.Range.fromTextSpan(response.body.textSpan) : undefined; return locations .map(location => { - const loc = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location); - return { - origin: span, - ...loc, + const target = typeConverters.Location.fromTextSpan(this.client.toResource(location.file), location); + return { + originSelectionRange: span, + targetRange: target.range, + targetUri: target.uri, }; }); } catch { diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index 6b8d3fb2aff..055f17e7114 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -565,7 +565,7 @@ export interface ImplementationProvider { /** * Provide the implementation of the symbol at the given position and document. */ - provideImplementation(model: model.ITextModel, position: Position, token: CancellationToken): Definition | Thenable; + provideImplementation(model: model.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable; } /** @@ -576,7 +576,7 @@ export interface TypeDefinitionProvider { /** * Provide the type definition of the symbol at the given position and document. */ - provideTypeDefinition(model: model.ITextModel, position: Position, token: CancellationToken): Definition | Thenable; + provideTypeDefinition(model: model.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable; } /** diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 0a9e5161b0e..2587e66c61d 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -4933,7 +4933,7 @@ declare namespace monaco.languages { /** * Provide the implementation of the symbol at the given position and document. */ - provideImplementation(model: editor.ITextModel, position: Position, token: CancellationToken): Definition | Thenable; + provideImplementation(model: editor.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable; } /** @@ -4944,7 +4944,7 @@ declare namespace monaco.languages { /** * Provide the type definition of the symbol at the given position and document. */ - provideTypeDefinition(model: editor.ITextModel, position: Position, token: CancellationToken): Definition | Thenable; + provideTypeDefinition(model: editor.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable; } /** diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 27a09386ff7..943698977fb 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -2156,6 +2156,41 @@ declare module 'vscode' { resolveCodeLens?(codeLens: CodeLens, token: CancellationToken): ProviderResult; } + /** + * Information about where a symbol is defined. + * + * Provides additional metadata over normal [location](#Location) definitions, including the range of + * the defining symbol + */ + export interface DefinitionLink { + /** + * Span of the symbol being defined in the source file. + * + * Used as the underlined span for mouse definition hover. Defaults to the word range at + * the definition position. + */ + originSelectionRange?: Range; + + /** + * The resource identifier of the definition. + */ + targetUri: Uri; + + /** + * The full range of the definition. + * + * For a class definition for example, this would be the entire body of the class definition. + */ + targetRange: Range; + + /** + * The span of the symbol definition. + * + * For a class definition, this would be the class name itself in the class definition. + */ + targetSelectionRange?: Range; + } + /** * The definition of a symbol represented as one or many [locations](#Location). * For most programming languages there is only one location at which a symbol is @@ -2179,7 +2214,7 @@ declare module 'vscode' { * @return A definition or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ - provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; + provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; } /** @@ -2197,7 +2232,7 @@ declare module 'vscode' { * @return A definition or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ - provideImplementation(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; + provideImplementation(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; } /** @@ -2215,7 +2250,7 @@ declare module 'vscode' { * @return A definition or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ - provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; + provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; } /** diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index f899c196ba9..c82b7a08c51 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1054,47 +1054,4 @@ declare module 'vscode' { export const onDidRenameFile: Event; } //#endregion - - //#region Matt: Deinition range - - /** - * Information about where a symbol is defined. - * - * Provides additional metadata over normal [location](#Location) definitions, including the range of - * the defining symbol - */ - export interface DefinitionLink { - /** - * Span of the symbol being defined in the source file. - * - * Used as the underlined span for mouse definition hover. Defaults to the word range at - * the definition position. - */ - origin?: Range; - - /** - * The resource identifier of the definition. - */ - uri: Uri; - - /** - * The full range of the definition. - * - * For a class definition for example, this would be the entire body of the class definition. - */ - range: Range; - - /** - * The span of the symbol definition. - * - * For a class definition, this would be the class name itself in the class definition. - */ - selectionRange?: Range; - } - - export interface DefinitionProvider { - provideDefinition2?(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; - } - - //#endregion } diff --git a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts index 7ecf37c7311..baa55c39fa6 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts @@ -162,7 +162,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha $registerImplementationSupport(handle: number, selector: ISerializedDocumentFilter[]): void { this._registrations[handle] = modes.ImplementationProviderRegistry.register(typeConverters.LanguageSelector.from(selector), { provideImplementation: (model, position, token): Thenable => { - return wireCancellationToken(token, this._proxy.$provideImplementation(handle, model.uri, position)).then(MainThreadLanguageFeatures._reviveLocationDto); + return wireCancellationToken(token, this._proxy.$provideImplementation(handle, model.uri, position)).then(MainThreadLanguageFeatures._reviveDefinitionLinkDto); } }); } @@ -170,7 +170,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha $registerTypeDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void { this._registrations[handle] = modes.TypeDefinitionProviderRegistry.register(typeConverters.LanguageSelector.from(selector), { provideTypeDefinition: (model, position, token): Thenable => { - return wireCancellationToken(token, this._proxy.$provideTypeDefinition(handle, model.uri, position)).then(MainThreadLanguageFeatures._reviveLocationDto); + return wireCancellationToken(token, this._proxy.$provideTypeDefinition(handle, model.uri, position)).then(MainThreadLanguageFeatures._reviveDefinitionLinkDto); } }); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index c65fd9cf161..122e6c14fb8 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -812,8 +812,8 @@ export interface ExtHostLanguageFeaturesShape { $provideCodeLenses(handle: number, resource: UriComponents): TPromise; $resolveCodeLens(handle: number, resource: UriComponents, symbol: modes.ICodeLensSymbol): TPromise; $provideDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise; - $provideImplementation(handle: number, resource: UriComponents, position: IPosition): TPromise; - $provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise; + $provideImplementation(handle: number, resource: UriComponents, position: IPosition): TPromise; + $provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise; $provideHover(handle: number, resource: UriComponents, position: IPosition): TPromise; $provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition): TPromise; $provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext): TPromise; diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index f562cb6d6fe..8dc9a268ce5 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -143,6 +143,15 @@ class CodeLensAdapter { } } +function convertToDefinitionLinks(value: vscode.Definition): modes.DefinitionLink[] { + if (Array.isArray(value)) { + return (value as (vscode.DefinitionLink | vscode.Location)[]).map(typeConvert.DefinitionLink.from); + } else if (value) { + return [typeConvert.DefinitionLink.from(value)]; + } + return undefined; +} + class DefinitionAdapter { constructor( @@ -153,29 +162,7 @@ class DefinitionAdapter { provideDefinition(resource: URI, position: IPosition): TPromise { let doc = this._documents.getDocumentData(resource).document; let pos = typeConvert.Position.to(position); - - return asWinJsPromise(token => this._provider.provideDefinition2 ? this._provider.provideDefinition2(doc, pos, token) : this._provider.provideDefinition(doc, pos, token)).then((value): modes.DefinitionLink[] => { - if (Array.isArray(value)) { - return (value as (vscode.DefinitionLink | vscode.Location)[]).map(x => DefinitionAdapter.convertDefinitionLink(x)); - } else if (value) { - return [DefinitionAdapter.convertDefinitionLink(value)]; - } - return undefined; - }); - } - - private static convertDefinitionLink(value: vscode.Location | vscode.DefinitionLink): modes.DefinitionLink { - const definitionLink = value; - return { - origin: definitionLink.origin - ? typeConvert.Range.from(definitionLink.origin) - : undefined, - uri: value.uri, - range: typeConvert.Range.from(value.range), - selectionRange: definitionLink.selectionRange - ? typeConvert.Range.from(definitionLink.selectionRange) - : undefined, - }; + return asWinJsPromise(token => this._provider.provideDefinition(doc, pos, token)).then(convertToDefinitionLinks); } } @@ -186,17 +173,10 @@ class ImplementationAdapter { private readonly _provider: vscode.ImplementationProvider ) { } - provideImplementation(resource: URI, position: IPosition): TPromise { + provideImplementation(resource: URI, position: IPosition): TPromise { let doc = this._documents.getDocumentData(resource).document; let pos = typeConvert.Position.to(position); - return asWinJsPromise(token => this._provider.provideImplementation(doc, pos, token)).then(value => { - if (Array.isArray(value)) { - return value.map(typeConvert.location.from); - } else if (value) { - return typeConvert.location.from(value); - } - return undefined; - }); + return asWinJsPromise(token => this._provider.provideImplementation(doc, pos, token)).then(convertToDefinitionLinks); } } @@ -207,17 +187,10 @@ class TypeDefinitionAdapter { private readonly _provider: vscode.TypeDefinitionProvider ) { } - provideTypeDefinition(resource: URI, position: IPosition): TPromise { + provideTypeDefinition(resource: URI, position: IPosition): TPromise { const doc = this._documents.getDocumentData(resource).document; const pos = typeConvert.Position.to(position); - return asWinJsPromise(token => this._provider.provideTypeDefinition(doc, pos, token)).then(value => { - if (Array.isArray(value)) { - return value.map(typeConvert.location.from); - } else if (value) { - return typeConvert.location.from(value); - } - return undefined; - }); + return asWinJsPromise(token => this._provider.provideTypeDefinition(doc, pos, token)).then(convertToDefinitionLinks); } } @@ -999,7 +972,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideImplementation(handle: number, resource: UriComponents, position: IPosition): TPromise { + $provideImplementation(handle: number, resource: UriComponents, position: IPosition): TPromise { return this._withAdapter(handle, ImplementationAdapter, adapter => adapter.provideImplementation(URI.revive(resource), position)); } @@ -1009,7 +982,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise { + $provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise { return this._withAdapter(handle, TypeDefinitionAdapter, adapter => adapter.provideTypeDefinition(URI.revive(resource), position)); } diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index bf942604411..ae449946df0 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -413,6 +413,23 @@ export const location = { } }; +export namespace DefinitionLink { + export function from(value: vscode.Location | vscode.DefinitionLink): modes.DefinitionLink { + const definitionLink = value; + const location = value; + return { + origin: definitionLink.originSelectionRange + ? Range.from(definitionLink.originSelectionRange) + : undefined, + uri: definitionLink.targetUri ? definitionLink.targetUri : location.uri, + range: Range.from(definitionLink.targetRange ? definitionLink.targetRange : location.range), + selectionRange: definitionLink.targetSelectionRange + ? Range.from(definitionLink.targetSelectionRange) + : undefined, + }; + } +} + export namespace Hover { export function from(hover: vscode.Hover): modes.Hover { return { -- GitLab