Skip to content

Commit 6497432

Browse files
committed
first steps in exposing language featues as command. done with: hover, definition, workspace symbols
1 parent 5f033c8 commit 6497432

12 files changed

Lines changed: 498 additions & 75 deletions

File tree

src/vs/base/common/marshalling.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var currentDynamicContrib:IMarshallingContribution = null;
2929

3030
export function canSerialize(obj: any): boolean {
3131
for (let contrib of marshallingContributions) {
32-
if (contrib.canDeserialize(obj)) {
32+
if (contrib.canSerialize(obj)) {
3333
return true;
3434
}
3535
}

src/vs/editor/contrib/goToDeclaration/common/goToDeclaration.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88
import URI from 'vs/base/common/uri';
99
import {TPromise} from 'vs/base/common/winjs.base';
10-
import {onUnexpectedError} from 'vs/base/common/errors';
10+
import {onUnexpectedError, illegalArgument} from 'vs/base/common/errors';
1111
import {IModel, IPosition} from 'vs/editor/common/editorCommon';
1212
import {IDeclarationSupport} from 'vs/editor/common/modes';
1313
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
1414
import {IReference} from 'vs/editor/common/modes';
15+
import {IModelService} from 'vs/editor/common/services/modelService';
16+
import {registerCommand} from 'vs/platform/keybinding/common/commandsUtils';
1517

1618
export const DeclarationRegistry = new LanguageFeatureRegistry<IDeclarationSupport>('declarationSupport');
1719

@@ -40,4 +42,19 @@ export function getDeclarationsAtPosition(model: IModel, position: IPosition): T
4042
}
4143
return result;
4244
});
43-
}
45+
}
46+
47+
registerCommand('_executeDefinitionProvider', function(accessor, args) {
48+
49+
let {resource, position} = args;
50+
if (!URI.isURI(resource)) {
51+
throw illegalArgument();
52+
}
53+
54+
let model = accessor.get(IModelService).getModel(resource);
55+
if (!model) {
56+
throw illegalArgument(resource + ' not found');
57+
}
58+
59+
return getDeclarationsAtPosition(model, position);
60+
});

src/vs/editor/contrib/hover/common/hover.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import {IExtraInfoSupport, IComputeExtraInfoResult} from 'vs/editor/common/modes
1010
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
1111
import {TPromise} from 'vs/base/common/winjs.base';
1212
import {coalesce} from 'vs/base/common/arrays';
13-
import {onUnexpectedError} from 'vs/base/common/errors';
13+
import {onUnexpectedError, illegalArgument} from 'vs/base/common/errors';
1414
import {IPosition, IModel} from 'vs/editor/common/editorCommon';
15+
import {IModelService} from 'vs/editor/common/services/modelService';
16+
import {registerCommand} from 'vs/platform/keybinding/common/commandsUtils';
1517

1618
export const ExtraInfoRegistry = new LanguageFeatureRegistry<IExtraInfoSupport>('extraInfoSupport');
1719

@@ -37,4 +39,18 @@ export function getExtraInfoAtPosition(model: IModel, position: IPosition): TPro
3739
});
3840

3941
return TPromise.join(promises).then(() => coalesce(values));
40-
}
42+
}
43+
44+
registerCommand('_executeHoverProvider', function(accessor, args) {
45+
46+
let {resource, position} = args;
47+
if (!URI.isURI(resource)) {
48+
throw illegalArgument();
49+
}
50+
let model = accessor.get(IModelService).getModel(resource);
51+
if (!model) {
52+
throw illegalArgument(resource + ' not found');
53+
}
54+
55+
return getExtraInfoAtPosition(model, position);
56+
});
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import {illegalArgument} from 'vs/base/common/errors';
8+
import {ServicesAccessor} from 'vs/platform/instantiation/common/instantiation';
9+
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
10+
11+
export function registerCommand(id: string, handler: (accessor: ServicesAccessor, args: { [n: string]: any }) => any) {
12+
13+
KeybindingsRegistry.registerCommandDesc({
14+
id,
15+
handler(accessor, args: any[]) {
16+
if (args && args.length > 1 || typeof args[0] !== 'object') {
17+
throw illegalArgument();
18+
}
19+
20+
return handler(accessor, args && args[0]);
21+
},
22+
weight: KeybindingsRegistry.WEIGHT.editorContrib(),
23+
primary: undefined,
24+
context: undefined,
25+
});
26+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {PluginHostTelemetryService} from 'vs/workbench/api/common/pluginHostTele
2222
import {PluginHostEditors} from 'vs/workbench/api/common/pluginHostEditors';
2323
import {ExtHostLanguages} from 'vs/workbench/api/common/extHostLanguages';
2424
import {ExtHostLanguageFeatures} from 'vs/workbench/api/common/extHostLanguageFeatures';
25+
import {ExtHostLanguageFeatureCommands} from 'vs/workbench/api/common/extHostLanguageFeatureCommands';
2526
import * as extHostTypes from 'vs/workbench/api/common/pluginHostTypes';
2627
import 'vs/workbench/api/common/pluginHostTypes.marshalling';
2728
import {wrapAsWinJSPromise} from 'vs/base/common/async';
@@ -251,6 +252,7 @@ export class PluginHostAPIImplementation {
251252
const languages = new ExtHostLanguages(this._threadService);
252253
const pluginHostDiagnostics = new PluginHostDiagnostics(this._threadService);
253254
const languageFeatures = threadService.getRemotable(ExtHostLanguageFeatures);
255+
const languageFeatureCommand = new ExtHostLanguageFeatureCommands(threadService.getRemotable(PluginHostCommands));
254256

255257
this.languages = {
256258
createDiagnosticCollection(name?: string): vscode.DiagnosticCollection {
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import URI from 'vs/base/common/uri';
8+
import Event, {Emitter} from 'vs/base/common/event';
9+
import Severity from 'vs/base/common/severity';
10+
import {DefaultFilter} from 'vs/editor/common/modes/modesFilters';
11+
import {TPromise} from 'vs/base/common/winjs.base';
12+
import {onUnexpectedError} from 'vs/base/common/errors';
13+
import {sequence} from 'vs/base/common/async';
14+
import {Range as EditorRange} from 'vs/editor/common/core/range';
15+
import {IDisposable} from 'vs/base/common/lifecycle';
16+
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
17+
import {Remotable, IThreadService} from 'vs/platform/thread/common/thread';
18+
import * as vscode from 'vscode';
19+
import * as typeConverters from 'vs/workbench/api/common/pluginHostTypeConverters';
20+
import * as types from 'vs/workbench/api/common/pluginHostTypes';
21+
import {IPosition, IRange, ISingleEditOperation} from 'vs/editor/common/editorCommon';
22+
import * as modes from 'vs/editor/common/modes';
23+
import {CancellationTokenSource} from 'vs/base/common/cancellation';
24+
import {PluginHostModelService} from 'vs/workbench/api/common/pluginHostDocuments';
25+
import {IMarkerService, IMarker} from 'vs/platform/markers/common/markers';
26+
import {PluginHostCommands, MainThreadCommands} from 'vs/workbench/api/common/pluginHostCommands';
27+
import {DeclarationRegistry} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
28+
import {ExtraInfoRegistry} from 'vs/editor/contrib/hover/common/hover';
29+
import {OccurrencesRegistry} from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
30+
import {ReferenceRegistry} from 'vs/editor/contrib/referenceSearch/common/referenceSearch';
31+
import {QuickFixRegistry} from 'vs/editor/contrib/quickFix/common/quickFix';
32+
import {OutlineRegistry, IOutlineEntry, IOutlineSupport} from 'vs/editor/contrib/quickOpen/common/quickOpen';
33+
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
34+
import {NavigateTypesSupportRegistry, INavigateTypesSupport, ITypeBearing} from 'vs/workbench/parts/search/common/search'
35+
import {RenameRegistry} from 'vs/editor/contrib/rename/common/rename';
36+
import {FormatRegistry, FormatOnTypeRegistry} from 'vs/editor/contrib/format/common/format';
37+
import {CodeLensRegistry} from 'vs/editor/contrib/codelens/common/codelens';
38+
import {ParameterHintsRegistry} from 'vs/editor/contrib/parameterHints/common/parameterHints';
39+
import {SuggestRegistry} from 'vs/editor/contrib/suggest/common/suggest';
40+
41+
// vscode.executeWorkspaceSymbolProvider
42+
// vscode.executeDefinitionProvider
43+
// vscode.executeHoverProvider
44+
45+
// vscode.executeDocumentHighlights
46+
// vscode.executeReferenceProvider
47+
// vscode.executeCodeActionProvider
48+
// vscode.executeCodeLensProvider
49+
// vscode.executeDocumentSymbolProvider
50+
// vscode.executeDocumentRenameProvider
51+
// vscode.executeFormatDocumentProvider
52+
// vscode.executeFormatRangeProvider
53+
// vscode.executeFormatOnTypeProvider
54+
// vscode.executeSignatureHelpProvider
55+
// vscode.executeCompletionItemProvider
56+
57+
export class ExtHostLanguageFeatureCommands {
58+
59+
private _commands: PluginHostCommands;
60+
private _disposables: IDisposable[] = [];
61+
62+
constructor(commands: PluginHostCommands) {
63+
this._commands = commands;
64+
65+
this._register('vscode.executeWorkspaceSymbolProvider', this._executeWorkspaceSymbolProvider);
66+
this._register('vscode.executeDefinitionProvider', this._executeDefinitionProvider);
67+
this._register('vscode.executeHoverProvider', this._executeHoverProvider);
68+
}
69+
70+
private _register(id: string, callback: (...args: any[]) => any): void {
71+
this._disposables.push(this._commands.registerCommand(id, callback, this));
72+
}
73+
74+
// --- command impl
75+
76+
private _executeWorkspaceSymbolProvider(query: string): Thenable<types.SymbolInformation[]> {
77+
return this._commands.executeCommand<ITypeBearing[]>('_executeWorkspaceSymbolProvider', { query }).then(value => {
78+
if (Array.isArray(value)) {
79+
return value.map(typeConverters.toSymbolInformation);
80+
}
81+
});
82+
}
83+
84+
private _executeDefinitionProvider(resource: URI, position: types.Position): Thenable<types.Location[]> {
85+
const args = {
86+
resource,
87+
position: position && typeConverters.fromPosition(position)
88+
};
89+
return this._commands.executeCommand<modes.IReference[]>('_executeDefinitionProvider', args).then(value => {
90+
if (Array.isArray(value)) {
91+
return value.map(typeConverters.toLocation)
92+
}
93+
});
94+
}
95+
96+
private _executeHoverProvider(resource: URI, position: types.Position): Thenable<types.Hover[]> {
97+
const args = {
98+
resource,
99+
position: position && typeConverters.fromPosition(position)
100+
};
101+
return this._commands.executeCommand<modes.IComputeExtraInfoResult[]>('_executeHoverProvider', args).then(value => {
102+
if (Array.isArray(value)) {
103+
return value.map(typeConverters.toHover)
104+
}
105+
});
106+
}
107+
}

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

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -215,20 +215,14 @@ class ExtraInfoAdapter implements modes.IExtraInfoSupport {
215215
if (!value) {
216216
return;
217217
}
218-
219-
let {range, contents} = value;
220-
221-
if (!range) {
222-
range = doc.getWordRangeAtPosition(pos);
218+
if (!value.range) {
219+
value.range = doc.getWordRangeAtPosition(pos);
223220
}
224-
if (!range) {
225-
range = new Range(pos, pos);
221+
if (!value.range) {
222+
value.range = new Range(pos, pos);
226223
}
227224

228-
return <modes.IComputeExtraInfoResult>{
229-
range: TypeConverters.fromRange(range),
230-
htmlContent: contents && contents.map(TypeConverters.fromFormattedString)
231-
}
225+
return TypeConverters.fromHover(value);
232226
});
233227
}
234228
}
@@ -438,21 +432,10 @@ class NavigateTypeAdapter implements INavigateTypesSupport {
438432
getNavigateToItems(search: string): TPromise<ITypeBearing[]> {
439433
return asWinJsPromise(token => this._provider.provideWorkspaceSymbols(search, token)).then(value => {
440434
if (Array.isArray(value)) {
441-
return value.map(NavigateTypeAdapter._fromSymbolInformation);
435+
return value.map(TypeConverters.fromSymbolInformation);
442436
}
443437
});
444438
}
445-
446-
private static _fromSymbolInformation(info: vscode.SymbolInformation): ITypeBearing {
447-
return <ITypeBearing>{
448-
name: info.name,
449-
type: SymbolKind[info.kind || SymbolKind.Property].toLowerCase(),
450-
range: TypeConverters.fromRange(info.location.range),
451-
resourceUri: info.location.uri,
452-
containerName: info.containerName,
453-
parameters: '',
454-
};
455-
}
456439
}
457440

458441
class RenameAdapter implements modes.IRenameSupport {

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ export class PluginHostCommands {
7878
return this._executeContributedCommand(id, ...args);
7979

8080
} else {
81-
// check that we can get all parameters over to
82-
// the other side
83-
for (let i = 0; i < args.length; i++) {
84-
if (typeof args[i] === 'object' && !canSerialize(args[i])) {
85-
throw new Error('illegal argument - can not serialize argument number: ' + i)
86-
}
87-
}
81+
// // check that we can get all parameters over to
82+
// // the other side
83+
// for (let i = 0; i < args.length; i++) {
84+
// if (args[i] !== null && typeof args[i] === 'object' && !canSerialize(args[i])) {
85+
// throw new Error('illegal argument - can not serialize argument number: ' + i)
86+
// }
87+
// }
8888

8989
return this._proxy._executeCommand(id, args);
9090
}

0 commit comments

Comments
 (0)