Skip to content

Commit 7d1de2c

Browse files
committed
signature help provider as support
1 parent 253b92e commit 7d1de2c

6 files changed

Lines changed: 141 additions & 130 deletions

File tree

src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import async = require('vs/base/common/async');
1111
import events = require('vs/base/common/eventEmitter');
1212
import EditorCommon = require('vs/editor/common/editorCommon');
1313
import Modes = require('vs/editor/common/modes');
14-
import {ParameterHintsRegistry} from '../common/parameterHints';
14+
import {ParameterHintsRegistry, getParameterHints} from '../common/parameterHints';
1515
import {sequence} from 'vs/base/common/async';
1616

1717
function hashParameterHints(hints: Modes.IParameterHints): string {
@@ -96,15 +96,8 @@ export class ParameterHintsModel extends events.EventEmitter {
9696
}
9797

9898
public doTrigger(triggerCharacter: string): TPromise<boolean> {
99-
let model = this.editor.getModel();
100-
let support = ParameterHintsRegistry.ordered(model)[0];
101-
if (!support) {
102-
return TPromise.as(false);
103-
}
104-
105-
return support.getParameterHints(model.getAssociatedResource(), this.editor.getPosition(), triggerCharacter).then((result: Modes.IParameterHints) => {
99+
return getParameterHints(this.editor.getModel(), this.editor.getPosition(), triggerCharacter).then(result => {
106100
var hash = hashParameterHints(result);
107-
108101
if (!result || result.signatures.length === 0 || (this.hash && hash !== this.hash)) {
109102
this.cancel();
110103
this.emit('cancel');

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,20 @@
55

66
'use strict';
77

8-
import {IParameterHintsSupport} from 'vs/editor/common/modes';
8+
import {IParameterHintsSupport, IParameterHints} from 'vs/editor/common/modes';
9+
import {IModel, IPosition} from 'vs/editor/common/editorCommon';
10+
import {TPromise} from 'vs/base/common/winjs.base';
11+
import {onUnexpectedError} from 'vs/base/common/errors';
912
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
1013

1114
export const ParameterHintsRegistry = new LanguageFeatureRegistry<IParameterHintsSupport>('parameterHintsSupport');
15+
16+
export function getParameterHints(model:IModel, position:IPosition, triggerCharacter: string): TPromise<IParameterHints> {
17+
18+
let support = ParameterHintsRegistry.ordered(model)[0];
19+
if (!support) {
20+
return TPromise.as(undefined);
21+
}
22+
23+
return support.getParameterHints(model.getAssociatedResource(), position, triggerCharacter);
24+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ export class PluginHostAPIImplementation {
301301
return languageFeatures.registerOnTypeFormattingEditProvider(selector, provider, [firstTriggerCharacter].concat(moreTriggerCharacters));
302302
},
303303
registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, ...triggerCharacters: string[]): vscode.Disposable {
304-
return features.signatureHelp.register(selector, { triggerCharacters, provider });
304+
return languageFeatures.registerSignatureHelpProvider(selector, provider, triggerCharacters);
305305
},
306306
registerCompletionItemProvider(selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, ...triggerCharacters: string[]): vscode.Disposable {
307307
return languageFeatures.registerCompletionItemProvider(selector, provider, triggerCharacters);

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

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,10 +617,81 @@ class SuggestAdapter implements modes.ISuggestSupport {
617617
}
618618
}
619619

620+
class ParameterHintsAdapter implements modes.IParameterHintsSupport {
621+
622+
private _documents: PluginHostModelService;
623+
private _provider: vscode.SignatureHelpProvider;
624+
625+
constructor(documents: PluginHostModelService, provider: vscode.SignatureHelpProvider) {
626+
this._documents = documents;
627+
this._provider = provider;
628+
}
629+
630+
getParameterHints(resource: URI, position: IPosition, triggerCharacter?: string): TPromise<modes.IParameterHints> {
631+
632+
const doc = this._documents.getDocument(resource);
633+
const pos = TypeConverters.toPosition(position);
634+
635+
return asWinJsPromise(token => this._provider.provideSignatureHelp(doc, pos, token)).then(value => {
636+
if (value instanceof SignatureHelp) {
637+
return ParameterHintsAdapter._convertSignatureHelp(value);
638+
}
639+
});
640+
}
641+
642+
private static _convertSignatureHelp(signatureHelp: SignatureHelp): modes.IParameterHints {
643+
644+
let result: modes.IParameterHints = {
645+
currentSignature: signatureHelp.activeSignature,
646+
currentParameter: signatureHelp.activeParameter,
647+
signatures: []
648+
}
649+
650+
for (let signature of signatureHelp.signatures) {
651+
652+
let signatureItem: modes.ISignature = {
653+
label: signature.label,
654+
documentation: signature.documentation,
655+
parameters: []
656+
};
657+
658+
let idx = 0;
659+
for (let parameter of signature.parameters) {
660+
661+
let parameterItem: modes.IParameter = {
662+
label: parameter.label,
663+
documentation: parameter.documentation,
664+
};
665+
666+
signatureItem.parameters.push(parameterItem);
667+
idx = signature.label.indexOf(parameter.label, idx);
668+
669+
if (idx >= 0) {
670+
parameterItem.signatureLabelOffset = idx;
671+
idx += parameter.label.length;
672+
parameterItem.signatureLabelEnd = idx;
673+
}
674+
}
675+
676+
result.signatures.push(signatureItem);
677+
}
678+
679+
return result;
680+
}
681+
682+
getParameterHintsTriggerCharacters(): string[] {
683+
throw new Error('illegal state');
684+
}
685+
686+
shouldTriggerParameterHints(context: modes.ILineContext, offset: number): boolean {
687+
throw new Error('illegal state');
688+
}
689+
}
690+
620691
type Adapter = OutlineAdapter | CodeLensAdapter | DeclarationAdapter | ExtraInfoAdapter
621692
| OccurrencesAdapter | ReferenceAdapter | QuickFixAdapter | DocumentFormattingAdapter
622693
| RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter
623-
| SuggestAdapter;
694+
| SuggestAdapter | ParameterHintsAdapter;
624695

625696
@Remotable.PluginHostContext('ExtHostLanguageFeatures')
626697
export class ExtHostLanguageFeatures {
@@ -833,6 +904,19 @@ export class ExtHostLanguageFeatures {
833904
$getSuggestionDetails(handle: number, resource: URI, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion> {
834905
return this._withAdapter(handle, SuggestAdapter, adapter => adapter.getSuggestionDetails(resource, position, suggestion));
835906
}
907+
908+
// --- parameter hints
909+
910+
registerSignatureHelpProvider(selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, triggerCharacters: string[]): vscode.Disposable {
911+
const handle = this._nextHandle();
912+
this._adapter[handle] = new ParameterHintsAdapter(this._documents, provider);
913+
this._proxy.$registerParameterHintsSupport(handle, selector, triggerCharacters);
914+
return this._createDisposable(handle);
915+
}
916+
917+
$getParameterHints(handle: number, resource: URI, position: IPosition, triggerCharacter?: string): TPromise<modes.IParameterHints> {
918+
return this._withAdapter(handle, ParameterHintsAdapter, adapter => adapter.getParameterHints(resource, position, triggerCharacter));
919+
}
836920
}
837921

838922
@Remotable.MainContext('MainThreadLanguageFeatures')
@@ -1030,4 +1114,21 @@ export class MainThreadLanguageFeatures {
10301114
});
10311115
return undefined;
10321116
}
1117+
1118+
// --- parameter hints
1119+
1120+
$registerParameterHintsSupport(handle: number, selector: vscode.DocumentSelector, triggerCharacter: string[]): TPromise<any> {
1121+
this._registrations[handle] = ParameterHintsRegistry.register(selector, <modes.IParameterHintsSupport>{
1122+
getParameterHints: (resource: URI, position: IPosition, triggerCharacter?: string): TPromise<modes.IParameterHints> => {
1123+
return this._proxy.$getParameterHints(handle, resource, position, triggerCharacter);
1124+
},
1125+
getParameterHintsTriggerCharacters(): string[] {
1126+
return triggerCharacter;
1127+
},
1128+
shouldTriggerParameterHints(context: modes.ILineContext, offset: number): boolean {
1129+
return true;
1130+
}
1131+
});
1132+
return undefined;
1133+
}
10331134
}

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

Lines changed: 0 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -282,132 +282,14 @@ export class MainThreadFormatOnType extends AbstractMainThreadFeature<modes.IFor
282282
}
283283
}
284284

285-
// ---- signature help
286-
287-
export interface SignatureHelpEntry {
288-
provider: vscode.SignatureHelpProvider;
289-
triggerCharacters: string[];
290-
}
291-
292-
export class ExtHostSignatureHelp extends AbstractExtensionHostFeature<SignatureHelpEntry, MainThreadSignatureHelp> {
293-
294-
constructor( @IThreadService threadService: IThreadService) {
295-
super(threadService.getRemotable(MainThreadSignatureHelp), threadService);
296-
}
297-
298-
register(selector: vscode.DocumentSelector, entry: SignatureHelpEntry): vscode.Disposable {
299-
300-
let disposable = this._registry.register(selector, entry);
301-
let registered = this._proxy._register(selector, entry.triggerCharacters);
302-
303-
return new Disposable(() => {
304-
disposable.dispose();
305-
registered.then(() => this._proxy._unregister());
306-
});
307-
}
308-
309-
_runAsCommand(resource: URI, position: IPosition, triggerCharacter?: string): TPromise<modes.IParameterHints> {
310-
311-
let document = this._models.getDocument(resource);
312-
let pos = TypeConverters.toPosition(position);
313-
314-
let entry = this._getOrderedFor(document)[0];
315-
if (entry) {
316-
317-
if (triggerCharacter) {
318-
if (entry.triggerCharacters.indexOf(triggerCharacter) < 0) {
319-
return;
320-
}
321-
}
322-
323-
return asWinJsPromise(token => entry.provider.provideSignatureHelp(document, pos, token)).then(result => {
324-
if (result instanceof SignatureHelp) {
325-
return ExtHostSignatureHelp._convertSignatureHelp(result);
326-
}
327-
});
328-
}
329-
}
330-
331-
private static _convertSignatureHelp(signatureHelp: SignatureHelp): modes.IParameterHints {
332-
333-
let result: modes.IParameterHints = {
334-
currentSignature: signatureHelp.activeSignature,
335-
currentParameter: signatureHelp.activeParameter,
336-
signatures: []
337-
}
338-
339-
for (let signature of signatureHelp.signatures) {
340-
341-
let signatureItem: modes.ISignature = {
342-
label: signature.label,
343-
documentation: signature.documentation,
344-
parameters: []
345-
};
346-
347-
let idx = 0;
348-
for (let parameter of signature.parameters) {
349-
350-
let parameterItem: modes.IParameter = {
351-
label: parameter.label,
352-
documentation: parameter.documentation,
353-
};
354-
355-
signatureItem.parameters.push(parameterItem);
356-
idx = signature.label.indexOf(parameter.label, idx);
357-
358-
if (idx >= 0) {
359-
parameterItem.signatureLabelOffset = idx;
360-
idx += parameter.label.length;
361-
parameterItem.signatureLabelEnd = idx;
362-
}
363-
}
364-
365-
result.signatures.push(signatureItem);
366-
}
367-
368-
return result;
369-
}
370-
}
371-
372-
@Remotable.MainContext('MainThreadSignatureHelp')
373-
export class MainThreadSignatureHelp extends AbstractMainThreadFeature<modes.IParameterHintsSupport> implements modes.IParameterHintsSupport {
374-
375-
private _triggerCharacters: string[] = [];
376-
377-
constructor( @IThreadService threadService: IThreadService) {
378-
super('vscode.executeSignatureHelpProvider', ParameterHintsRegistry, threadService);
379-
}
380-
381-
_register(selector: vscode.DocumentSelector, triggerCharacters: string[] = []): TPromise<number> {
382-
this._triggerCharacters.push(...triggerCharacters);
383-
return super._register(selector);
384-
}
385-
386-
getParameterHintsTriggerCharacters(): string[] {
387-
return this._triggerCharacters;
388-
}
389-
390-
shouldTriggerParameterHints(context: modes.ILineContext, offset: number): boolean {
391-
return true;
392-
}
393-
394-
getParameterHints(resource: URI, position: IPosition, triggerCharacter?: string): TPromise<modes.IParameterHints> {
395-
return this._executeCommand(resource, position, triggerCharacter);
396-
}
397-
}
398-
399-
// ---- Completions
400-
401285

402286
export namespace LanguageFeatures {
403287

404288
export function createMainThreadInstances(threadService: IThreadService): void {
405-
threadService.getRemotable(MainThreadSignatureHelp);
406289
}
407290

408291
export function createExtensionHostInstances(threadService: IThreadService) {
409292
return {
410-
signatureHelp: new ExtHostSignatureHelp(threadService),
411293
};
412294
}
413295
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {ReferenceRegistry, findReferences} from 'vs/editor/contrib/referenceSear
3535
import {getQuickFixes} from 'vs/editor/contrib/quickFix/common/quickFix';
3636
import {getNavigateToItems} from 'vs/workbench/parts/search/common/search';
3737
import {rename} from 'vs/editor/contrib/rename/common/rename';
38+
import {getParameterHints} from 'vs/editor/contrib/parameterHints/common/parameterHints';
3839

3940
const defaultSelector = { scheme: 'far' };
4041
const model: EditorCommon.IModel = new EditorModel(
@@ -779,4 +780,25 @@ suite('ExtHostLanguageFeatures', function() {
779780
});
780781
});
781782
});
783+
784+
// --- parameter hints
785+
786+
test('Parameter Hints, evil provider', function(done) {
787+
788+
disposables.push(extHost.registerSignatureHelpProvider(defaultSelector, <vscode.SignatureHelpProvider>{
789+
provideSignatureHelp(): any {
790+
throw new Error('evil');
791+
}
792+
}, []));
793+
794+
threadService.sync().then(() => {
795+
796+
getParameterHints(model, { lineNumber: 1, column: 1 }, '(').then(value => {
797+
done(new Error('error expeted'));
798+
}, err => {
799+
assert.equal(err.message, 'evil');
800+
done();
801+
})
802+
});
803+
})
782804
});

0 commit comments

Comments
 (0)