Skip to content

Commit a7ff9cd

Browse files
committed
workspace symbol provider as support
1 parent d872b0f commit a7ff9cd

6 files changed

Lines changed: 100 additions & 130 deletions

File tree

src/vs/workbench/api/browser/pluginHost.api.impl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ export class PluginHostAPIImplementation {
289289
return languageFeatures.registerDocumentSymbolProvider(selector, provider);
290290
},
291291
registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
292-
return features.workspaceSymbols.register(provider);
292+
return languageFeatures.registerWorkspaceSymbolProvider(provider);
293293
},
294294
registerDocumentFormattingEditProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentFormattingEditProvider): vscode.Disposable {
295295
return languageFeatures.registerDocumentFormattingEditProvider(selector, provider);

src/vs/workbench/api/common/extHostLanguageFeatures.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,36 @@ class OnTypeFormattingAdapter implements modes.IFormattingSupport {
426426
}
427427
}
428428

429+
class NavigateTypeAdapter implements INavigateTypesSupport {
430+
431+
private _provider: vscode.WorkspaceSymbolProvider;
432+
433+
constructor(provider: vscode.WorkspaceSymbolProvider) {
434+
this._provider = provider;
435+
}
436+
437+
getNavigateToItems(search: string): TPromise<ITypeBearing[]> {
438+
return asWinJsPromise(token => this._provider.provideWorkspaceSymbols(search, token)).then(value => {
439+
if (Array.isArray(value)) {
440+
return value.map(NavigateTypeAdapter._fromSymbolInformation);
441+
}
442+
});
443+
}
444+
445+
private static _fromSymbolInformation(info: vscode.SymbolInformation): ITypeBearing {
446+
return <ITypeBearing>{
447+
name: info.name,
448+
type: SymbolKind[info.kind || SymbolKind.Property].toLowerCase(),
449+
range: TypeConverters.fromRange(info.location.range),
450+
resourceUri: info.location.uri,
451+
containerName: info.containerName,
452+
parameters: '',
453+
};
454+
}
455+
}
456+
429457
type Adapter = OutlineAdapter | CodeLensAdapter | DeclarationAdapter | ExtraInfoAdapter | OccurrencesAdapter | ReferenceAdapter | QuickFixAdapter
430-
| DocumentFormattingAdapter | RangeFormattingAdapter | OnTypeFormattingAdapter;
458+
| DocumentFormattingAdapter | RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter;
431459

432460
@Remotable.PluginHostContext('ExtHostLanguageFeatures')
433461
export class ExtHostLanguageFeatures {
@@ -598,6 +626,18 @@ export class ExtHostLanguageFeatures {
598626
return this._withAdapter(handle, OnTypeFormattingAdapter, adapter => adapter.formatAfterKeystroke(resource, position, ch, options));
599627
}
600628

629+
// --- navigate types
630+
631+
registerWorkspaceSymbolProvider(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
632+
const handle = this._nextHandle();
633+
this._adapter[handle] = new NavigateTypeAdapter(provider);
634+
this._proxy.$registerNavigateTypeSupport(handle);
635+
return this._createDisposable(handle);
636+
}
637+
638+
$getNavigateToItems(handle: number, search: string): TPromise<ITypeBearing[]> {
639+
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.getNavigateToItems(search));
640+
}
601641
}
602642

603643
@Remotable.MainContext('MainThreadLanguageFeatures')
@@ -747,4 +787,15 @@ export class MainThreadLanguageFeatures {
747787
});
748788
return undefined;
749789
}
790+
791+
// --- navigate type
792+
793+
$registerNavigateTypeSupport(handle: number): TPromise<any> {
794+
this._registrations[handle] = NavigateTypesSupportRegistry.register(<INavigateTypesSupport>{
795+
getNavigateToItems: (search: string): TPromise<ITypeBearing[]> => {
796+
return this._proxy.$getNavigateToItems(handle, search);
797+
}
798+
});
799+
return undefined;
800+
}
750801
}

src/vs/workbench/api/common/languageFeatures.ts

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -625,124 +625,17 @@ export class MainThreadCompletions extends AbstractMainThreadFeature<modes.ISugg
625625
}
626626
}
627627

628-
// --- workspace symbols
629-
630-
export class ExtensionHostWorkspaceSymbols {
631-
632-
private _provider: vscode.WorkspaceSymbolProvider[] = [];
633-
private _proxy: MainThreadWorkspaceSymbols;
634-
private _threadService: IThreadService;
635-
private _commands: PluginHostCommands;
636-
637-
constructor(@IThreadService threadService: IThreadService) {
638-
this._threadService = threadService;
639-
this._commands = threadService.getRemotable(PluginHostCommands);
640-
this._proxy = threadService.getRemotable(MainThreadWorkspaceSymbols);
641-
this._commands.registerCommand(MainThreadWorkspaceSymbols.CommandId, this._runAsCommand, this);
642-
}
643-
644-
register(provider: vscode.WorkspaceSymbolProvider): vscode.Disposable {
645-
646-
this._provider.push(provider);
647-
648-
// is first, register commands, do stuff
649-
if (this._provider.length === 1) {
650-
this._proxy._enable(true);
651-
}
652-
653-
return new Disposable(() => {
654-
let idx = this._provider.indexOf(provider);
655-
if (idx >= 0) {
656-
this._provider.splice(idx, 1);
657-
if (this._provider.length === 0) {
658-
this._proxy._enable(false);
659-
}
660-
}
661-
});
662-
}
663-
664-
private _runAsCommand(query: string): TPromise<ITypeBearing[]> {
665-
666-
if (typeof query !== 'string') {
667-
return TPromise.wrapError('query is not string');
668-
}
669-
670-
let symbols: vscode.SymbolInformation[] = [];
671-
let promises = this._provider.map(provider => {
672-
return asWinJsPromise(token => {
673-
return provider.provideWorkspaceSymbols(query, token)
674-
}).then(value => {
675-
if (Array.isArray(value)) {
676-
symbols.push(...value);
677-
}
678-
}, err => {
679-
console.error(err);
680-
});
681-
});
682-
683-
return TPromise.join(promises).then(() => {
684-
return symbols.map(ExtensionHostWorkspaceSymbols._fromSymbolInformation);
685-
});
686-
}
687-
688-
private static _fromSymbolInformation(info: vscode.SymbolInformation): ITypeBearing {
689-
return <ITypeBearing>{
690-
name: info.name,
691-
type: SymbolKind[info.kind || SymbolKind.Property].toLowerCase(),
692-
range: TypeConverters.fromRange(info.location.range),
693-
resourceUri: info.location.uri,
694-
containerName: info.containerName,
695-
parameters: '',
696-
};
697-
}
698-
}
699-
700-
@Remotable.MainContext('MainThreadWorkspaceSymbols')
701-
export class MainThreadWorkspaceSymbols implements INavigateTypesSupport {
702-
703-
static CommandId = 'vscode.executeWorkspaceSymbolProvider';
704-
705-
private _commands: PluginHostCommands;
706-
private _disposable: IDisposable;
707-
708-
constructor(@IThreadService threadService: IThreadService) {
709-
this._commands = threadService.getRemotable(PluginHostCommands);
710-
}
711-
712-
_enable(value: boolean): void {
713-
if (value) {
714-
this._disposable = NavigateTypesSupportRegistry.register(this);
715-
} else if (this._disposable) {
716-
this._disposable.dispose();
717-
this._disposable = undefined;
718-
}
719-
}
720-
721-
getNavigateToItems(search: string): TPromise<ITypeBearing[]> {
722-
let value = this._commands.executeCommand<ITypeBearing[]>(MainThreadWorkspaceSymbols.CommandId, search);
723-
return TPromise.as(<any>value);
724-
}
725-
}
726-
727628
export namespace LanguageFeatures {
728629

729630
export function createMainThreadInstances(threadService: IThreadService): void {
730-
threadService.getRemotable(MainThreadWorkspaceSymbols);
731631
threadService.getRemotable(MainThreadRename);
732-
threadService.getRemotable(MainThreadFormatDocument);
733-
threadService.getRemotable(MainThreadFormatRange);
734-
threadService.getRemotable(MainThreadFormatOnType);
735632
threadService.getRemotable(MainThreadSignatureHelp);
736633
threadService.getRemotable(MainThreadCompletions);
737634
}
738635

739636
export function createExtensionHostInstances(threadService: IThreadService) {
740637
return {
741-
workspaceSymbols: new ExtensionHostWorkspaceSymbols(threadService),
742638
rename: new ExtensionHostRename(threadService),
743-
formatDocument: new ExtHostFormatDocument(threadService),
744-
formatRange: new ExtHostFormatRange(threadService),
745-
formatOnType: new ExtHostFormatOnType(threadService),
746639
signatureHelp: new ExtHostSignatureHelp(threadService),
747640
completions: threadService.getRemotable(ExtHostCompletions)
748641
};

src/vs/workbench/parts/search/browser/openSymbolHandler.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {IWorkbenchEditorService, IFileInput} from 'vs/workbench/services/editor/
2323
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
2424
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
2525
import {IModeService} from 'vs/editor/common/services/modeService';
26-
import {NavigateTypesSupportRegistry, ITypeBearing} from '../common/search';
26+
import {NavigateTypesSupportRegistry, ITypeBearing, getNavigateToItems} from '../common/search';
2727

2828
class SymbolEntry extends EditorQuickOpenEntry {
2929
private name: string;
@@ -135,21 +135,7 @@ export class OpenSymbolHandler extends QuickOpenHandler {
135135

136136
private doGetResults(searchValue: string): TPromise<QuickOpenEntry[]> {
137137

138-
let registry = <IEditorModesRegistry>Registry.as(Extensions.EditorModes);
139-
140-
// Find Types (and ignore error)
141-
let bearings: ITypeBearing[] = [];
142-
let promises = NavigateTypesSupportRegistry.getAll().map(support => {
143-
return support.getNavigateToItems(searchValue).then(result => {
144-
if (Array.isArray(result)) {
145-
bearings.push(...result);
146-
}
147-
}, err => {
148-
errors.onUnexpectedError(err);
149-
});
150-
});
151-
152-
return TPromise.join(promises).then(() => {
138+
return getNavigateToItems(searchValue).then(bearings => {
153139
return this.toQuickOpenEntries(bearings, searchValue);
154140
});
155141
}

src/vs/workbench/parts/search/common/search.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
'use strict';
77

88
import {TPromise} from 'vs/base/common/winjs.base';
9+
import {onUnexpectedError} from 'vs/base/common/errors';
910
import {IDisposable} from 'vs/base/common/lifecycle';
1011
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
1112
import {IRange} from 'vs/editor/common/editorCommon';
@@ -51,11 +52,24 @@ export namespace NavigateTypesSupportRegistry {
5152
}
5253
}
5354

54-
// export function has(): boolean {
55-
// return _supports.length > 0;
56-
// }
57-
58-
export function getAll(): INavigateTypesSupport[] {
55+
export function all(): INavigateTypesSupport[] {
5956
return _supports.slice(0);
6057
}
6158
}
59+
60+
export function getNavigateToItems(query: string): TPromise<ITypeBearing[]> {
61+
62+
const promises = NavigateTypesSupportRegistry.all().map(support => {
63+
return support.getNavigateToItems(query).then(value => value, onUnexpectedError);
64+
});
65+
66+
return TPromise.join(promises).then(all => {
67+
const result: ITypeBearing[] = [];
68+
for (let bearings of all) {
69+
if (Array.isArray(bearings)) {
70+
result.push(...bearings);
71+
}
72+
}
73+
return result;
74+
});
75+
}

src/vs/workbench/test/common/api/extHostLanguageFeatures.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {ExtraInfoRegistry, getExtraInfoAtPosition} from 'vs/editor/contrib/hover
3333
import {OccurrencesRegistry, getOccurrencesAtPosition} from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
3434
import {ReferenceRegistry, findReferences} from 'vs/editor/contrib/referenceSearch/common/referenceSearch';
3535
import {getQuickFixes} from 'vs/editor/contrib/quickFix/common/quickFix';
36+
import {getNavigateToItems} from 'vs/workbench/parts/search/common/search';
3637

3738
const defaultSelector = { scheme: 'far' };
3839
const model: EditorCommon.IModel = new EditorModel(
@@ -681,4 +682,29 @@ suite('ExtHostLanguageFeatures', function() {
681682
});
682683
});
683684
});
685+
686+
// --- navigate types
687+
688+
test('Navigate types, evil provider', function(done) {
689+
690+
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
691+
provideWorkspaceSymbols(): any {
692+
throw new Error('evil');
693+
}
694+
}));
695+
696+
disposables.push(extHost.registerWorkspaceSymbolProvider(<vscode.WorkspaceSymbolProvider>{
697+
provideWorkspaceSymbols(): any {
698+
return [new types.SymbolInformation('testing', types.SymbolKind.Array, new types.Range(0, 0, 1, 1))]
699+
}
700+
}));
701+
702+
threadService.sync().then(() => {
703+
704+
getNavigateToItems('').then(value => {
705+
assert.equal(value.length, 1);
706+
done();
707+
});
708+
});
709+
})
684710
});

0 commit comments

Comments
 (0)