未验证 提交 44cd521c 编写于 作者: M Matt Bierner 提交者: GitHub

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
上级 80a47248
......@@ -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 <vscode.DefinitionLink>{
originSelectionRange: span,
targetRange: target.range,
targetUri: target.uri,
};
});
} catch {
......
......@@ -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<Definition>;
provideImplementation(model: model.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable<DefinitionLink>;
}
/**
......@@ -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<Definition>;
provideTypeDefinition(model: model.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable<DefinitionLink>;
}
/**
......
......@@ -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<Definition>;
provideImplementation(model: editor.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable<DefinitionLink>;
}
/**
......@@ -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<Definition>;
provideTypeDefinition(model: editor.ITextModel, position: Position, token: CancellationToken): DefinitionLink | Thenable<DefinitionLink>;
}
/**
......
......@@ -2156,6 +2156,41 @@ declare module 'vscode' {
resolveCodeLens?(codeLens: CodeLens, token: CancellationToken): ProviderResult<CodeLens>;
}
/**
* 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<Definition>;
provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition | DefinitionLink[]>;
}
/**
......@@ -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<Definition>;
provideImplementation(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition | DefinitionLink[]>;
}
/**
......@@ -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<Definition>;
provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition | DefinitionLink[]>;
}
/**
......
......@@ -1054,47 +1054,4 @@ declare module 'vscode' {
export const onDidRenameFile: Event<FileRenameEvent>;
}
//#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<Definition | DefinitionLink[]>;
}
//#endregion
}
......@@ -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), <modes.ImplementationProvider>{
provideImplementation: (model, position, token): Thenable<modes.Definition> => {
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), <modes.TypeDefinitionProvider>{
provideTypeDefinition: (model, position, token): Thenable<modes.Definition> => {
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);
}
});
}
......
......@@ -812,8 +812,8 @@ export interface ExtHostLanguageFeaturesShape {
$provideCodeLenses(handle: number, resource: UriComponents): TPromise<modes.ICodeLensSymbol[]>;
$resolveCodeLens(handle: number, resource: UriComponents, symbol: modes.ICodeLensSymbol): TPromise<modes.ICodeLensSymbol>;
$provideDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise<DefinitionLinkDto[]>;
$provideImplementation(handle: number, resource: UriComponents, position: IPosition): TPromise<LocationDto | LocationDto[]>;
$provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise<LocationDto | LocationDto[]>;
$provideImplementation(handle: number, resource: UriComponents, position: IPosition): TPromise<DefinitionLinkDto[]>;
$provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise<DefinitionLinkDto[]>;
$provideHover(handle: number, resource: UriComponents, position: IPosition): TPromise<modes.Hover>;
$provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition): TPromise<modes.DocumentHighlight[]>;
$provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext): TPromise<LocationDto[]>;
......
......@@ -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<modes.DefinitionLink[]> {
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 = <vscode.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<modes.Definition> {
provideImplementation(resource: URI, position: IPosition): TPromise<modes.DefinitionLink[]> {
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<modes.Definition> {
provideTypeDefinition(resource: URI, position: IPosition): TPromise<modes.DefinitionLink[]> {
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<modes.Definition> {
$provideImplementation(handle: number, resource: UriComponents, position: IPosition): TPromise<modes.DefinitionLink[]> {
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<modes.Definition> {
$provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition): TPromise<modes.DefinitionLink[]> {
return this._withAdapter(handle, TypeDefinitionAdapter, adapter => adapter.provideTypeDefinition(URI.revive(resource), position));
}
......
......@@ -413,6 +413,23 @@ export const location = {
}
};
export namespace DefinitionLink {
export function from(value: vscode.Location | vscode.DefinitionLink): modes.DefinitionLink {
const definitionLink = <vscode.DefinitionLink>value;
const location = <vscode.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 <modes.Hover>{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册