mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 16:58:55 -05:00
Add Type Definition Provider API (#19699)
* Add Type Definition Provider API Adds a new API to support type definition providers and adds an initial type definition provider for TypeScript * Fix comment * Addressing comments * Fixer menu option ordering * Added simple test
This commit is contained in:
@@ -14,7 +14,12 @@ export default class TypeScriptDefinitionProviderBase {
|
||||
constructor(
|
||||
private client: ITypescriptServiceClient) { }
|
||||
|
||||
protected getSymbolLocations(definitionType: 'definition' | 'implementation', document: TextDocument, position: Position, token: CancellationToken | boolean): Promise<Location[] | null> {
|
||||
protected getSymbolLocations(
|
||||
definitionType: 'definition' | 'implementation' | 'typeDefinition',
|
||||
document: TextDocument,
|
||||
position: Position,
|
||||
token: CancellationToken | boolean
|
||||
): Promise<Location[] | null> {
|
||||
const filepath = this.client.normalizePath(document.uri);
|
||||
if (!filepath) {
|
||||
return Promise.resolve(null);
|
||||
|
||||
21
extensions/typescript/src/features/typeDefinitionProvider.ts
Normal file
21
extensions/typescript/src/features/typeDefinitionProvider.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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('typeDefinition', document, position, token);
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import { ITypescriptServiceClientHost } from './typescriptService';
|
||||
import HoverProvider from './features/hoverProvider';
|
||||
import DefinitionProvider from './features/definitionProvider';
|
||||
import ImplementationProvider from './features/ImplementationProvider';
|
||||
import TypeDefintionProvider from './features/typeDefinitionProvider';
|
||||
import DocumentHighlightProvider from './features/documentHighlightProvider';
|
||||
import ReferenceProvider from './features/referenceProvider';
|
||||
import DocumentSymbolProvider from './features/documentSymbolProvider';
|
||||
@@ -155,6 +156,7 @@ class LanguageProvider {
|
||||
let hoverProvider = new HoverProvider(client);
|
||||
let definitionProvider = new DefinitionProvider(client);
|
||||
let implementationProvider = new ImplementationProvider(client);
|
||||
const typeDefinitionProvider = new TypeDefintionProvider(client);
|
||||
let documentHighlightProvider = new DocumentHighlightProvider(client);
|
||||
let referenceProvider = new ReferenceProvider(client);
|
||||
let documentSymbolProvider = new DocumentSymbolProvider(client);
|
||||
@@ -181,6 +183,9 @@ class LanguageProvider {
|
||||
// TODO: TS 2.1.5 returns incorrect results for implementation locations.
|
||||
languages.registerImplementationProvider(selector, implementationProvider);
|
||||
}
|
||||
if (client.apiVersion.has213Features()) {
|
||||
languages.registerTypeDefinitionProvider(selector, typeDefinitionProvider);
|
||||
}
|
||||
languages.registerDocumentHighlightProvider(selector, documentHighlightProvider);
|
||||
languages.registerReferenceProvider(selector, referenceProvider);
|
||||
languages.registerDocumentSymbolProvider(selector, documentSymbolProvider);
|
||||
|
||||
@@ -88,6 +88,7 @@ export interface ITypescriptServiceClient {
|
||||
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: 'typeDefinition', args: Proto.FileLocationRequestArgs, token?: CancellationToken): Promise<Proto.TypeDefinitionResponse>;
|
||||
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>;
|
||||
|
||||
@@ -275,12 +275,19 @@ export function registerDefinitionProvider(languageId: string, provider: modes.D
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a type implementation provider (used by e.g. go to implementation).
|
||||
* Register a implementation provider (used by e.g. go to implementation).
|
||||
*/
|
||||
export function registerImplementationProvider(languageId: string, provider: modes.ImplementationProvider): IDisposable {
|
||||
return modes.ImplementationProviderRegistry.register(languageId, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a type definition provider (used by e.g. go to type definition).
|
||||
*/
|
||||
export function registerTypeDefinitionProvider(languageId: string, provider: modes.TypeDefinitionProvider): IDisposable {
|
||||
return modes.TypeDefinitionProviderRegistry.register(languageId, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a code lens provider (used by e.g. inline code lenses).
|
||||
*/
|
||||
@@ -682,6 +689,7 @@ export function createMonacoLanguagesAPI(): typeof monaco.languages {
|
||||
registerDocumentHighlightProvider: registerDocumentHighlightProvider,
|
||||
registerDefinitionProvider: registerDefinitionProvider,
|
||||
registerImplementationProvider: registerImplementationProvider,
|
||||
registerTypeDefinitionProvider: registerTypeDefinitionProvider,
|
||||
registerCodeLensProvider: registerCodeLensProvider,
|
||||
registerCodeActionProvider: registerCodeActionProvider,
|
||||
registerDocumentFormattingEditProvider: registerDocumentFormattingEditProvider,
|
||||
|
||||
@@ -3146,6 +3146,10 @@ export namespace ModeContextKeys {
|
||||
* @internal
|
||||
*/
|
||||
export const hasImplementationProvider = new RawContextKey<boolean>('editorHasImplementationProvider', undefined);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const hasTypeDefinitionProvider = new RawContextKey<boolean>('editorHasTypeDefinitionProvider', undefined);
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
||||
@@ -429,7 +429,7 @@ export interface DefinitionProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* The type definition provider interface defines the contract between extensions and
|
||||
* The implementation provider interface defines the contract between extensions and
|
||||
* the go to implementation feature.
|
||||
*/
|
||||
export interface ImplementationProvider {
|
||||
@@ -439,6 +439,17 @@ export interface ImplementationProvider {
|
||||
provideImplementation(model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type definition provider interface defines the contract between extensions and
|
||||
* the go to type definition feature.
|
||||
*/
|
||||
export interface TypeDefinitionProvider {
|
||||
/**
|
||||
* Provide the type definition of the symbol at the given position and document.
|
||||
*/
|
||||
provideTypeDefinition(model: editorCommon.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A symbol kind.
|
||||
*/
|
||||
@@ -751,6 +762,11 @@ export const DefinitionProviderRegistry = new LanguageFeatureRegistry<Definition
|
||||
*/
|
||||
export const ImplementationProviderRegistry = new LanguageFeatureRegistry<ImplementationProvider>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const TypeDefinitionProviderRegistry = new LanguageFeatureRegistry<TypeDefinitionProvider>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,7 @@ export class EditorModeContext {
|
||||
private _hasCodeLensProvider: IContextKey<boolean>;
|
||||
private _hasDefinitionProvider: IContextKey<boolean>;
|
||||
private _hasImplementationProvider: IContextKey<boolean>;
|
||||
private _hasTypeDefinitionProvider: IContextKey<boolean>;
|
||||
private _hasHoverProvider: IContextKey<boolean>;
|
||||
private _hasDocumentHighlightProvider: IContextKey<boolean>;
|
||||
private _hasDocumentSymbolProvider: IContextKey<boolean>;
|
||||
@@ -43,6 +44,7 @@ export class EditorModeContext {
|
||||
this._hasCodeLensProvider = ModeContextKeys.hasCodeLensProvider.bindTo(contextKeyService);
|
||||
this._hasDefinitionProvider = ModeContextKeys.hasDefinitionProvider.bindTo(contextKeyService);
|
||||
this._hasImplementationProvider = ModeContextKeys.hasImplementationProvider.bindTo(contextKeyService);
|
||||
this._hasTypeDefinitionProvider = ModeContextKeys.hasTypeDefinitionProvider.bindTo(contextKeyService);
|
||||
this._hasHoverProvider = ModeContextKeys.hasHoverProvider.bindTo(contextKeyService);
|
||||
this._hasDocumentHighlightProvider = ModeContextKeys.hasDocumentHighlightProvider.bindTo(contextKeyService);
|
||||
this._hasDocumentSymbolProvider = ModeContextKeys.hasDocumentSymbolProvider.bindTo(contextKeyService);
|
||||
@@ -63,6 +65,7 @@ export class EditorModeContext {
|
||||
modes.CodeLensProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||
modes.DefinitionProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||
modes.ImplementationProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||
modes.TypeDefinitionProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||
modes.HoverProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||
modes.DocumentHighlightProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||
modes.DocumentSymbolProviderRegistry.onDidChange(this._update, this, this._disposables);
|
||||
@@ -86,6 +89,7 @@ export class EditorModeContext {
|
||||
this._hasCodeLensProvider.reset();
|
||||
this._hasDefinitionProvider.reset();
|
||||
this._hasImplementationProvider.reset();
|
||||
this._hasTypeDefinitionProvider.reset();
|
||||
this._hasHoverProvider.reset();
|
||||
this._hasDocumentHighlightProvider.reset();
|
||||
this._hasDocumentSymbolProvider.reset();
|
||||
@@ -109,6 +113,7 @@ export class EditorModeContext {
|
||||
this._hasCodeLensProvider.set(modes.CodeLensProviderRegistry.has(model));
|
||||
this._hasDefinitionProvider.set(modes.DefinitionProviderRegistry.has(model));
|
||||
this._hasImplementationProvider.set(modes.ImplementationProviderRegistry.has(model));
|
||||
this._hasTypeDefinitionProvider.set(modes.TypeDefinitionProviderRegistry.has(model));
|
||||
this._hasHoverProvider.set(modes.HoverProviderRegistry.has(model));
|
||||
this._hasDocumentHighlightProvider.set(modes.DocumentHighlightProviderRegistry.has(model));
|
||||
this._hasDocumentSymbolProvider.set(modes.DocumentSymbolProviderRegistry.has(model));
|
||||
|
||||
@@ -26,7 +26,7 @@ import { editorAction, IActionOptions, ServicesAccessor, EditorAction } from 'vs
|
||||
import { Location, DefinitionProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { ICodeEditor, IEditorMouseEvent, IMouseTarget } from 'vs/editor/browser/editorBrowser';
|
||||
import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
|
||||
import { getDeclarationsAtPosition, getImplementationAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||
import { ReferencesController } from 'vs/editor/contrib/referenceSearch/browser/referencesController';
|
||||
import { ReferencesModel } from 'vs/editor/contrib/referenceSearch/browser/referencesModel';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
@@ -106,7 +106,7 @@ export class DefinitionAction extends EditorAction {
|
||||
}
|
||||
|
||||
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||
return getDeclarationsAtPosition(model, position);
|
||||
return getDefinitionsAtPosition(model, position);
|
||||
}
|
||||
|
||||
private _onResult(editorService: IEditorService, editor: editorCommon.ICommonCodeEditor, model: ReferencesModel) {
|
||||
@@ -255,7 +255,7 @@ export class GoToImplementationAction extends DefinitionAction {
|
||||
}
|
||||
|
||||
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||
return getImplementationAtPosition(model, position);
|
||||
return getImplementationsAtPosition(model, position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,19 +275,70 @@ export class PeekImplementationAction extends DefinitionAction {
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.TextFocus,
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.F12
|
||||
},
|
||||
menuOpts: {
|
||||
group: 'navigation',
|
||||
order: 1.3
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||
return getImplementationAtPosition(model, position);
|
||||
return getImplementationsAtPosition(model, position);
|
||||
}
|
||||
}
|
||||
|
||||
@editorAction
|
||||
export class GoToTypeDefintionAction extends DefinitionAction {
|
||||
|
||||
public static ID = 'editor.action.goToTypeDefinition';
|
||||
|
||||
constructor() {
|
||||
super(new DefinitionActionConfig(), {
|
||||
id: GoToTypeDefintionAction.ID,
|
||||
label: nls.localize('actions.goToTypeDefinition.label', "Go to Type Definition"),
|
||||
alias: 'Go to Type Definition',
|
||||
precondition: ContextKeyExpr.and(
|
||||
ModeContextKeys.hasTypeDefinitionProvider,
|
||||
ModeContextKeys.isInEmbeddedEditor.toNegated()),
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.TextFocus,
|
||||
primary: 0
|
||||
},
|
||||
menuOpts: {
|
||||
group: 'navigation',
|
||||
order: 1.4
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||
return getTypeDefinitionsAtPosition(model, position);
|
||||
}
|
||||
}
|
||||
|
||||
@editorAction
|
||||
export class PeekTypeDefinitionAction extends DefinitionAction {
|
||||
|
||||
public static ID = 'editor.action.peekTypeDefinition';
|
||||
|
||||
constructor() {
|
||||
super(new DefinitionActionConfig(false, true, false), {
|
||||
id: PeekTypeDefinitionAction.ID,
|
||||
label: nls.localize('actions.peekTypeDefinition.label', "Peek Type Definition"),
|
||||
alias: 'Peek Type Definition',
|
||||
precondition: ContextKeyExpr.and(
|
||||
ModeContextKeys.hasTypeDefinitionProvider,
|
||||
ModeContextKeys.isInEmbeddedEditor.toNegated()),
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.TextFocus,
|
||||
primary: 0
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected getDeclarationsAtPosition(model: editorCommon.IModel, position: corePosition.Position): TPromise<Location[]> {
|
||||
return getTypeDefinitionsAtPosition(model, position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --- Editor Contribution to goto definition using the mouse and a modifier key
|
||||
|
||||
@editorContribution
|
||||
@@ -541,7 +592,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
return getDeclarationsAtPosition(this.editor.getModel(), target.position);
|
||||
return getDefinitionsAtPosition(this.editor.getModel(), target.position);
|
||||
}
|
||||
|
||||
private gotoDefinition(target: IMouseTarget, sideBySide: boolean): TPromise<any> {
|
||||
|
||||
@@ -9,7 +9,9 @@ import { onUnexpectedExternalError } from 'vs/base/common/errors';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IReadOnlyModel } from 'vs/editor/common/editorCommon';
|
||||
import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
|
||||
import { DefinitionProviderRegistry, ImplementationProviderRegistry, Location } from 'vs/editor/common/modes';
|
||||
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
|
||||
import { DefinitionProviderRegistry, ImplementationProviderRegistry, TypeDefinitionProviderRegistry, Location } from 'vs/editor/common/modes';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
|
||||
@@ -27,14 +29,18 @@ function outputResults(promises: TPromise<Location[]>[]) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getDeclarationsAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
||||
|
||||
const provider = DefinitionProviderRegistry.ordered(model);
|
||||
function getDefinitions<T>(
|
||||
model: IReadOnlyModel,
|
||||
position: Position,
|
||||
registry: LanguageFeatureRegistry<T>,
|
||||
provide: (provider: T, model: IReadOnlyModel, position: Position, token: CancellationToken) => Location | Location[] | Thenable<Location | Location[]>
|
||||
): TPromise<Location[]> {
|
||||
const provider = registry.ordered(model);
|
||||
|
||||
// get results
|
||||
const promises = provider.map((provider, idx) => {
|
||||
return asWinJsPromise((token) => {
|
||||
return provider.provideDefinition(model, position, token);
|
||||
return provide(provider, model, position, token);
|
||||
}).then(result => {
|
||||
return result;
|
||||
}, err => {
|
||||
@@ -44,22 +50,25 @@ export function getDeclarationsAtPosition(model: IReadOnlyModel, position: Posit
|
||||
return outputResults(promises);
|
||||
}
|
||||
|
||||
export function getImplementationAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
||||
|
||||
const provider = ImplementationProviderRegistry.ordered(model);
|
||||
|
||||
// get results
|
||||
const promises = provider.map((provider, idx) => {
|
||||
return asWinJsPromise((token) => {
|
||||
return provider.provideImplementation(model, position, token);
|
||||
}).then(result => {
|
||||
return result;
|
||||
}, err => {
|
||||
onUnexpectedExternalError(err);
|
||||
});
|
||||
export function getDefinitionsAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
||||
return getDefinitions(model, position, DefinitionProviderRegistry, (provider, model, position, token) => {
|
||||
return provider.provideDefinition(model, position, token);
|
||||
});
|
||||
return outputResults(promises);
|
||||
}
|
||||
|
||||
CommonEditorRegistry.registerDefaultLanguageCommand('_executeDefinitionProvider', getDeclarationsAtPosition);
|
||||
CommonEditorRegistry.registerDefaultLanguageCommand('_executeImplementationProvider', getImplementationAtPosition);
|
||||
export function getImplementationsAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
||||
return getDefinitions(model, position, ImplementationProviderRegistry, (provider, model, position, token) => {
|
||||
return provider.provideImplementation(model, position, token);
|
||||
});
|
||||
}
|
||||
|
||||
export function getTypeDefinitionsAtPosition(model: IReadOnlyModel, position: Position): TPromise<Location[]> {
|
||||
return getDefinitions(model, position, TypeDefinitionProviderRegistry, (provider, model, position, token) => {
|
||||
return provider.provideTypeDefinition(model, position, token);
|
||||
});
|
||||
}
|
||||
|
||||
CommonEditorRegistry.registerDefaultLanguageCommand('_executeDefinitionProvider', getDefinitionsAtPosition);
|
||||
CommonEditorRegistry.registerDefaultLanguageCommand('_executeImplementationProvider', getImplementationsAtPosition);
|
||||
CommonEditorRegistry.registerDefaultLanguageCommand('_executeTypeDefinitionProvider', getTypeDefinitionsAtPosition);
|
||||
@@ -73,7 +73,7 @@ export class ReferenceAction extends EditorAction {
|
||||
},
|
||||
menuOpts: {
|
||||
group: 'navigation',
|
||||
order: 1.3
|
||||
order: 1.5
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
20
src/vs/monaco.d.ts
vendored
20
src/vs/monaco.d.ts
vendored
@@ -3953,10 +3953,15 @@ declare module monaco.languages {
|
||||
export function registerDefinitionProvider(languageId: string, provider: DefinitionProvider): IDisposable;
|
||||
|
||||
/**
|
||||
* Register a type implementation provider (used by e.g. go to implementation).
|
||||
* Register a implementation provider (used by e.g. go to implementation).
|
||||
*/
|
||||
export function registerImplementationProvider(languageId: string, provider: ImplementationProvider): IDisposable;
|
||||
|
||||
/**
|
||||
* Register a type definition provider (used by e.g. go to type definition).
|
||||
*/
|
||||
export function registerTypeDefinitionProvider(languageId: string, provider: TypeDefinitionProvider): IDisposable;
|
||||
|
||||
/**
|
||||
* Register a code lens provider (used by e.g. inline code lenses).
|
||||
*/
|
||||
@@ -4570,7 +4575,7 @@ declare module monaco.languages {
|
||||
}
|
||||
|
||||
/**
|
||||
* The type definition provider interface defines the contract between extensions and
|
||||
* The implementation provider interface defines the contract between extensions and
|
||||
* the go to implementation feature.
|
||||
*/
|
||||
export interface ImplementationProvider {
|
||||
@@ -4580,6 +4585,17 @@ declare module monaco.languages {
|
||||
provideImplementation(model: editor.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type definition provider interface defines the contract between extensions and
|
||||
* the go to type definition feature.
|
||||
*/
|
||||
export interface TypeDefinitionProvider {
|
||||
/**
|
||||
* Provide the type definition of the symbol at the given position and document.
|
||||
*/
|
||||
provideTypeDefinition(model: editor.IReadOnlyModel, position: Position, token: CancellationToken): Definition | Thenable<Definition>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A symbol kind.
|
||||
*/
|
||||
|
||||
33
src/vs/vscode.d.ts
vendored
33
src/vs/vscode.d.ts
vendored
@@ -1650,7 +1650,7 @@ declare module 'vscode' {
|
||||
}
|
||||
|
||||
/**
|
||||
* The type implemenetation provider interface defines the contract between extensions and
|
||||
* The implemenetation provider interface defines the contract between extensions and
|
||||
* the go to implementation feature.
|
||||
*/
|
||||
export interface ImplementationProvider {
|
||||
@@ -1667,6 +1667,24 @@ declare module 'vscode' {
|
||||
provideImplementation(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Definition>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type definition provider defines the contract between extensions and
|
||||
* the go to type definition feature.
|
||||
*/
|
||||
export interface TypeDefinitionProvider {
|
||||
|
||||
/**
|
||||
* Provide the type definition of the symbol at the given position and document.
|
||||
*
|
||||
* @param document The document in which the command was invoked.
|
||||
* @param position The position at which the command was invoked.
|
||||
* @param token A cancellation token.
|
||||
* @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>;
|
||||
}
|
||||
|
||||
/**
|
||||
* MarkedString can be used to render human readable text. It is either a markdown string
|
||||
* or a code-block that provides a language and a code snippet. Note that
|
||||
@@ -4173,6 +4191,19 @@ declare module 'vscode' {
|
||||
*/
|
||||
export function registerImplementationProvider(selector: DocumentSelector, provider: ImplementationProvider): Disposable;
|
||||
|
||||
/**
|
||||
* Register a type definition provider.
|
||||
*
|
||||
* Multiple providers can be registered for a language. In that case providers are asked in
|
||||
* parallel and the results are merged. A failing provider (rejected promise or exception) will
|
||||
* not cause a failure of the whole operation.
|
||||
*
|
||||
* @param selector A selector that defines the documents this provider is applicable to.
|
||||
* @param provider A type definition provider.
|
||||
* @return A [disposable](#Disposable) that unregisters this provider when being disposed.
|
||||
*/
|
||||
export function registerTypeDefinitionProvider(selector: DocumentSelector, provider: TypeDefinitionProvider): Disposable;
|
||||
|
||||
/**
|
||||
* Register a hover provider.
|
||||
*
|
||||
|
||||
@@ -215,6 +215,9 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
|
||||
registerImplementationProvider(selector: vscode.DocumentSelector, provider: vscode.ImplementationProvider): vscode.Disposable {
|
||||
return languageFeatures.registerImplementationProvider(selector, provider);
|
||||
},
|
||||
registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
|
||||
return languageFeatures.registerTypeDefinitionProvider(selector, provider);
|
||||
},
|
||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
||||
return languageFeatures.registerHoverProvider(selector, provider);
|
||||
},
|
||||
|
||||
@@ -156,6 +156,7 @@ export abstract class MainThreadLanguageFeaturesShape {
|
||||
$emitCodeLensEvent(eventHandle: number, event?: any): TPromise<any> { throw ni(); }
|
||||
$registerDeclaractionSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerImplementationSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerTypeDefinitionSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerDocumentHighlightProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
$registerReferenceSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> { throw ni(); }
|
||||
@@ -361,6 +362,7 @@ export abstract class ExtHostLanguageFeaturesShape {
|
||||
$resolveCodeLens(handle: number, resource: URI, symbol: modes.ICodeLensSymbol): TPromise<modes.ICodeLensSymbol> { throw ni(); }
|
||||
$provideDefinition(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
||||
$provideImplementation(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
||||
$provideTypeDefinition(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Definition> { throw ni(); }
|
||||
$provideHover(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.Hover> { throw ni(); }
|
||||
$provideDocumentHighlights(handle: number, resource: URI, position: editorCommon.IPosition): TPromise<modes.DocumentHighlight[]> { throw ni(); }
|
||||
$provideReferences(handle: number, resource: URI, position: editorCommon.IPosition, context: modes.ReferenceContext): TPromise<modes.Location[]> { throw ni(); }
|
||||
|
||||
@@ -101,7 +101,6 @@ class CodeLensAdapter {
|
||||
}
|
||||
|
||||
class DefinitionAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.DefinitionProvider;
|
||||
|
||||
@@ -125,7 +124,6 @@ class DefinitionAdapter {
|
||||
}
|
||||
|
||||
class ImplementationAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.ImplementationProvider;
|
||||
|
||||
@@ -148,6 +146,30 @@ class ImplementationAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
class TypeDefinitionAdapter {
|
||||
private _documents: ExtHostDocuments;
|
||||
private _provider: vscode.TypeDefinitionProvider;
|
||||
|
||||
constructor(documents: ExtHostDocuments, provider: vscode.TypeDefinitionProvider) {
|
||||
this._documents = documents;
|
||||
this._provider = provider;
|
||||
}
|
||||
|
||||
provideTypeDefinition(resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||
const doc = this._documents.getDocumentData(resource).document;
|
||||
const pos = TypeConverters.toPosition(position);
|
||||
return asWinJsPromise(token => this._provider.provideTypeDefinition(doc, pos, token)).then(value => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(TypeConverters.location.from);
|
||||
} else if (value) {
|
||||
return TypeConverters.location.from(value);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class HoverAdapter {
|
||||
|
||||
private _documents: ExtHostDocuments;
|
||||
@@ -650,7 +672,7 @@ class LinkProviderAdapter {
|
||||
type Adapter = OutlineAdapter | CodeLensAdapter | DefinitionAdapter | HoverAdapter
|
||||
| DocumentHighlightAdapter | ReferenceAdapter | QuickFixAdapter | DocumentFormattingAdapter
|
||||
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
|
||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter;
|
||||
| SuggestAdapter | SignatureHelpAdapter | LinkProviderAdapter | ImplementationAdapter | TypeDefinitionAdapter;
|
||||
|
||||
export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
|
||||
@@ -760,6 +782,17 @@ export class ExtHostLanguageFeatures extends ExtHostLanguageFeaturesShape {
|
||||
return this._withAdapter(handle, ImplementationAdapter, adapter => adapter.provideImplementation(resource, position));
|
||||
}
|
||||
|
||||
registerTypeDefinitionProvider(selector: vscode.DocumentSelector, provider: vscode.TypeDefinitionProvider): vscode.Disposable {
|
||||
const handle = this._nextHandle();
|
||||
this._adapter.set(handle, new TypeDefinitionAdapter(this._documents, provider));
|
||||
this._proxy.$registerTypeDefinitionSupport(handle, selector);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
$provideTypeDefinition(handle: number, resource: URI, position: IPosition): TPromise<modes.Definition> {
|
||||
return this._withAdapter(handle, TypeDefinitionAdapter, adapter => adapter.provideTypeDefinition(resource, position));
|
||||
}
|
||||
|
||||
// --- extra info
|
||||
|
||||
registerHoverProvider(selector: vscode.DocumentSelector, provider: vscode.HoverProvider): vscode.Disposable {
|
||||
|
||||
@@ -111,6 +111,15 @@ export class MainThreadLanguageFeatures extends MainThreadLanguageFeaturesShape
|
||||
return undefined;
|
||||
}
|
||||
|
||||
$registerTypeDefinitionSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||
this._registrations[handle] = modes.TypeDefinitionProviderRegistry.register(selector, <modes.TypeDefinitionProvider>{
|
||||
provideTypeDefinition: (model, position, token): Thenable<modes.Definition> => {
|
||||
return wireCancellationToken(token, this._proxy.$provideTypeDefinition(handle, model.uri, position));
|
||||
}
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// --- extra info
|
||||
|
||||
$registerHoverProvider(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
|
||||
|
||||
@@ -27,7 +27,7 @@ import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
|
||||
import { getDocumentSymbols } from 'vs/editor/contrib/quickOpen/common/quickOpen';
|
||||
import { DocumentSymbolProviderRegistry, DocumentHighlightKind } from 'vs/editor/common/modes';
|
||||
import { getCodeLensData } from 'vs/editor/contrib/codelens/common/codelens';
|
||||
import { getDeclarationsAtPosition, getImplementationAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition } from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
|
||||
import { getHover } from 'vs/editor/contrib/hover/common/hover';
|
||||
import { getOccurrencesAtPosition } from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
|
||||
import { provideReferences } from 'vs/editor/contrib/referenceSearch/common/referenceSearch';
|
||||
@@ -275,7 +275,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return threadService.sync().then(() => {
|
||||
|
||||
return getDeclarationsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||
@@ -299,7 +299,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return threadService.sync().then(() => {
|
||||
|
||||
return getDeclarationsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
assert.equal(value.length, 2);
|
||||
});
|
||||
});
|
||||
@@ -321,7 +321,7 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return threadService.sync().then(() => {
|
||||
|
||||
return getDeclarationsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
assert.equal(value.length, 2);
|
||||
// let [first, second] = value;
|
||||
|
||||
@@ -346,13 +346,13 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
|
||||
return threadService.sync().then(() => {
|
||||
|
||||
return getDeclarationsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- type implementation
|
||||
// --- implementation
|
||||
|
||||
test('Implementation, data conversion', function () {
|
||||
|
||||
@@ -363,7 +363,27 @@ suite('ExtHostLanguageFeatures', function () {
|
||||
}));
|
||||
|
||||
return threadService.sync().then(() => {
|
||||
return getImplementationAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
return getImplementationsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||
assert.equal(entry.uri.toString(), model.uri.toString());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// --- type definition
|
||||
|
||||
test('Type Definition, data conversion', function () {
|
||||
|
||||
disposables.push(extHost.registerTypeDefinitionProvider(defaultSelector, <vscode.TypeDefinitionProvider>{
|
||||
provideTypeDefinition(): any {
|
||||
return [new types.Location(model.uri, new types.Range(1, 2, 3, 4))];
|
||||
}
|
||||
}));
|
||||
|
||||
return threadService.sync().then(() => {
|
||||
return getTypeDefinitionsAtPosition(model, new EditorPosition(1, 1)).then(value => {
|
||||
assert.equal(value.length, 1);
|
||||
let [entry] = value;
|
||||
assert.deepEqual(entry.range, { startLineNumber: 2, startColumn: 3, endLineNumber: 4, endColumn: 5 });
|
||||
|
||||
Reference in New Issue
Block a user