Skip to content

Commit

Permalink
show error when inlay hints command fails, annotate error with source…
Browse files Browse the repository at this point in the history
… (e.g extension name), fixes #141588
  • Loading branch information
jrieken committed Jan 27, 2022
1 parent 4f9c935 commit ffdeff7
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/vs/editor/common/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1846,6 +1846,7 @@ export interface InlayHintList {
}

export interface InlayHintsProvider {
displayName?: string
onDidChangeInlayHints?: Event<void>;
provideInlayHints(model: model.ITextModel, range: Range, token: CancellationToken): ProviderResult<InlayHintList>;
resolveInlayHint?(hint: InlayHint, token: CancellationToken): ProviderResult<InlayHint>;
Expand Down
8 changes: 4 additions & 4 deletions src/vs/editor/contrib/inlayHints/browser/inlayHints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ export class InlayHintItem {
private _isResolved: boolean = false;
private _currentResolve?: Promise<void>;

constructor(readonly hint: InlayHint, readonly anchor: InlayHintAnchor, private readonly _provider: InlayHintsProvider) { }
constructor(readonly hint: InlayHint, readonly anchor: InlayHintAnchor, readonly provider: InlayHintsProvider) { }

with(delta: { anchor: InlayHintAnchor; }): InlayHintItem {
const result = new InlayHintItem(this.hint, delta.anchor, this._provider);
const result = new InlayHintItem(this.hint, delta.anchor, this.provider);
result._isResolved = this._isResolved;
result._currentResolve = this._currentResolve;
return result;
}

async resolve(token: CancellationToken): Promise<void> {
if (typeof this._provider.resolveInlayHint !== 'function') {
if (typeof this.provider.resolveInlayHint !== 'function') {
return;
}
if (this._currentResolve) {
Expand All @@ -51,7 +51,7 @@ export class InlayHintItem {

private async _doResolve(token: CancellationToken) {
try {
const newHint = await Promise.resolve(this._provider.resolveInlayHint!(this.hint, token));
const newHint = await Promise.resolve(this.provider.resolveInlayHint!(this.hint, token));
this.hint.tooltip = newHint?.tooltip ?? this.hint.tooltip;
this.hint.label = newHint?.label ?? this.hint.label;
this._isResolved = true;
Expand Down
14 changes: 11 additions & 3 deletions src/vs/editor/contrib/inlayHints/browser/inlayHintsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { goToDefinitionWithLocation, showGoToContextMenu } from 'vs/editor/contr
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import * as colors from 'vs/platform/theme/common/colorRegistry';
import { themeColorFromId } from 'vs/platform/theme/common/themeService';

Expand Down Expand Up @@ -254,7 +254,7 @@ export class InlayHintsController implements IEditorContribution {
}
});
gesture.onCancel(removeHighlight);
gesture.onExecute(e => {
gesture.onExecute(async e => {
const label = this._getInlayHintLabelPart(e);
if (label) {
const part = label.part;
Expand All @@ -263,7 +263,15 @@ export class InlayHintsController implements IEditorContribution {
this._instaService.invokeFunction(goToDefinitionWithLocation, e, this._editor as IActiveCodeEditor, part.location);
} else if (languages.Command.is(part.command)) {
// command -> execute it
this._commandService.executeCommand(part.command.id, ...(part.command.arguments ?? [])).catch(err => this._notificationService.error(err));
try {
await this._commandService.executeCommand(part.command.id, ...(part.command.arguments ?? []));
} catch (err) {
this._notificationService.notify({
severity: Severity.Error,
source: label.item.provider.displayName,
message: err
});
}
}
}
});
Expand Down
14 changes: 12 additions & 2 deletions src/vs/editor/contrib/inlayHints/browser/inlayHintsLocations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';

export async function showGoToContextMenu(accessor: ServicesAccessor, editor: ICodeEditor, anchor: HTMLElement, part: RenderedInlayHintLabelPart) {

const resolverService = accessor.get(ITextModelService);
const contextMenuService = accessor.get(IContextMenuService);
const commandService = accessor.get(ICommandService);
const instaService = accessor.get(IInstantiationService);
const notificationService = accessor.get(INotificationService);

await part.item.resolve(CancellationToken.None);

Expand Down Expand Up @@ -60,8 +62,16 @@ export async function showGoToContextMenu(accessor: ServicesAccessor, editor: IC
if (part.part.command) {
const { command } = part.part;
menuActions.push(new Separator());
menuActions.push(new Action(command.id, command.title, undefined, true, () => {
commandService.executeCommand(command.id, ...(command.arguments ?? []));
menuActions.push(new Action(command.id, command.title, undefined, true, async () => {
try {
await commandService.executeCommand(command.id, ...(command.arguments ?? []));
} catch (err) {
notificationService.notify({
severity: Severity.Error,
source: part.item.provider.displayName,
message: err
});
}
}));
}

Expand Down
1 change: 1 addition & 0 deletions src/vs/monaco.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6908,6 +6908,7 @@ declare namespace monaco.languages {
}

export interface InlayHintsProvider {
displayName?: string;
onDidChangeInlayHints?: IEvent<void>;
provideInlayHints(model: editor.ITextModel, range: Range, token: CancellationToken): ProviderResult<InlayHintList>;
resolveInlayHint?(hint: InlayHint, token: CancellationToken): ProviderResult<InlayHint>;
Expand Down
3 changes: 2 additions & 1 deletion src/vs/workbench/api/browser/mainThreadLanguageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,9 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha

// --- inline hints

$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined): void {
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined, displayName: string | undefined): void {
const provider = <modes.InlayHintsProvider>{
displayName,
provideInlayHints: async (model: ITextModel, range: EditorRange, token: CancellationToken): Promise<modes.InlayHintList | undefined> => {
const result = await this._proxy.$provideInlayHints(handle, model.uri, range, token);
if (!result) {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerSuggestSupport(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, displayName: string): void;
$registerInlineCompletionsSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void;
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined): void;
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined, displayName: string | undefined): void;
$emitInlayHintsEvent(eventHandle: number): void;
$registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void;
$registerDocumentColorProvider(handle: number, selector: IDocumentFilterDto[]): void;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHostLanguageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2086,7 +2086,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
const eventHandle = typeof provider.onDidChangeInlayHints === 'function' ? this._nextHandle() : undefined;
const handle = this._addNewAdapter(new InlayHintsAdapter(this._documents, this._commands.converter, provider, this._logService, extension), extension);

this._proxy.$registerInlayHintsProvider(handle, this._transformDocumentSelector(selector), typeof provider.resolveInlayHint === 'function', eventHandle);
this._proxy.$registerInlayHintsProvider(handle, this._transformDocumentSelector(selector), typeof provider.resolveInlayHint === 'function', eventHandle, ExtHostLanguageFeatures._extLabel(extension));
let result = this._createDisposable(handle);

if (eventHandle !== undefined) {
Expand Down

0 comments on commit ffdeff7

Please sign in to comment.