From 893a78374d2aab18df2a9c12a3ee3ecc411d0e63 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 27 Nov 2015 16:08:52 +0100 Subject: [PATCH] commands: executeDocumentSymbolProvider --- .../contrib/quickOpen/common/quickOpen.ts | 25 +++- .../common/extHostLanguageFeatureCommands.ts | 16 ++- .../api/common/extHostLanguageFeatures.ts | 12 +- .../api/common/pluginHostTypeConverters.ts | 134 +++++++++++++----- .../extHostLanguageFeatureCommands.test.ts | 27 +++- 5 files changed, 160 insertions(+), 54 deletions(-) diff --git a/src/vs/editor/contrib/quickOpen/common/quickOpen.ts b/src/vs/editor/contrib/quickOpen/common/quickOpen.ts index 4b135a963da..b232934917f 100644 --- a/src/vs/editor/contrib/quickOpen/common/quickOpen.ts +++ b/src/vs/editor/contrib/quickOpen/common/quickOpen.ts @@ -5,12 +5,15 @@ 'use strict'; -import {onUnexpectedError} from 'vs/base/common/errors'; +import URI from 'vs/base/common/uri'; +import {onUnexpectedError, illegalArgument} from 'vs/base/common/errors'; import {TPromise} from 'vs/base/common/winjs.base'; import {Range} from 'vs/editor/common/core/range'; import {IModel} from 'vs/editor/common/editorCommon'; import {IOutlineEntry, IOutlineSupport} from 'vs/editor/common/modes'; import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry'; +import {IModelService} from 'vs/editor/common/services/modelService'; +import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions'; const OutlineRegistry = new LanguageFeatureRegistry('outlineSupport'); @@ -20,7 +23,12 @@ export { IOutlineSupport } -export function getOutlineEntries(model: IModel): TPromise<{ entries: IOutlineEntry[], outlineGroupLabel: { [n: string]: string;} }> { +export interface IOutline { + entries: IOutlineEntry[]; + outlineGroupLabel: { [n: string]: string; }; +} + +export function getOutlineEntries(model: IModel): TPromise { let groupLabels: { [n: string]: string } = Object.create(null); let entries: IOutlineEntry[] = []; @@ -74,3 +82,16 @@ function flatten(bucket: IOutlineEntry[], entries: IOutlineEntry[], overrideCont } } } + + +CommonEditorRegistry.registerLanguageCommand('_executeDocumentSymbolProvider', function(accessor, args) { + const {resource} = args; + if (!URI.isURI(resource)) { + throw illegalArgument('resource'); + } + const model = accessor.get(IModelService).getModel(resource); + if (!model) { + throw illegalArgument('resource'); + } + return getOutlineEntries(model); +}); \ No newline at end of file diff --git a/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts b/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts index 3e413da1e18..4f22bacbe26 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatureCommands.ts @@ -29,7 +29,7 @@ import {ExtraInfoRegistry} from 'vs/editor/contrib/hover/common/hover'; import {OccurrencesRegistry} from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter'; import {ReferenceRegistry} from 'vs/editor/contrib/referenceSearch/common/referenceSearch'; import {QuickFixRegistry} from 'vs/editor/contrib/quickFix/common/quickFix'; -import {OutlineRegistry, IOutlineEntry, IOutlineSupport} from 'vs/editor/contrib/quickOpen/common/quickOpen'; +import {IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen'; import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry'; import {NavigateTypesSupportRegistry, INavigateTypesSupport, ITypeBearing} from 'vs/workbench/parts/search/common/search' import {RenameRegistry} from 'vs/editor/contrib/rename/common/rename'; @@ -45,10 +45,10 @@ import {SuggestRegistry} from 'vs/editor/contrib/suggest/common/suggest'; // vscode.executeReferenceProvider // vscode.executeDocumentRenameProvider // vscode.executeSignatureHelpProvider +// vscode.executeDocumentSymbolProvider // vscode.executeCodeActionProvider // vscode.executeCodeLensProvider -// vscode.executeDocumentSymbolProvider // vscode.executeFormatDocumentProvider // vscode.executeFormatRangeProvider // vscode.executeFormatOnTypeProvider @@ -69,6 +69,7 @@ export class ExtHostLanguageFeatureCommands { this._register('vscode.executeReferenceProvider', this._executeReferenceProvider); this._register('vscode.executeDocumentRenameProvider', this._executeDocumentRenameProvider); this._register('vscode.executeSignatureHelpProvider', this._executeSignatureHelpProvider); + this._register('vscode.executeDocumentSymbolProvider', this._executeDocumentSymbolProvider); } private _register(id: string, callback: (...args: any[]) => any): void { @@ -166,4 +167,15 @@ export class ExtHostLanguageFeatureCommands { } }); } + + private _executeDocumentSymbolProvider(resource: URI): Thenable { + const args = { + resource + }; + return this._commands.executeCommand('_executeDocumentSymbolProvider', args).then(value => { + if (value && Array.isArray(value.entries)) { + return value.entries.map(typeConverters.SymbolInformation.fromOutlineEntry); + } + }); + } } \ No newline at end of file diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index cb91662ab87..6a117f040bb 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -72,20 +72,10 @@ class OutlineAdapter implements IOutlineSupport { let doc = this._documents.getDocument(resource); return asWinJsPromise(token => this._provider.provideDocumentSymbols(doc, token)).then(value => { if (Array.isArray(value)) { - return value.map(OutlineAdapter._convertSymbolInfo); + return value.map(TypeConverters.SymbolInformation.toOutlineEntry); } }); } - - private static _convertSymbolInfo(symbol: vscode.SymbolInformation): IOutlineEntry { - return { - type: TypeConverters.fromSymbolKind(symbol.kind), - range: TypeConverters.fromRange(symbol.location.range), - containerLabel: symbol.containerName, - label: symbol.name, - icon: undefined, - }; - } } class CodeLensAdapter implements modes.ICodeLensSupport { diff --git a/src/vs/workbench/api/common/pluginHostTypeConverters.ts b/src/vs/workbench/api/common/pluginHostTypeConverters.ts index fbe21b4c8c5..1f8e6433c65 100644 --- a/src/vs/workbench/api/common/pluginHostTypeConverters.ts +++ b/src/vs/workbench/api/common/pluginHostTypeConverters.ts @@ -68,43 +68,6 @@ export function fromPosition(position: types.Position):IPosition { return { lineNumber: position.line + 1, column: position.character + 1}; } -export function fromSymbolKind(kind: number | types.SymbolKind): string { - switch (kind) { - case types.SymbolKind.Method: - return 'method'; - case types.SymbolKind.Function: - return 'function'; - case types.SymbolKind.Constructor: - return 'constructor'; - case types.SymbolKind.Variable: - return 'variable'; - case types.SymbolKind.Class: - return 'class'; - case types.SymbolKind.Interface: - return 'interface'; - case types.SymbolKind.Module: - case types.SymbolKind.Namespace: - case types.SymbolKind.Package: - return 'module'; - case types.SymbolKind.Property: - return 'property'; - case types.SymbolKind.Enum: - return 'enum'; - case types.SymbolKind.String: - return 'string'; - case types.SymbolKind.File: - return 'file'; - case types.SymbolKind.Array: - return 'array'; - case types.SymbolKind.Number: - return 'number'; - case types.SymbolKind.Boolean: - return 'boolean'; - } - - return 'property'; -} - export function fromDiagnosticSeverity(value: number): Severity { switch (value) { case types.DiagnosticSeverity.Error: @@ -211,6 +174,103 @@ export function fromTextEdit(edit: vscode.TextEdit) { } } +export namespace SymbolKind { + + export function from(kind: number | types.SymbolKind): string { + switch (kind) { + case types.SymbolKind.Method: + return 'method'; + case types.SymbolKind.Function: + return 'function'; + case types.SymbolKind.Constructor: + return 'constructor'; + case types.SymbolKind.Variable: + return 'variable'; + case types.SymbolKind.Class: + return 'class'; + case types.SymbolKind.Interface: + return 'interface'; + case types.SymbolKind.Module: + case types.SymbolKind.Namespace: + case types.SymbolKind.Package: + return 'module'; + case types.SymbolKind.Property: + return 'property'; + case types.SymbolKind.Enum: + return 'enum'; + case types.SymbolKind.String: + return 'string'; + case types.SymbolKind.File: + return 'file'; + case types.SymbolKind.Array: + return 'array'; + case types.SymbolKind.Number: + return 'number'; + case types.SymbolKind.Boolean: + return 'boolean'; + } + return 'property'; + } + + export function to(type: string): types.SymbolKind { + switch (type) { + case 'method': + return types.SymbolKind.Method; + case 'function': + return types.SymbolKind.Function; + case 'constructor': + return types.SymbolKind.Constructor; + case 'variable': + return types.SymbolKind.Variable; + case 'class': + return types.SymbolKind.Class; + case 'interface': + return types.SymbolKind.Interface; + case 'module': + // case types.SymbolKind.Namespace: + // case types.SymbolKind.Package: + return types.SymbolKind.Module; + case 'property': + return types.SymbolKind.Property; + case 'enum': + return types.SymbolKind.Enum; + case 'string': + return types.SymbolKind.String; + case 'file': + return types.SymbolKind.File; + case 'array': + return types.SymbolKind.Array; + case 'number': + return types.SymbolKind.Number; + case 'boolean': + return types.SymbolKind.Boolean; + } + return types.SymbolKind.Property + } +} + +export namespace SymbolInformation { + + export function fromOutlineEntry(entry: modes.IOutlineEntry): types.SymbolInformation { + return new types.SymbolInformation(entry.label, + SymbolKind.to(entry.type), + toRange(entry.range), + undefined, + entry.containerLabel) + } + + export function toOutlineEntry(symbol: vscode.SymbolInformation): modes.IOutlineEntry { + return { + type: SymbolKind.from(symbol.kind), + range: fromRange(symbol.location.range), + containerLabel: symbol.containerName, + label: symbol.name, + icon: undefined, + }; + } + +} + export function fromSymbolInformation(info: vscode.SymbolInformation): ITypeBearing { return { name: info.name, diff --git a/src/vs/workbench/test/common/api/extHostLanguageFeatureCommands.test.ts b/src/vs/workbench/test/common/api/extHostLanguageFeatureCommands.test.ts index c5eeb9052ea..b3fe6b701dc 100644 --- a/src/vs/workbench/test/common/api/extHostLanguageFeatureCommands.test.ts +++ b/src/vs/workbench/test/common/api/extHostLanguageFeatureCommands.test.ts @@ -188,7 +188,7 @@ suite('ExtHostLanguageFeatureCommands', function() { test('Definition, ⇔ back and forth', function(done) { disposables.push(extHost.registerDefinitionProvider(defaultSelector, { - provideDefinition(doc:any): any { + provideDefinition(doc: any): any { return new types.Location(doc.uri, new types.Range(0, 0, 0, 0)); } })); @@ -208,5 +208,28 @@ suite('ExtHostLanguageFeatureCommands', function() { done(); }); }); - }) + }); + + // --- outline + + test('Outline, back and forth', function(done) { + disposables.push(extHost.registerDocumentSymbolProvider(defaultSelector, { + provideDocumentSymbols(): any { + return [ + new types.SymbolInformation('testing1', types.SymbolKind.Enum, new types.Range(1, 0, 1, 0)), + new types.SymbolInformation('testing2', types.SymbolKind.Enum, new types.Range(0, 1, 0, 3)), + ] + } + })); + + threadService.sync().then(() => { + commands.executeCommand('vscode.executeDocumentSymbolProvider', model.getAssociatedResource()).then(values => { + assert.equal(values.length, 2); + let [first, second] = values; + assert.equal(first.name, 'testing2'); + assert.equal(second.name, 'testing1'); + done(); + }); + }); + }); }); \ No newline at end of file -- GitLab