From f9687fc5ec93f8820264ec730da4900366c78f9d Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 8 Feb 2019 20:54:53 -0800 Subject: [PATCH] Strict null work on extHostLanguageFeatures --- src/vs/base/common/types.ts | 2 +- src/vs/vscode.d.ts | 2 +- .../mainThreadLanguageFeatures.ts | 4 +- src/vs/workbench/api/node/extHost.protocol.ts | 30 ++--- src/vs/workbench/api/node/extHostCommands.ts | 12 +- .../workbench/api/node/extHostDocumentData.ts | 2 +- src/vs/workbench/api/node/extHostDocuments.ts | 2 +- .../api/node/extHostDocumentsAndEditors.ts | 8 +- .../api/node/extHostLanguageFeatures.ts | 126 ++++++++++-------- .../api/node/extHostTypeConverters.ts | 4 +- src/vs/workbench/api/node/extHostTypes.ts | 4 +- 11 files changed, 106 insertions(+), 90 deletions(-) diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index ad873be97b1..9dbae8ce1e2 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -49,7 +49,7 @@ export function isStringArray(value: any): value is string[] { * @returns whether the provided parameter is of type `object` but **not** * `null`, an `array`, a `regexp`, nor a `date`. */ -export function isObject(obj: any): boolean { +export function isObject(obj: any): obj is Object { // The method can't do a type cast since there are type (like strings) which // are subclasses of any put not positvely matched by the function. Hence type // narrowing results in wrong results. diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 7fa1945c4b2..ebaf0431533 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -2019,7 +2019,7 @@ declare module 'vscode' { /** * String value of the kind, e.g. `"refactor.extract.function"`. */ - readonly value?: string; + readonly value: string; /** * Create a new kind by appending a more specific selector to the current kind. diff --git a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts index 7a88d4dee39..009f0323c6e 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadLanguageFeatures.ts @@ -111,7 +111,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha $registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], displayName: string): void { this._registrations[handle] = modes.DocumentSymbolProviderRegistry.register(typeConverters.LanguageSelector.from(selector), { displayName, - provideDocumentSymbols: (model: ITextModel, token: CancellationToken): Promise => { + provideDocumentSymbols: (model: ITextModel, token: CancellationToken): Promise => { return this._proxy.$provideDocumentSymbols(handle, model.uri, token); } }); @@ -119,7 +119,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha // --- code lens - $registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number): void { + $registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void { const provider = { provideCodeLenses: (model: ITextModel, token: CancellationToken): modes.ICodeLensSymbol[] | Promise => { diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index a2883df2540..c64f2d0d430 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -298,7 +298,7 @@ export interface ISerializedSignatureHelpProviderMetadata { export interface MainThreadLanguageFeaturesShape extends IDisposable { $unregister(handle: number): void; $registerDocumentSymbolProvider(handle: number, selector: ISerializedDocumentFilter[], label: string): void; - $registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number): void; + $registerCodeLensSupport(handle: number, selector: ISerializedDocumentFilter[], eventHandle: number | undefined): void; $emitCodeLensEvent(eventHandle: number, event?: any): void; $registerDefinitionSupport(handle: number, selector: ISerializedDocumentFilter[]): void; $registerDeclarationSupport(handle: number, selector: ISerializedDocumentFilter[]): void; @@ -893,31 +893,31 @@ export interface CodeLensDto extends ObjectIdentifier { } export interface ExtHostLanguageFeaturesShape { - $provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise; + $provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise; $provideCodeLenses(handle: number, resource: UriComponents, token: CancellationToken): Promise; $resolveCodeLens(handle: number, resource: UriComponents, symbol: CodeLensDto, token: CancellationToken): Promise; $provideDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; $provideDeclaration(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; $provideImplementation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; $provideTypeDefinition(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; - $provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise; - $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise; - $provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise; - $provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise; - $provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise; + $provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise; + $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise; + $provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise; + $provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise; + $provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise; $provideWorkspaceSymbols(handle: number, search: string, token: CancellationToken): Promise; - $resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise; + $resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise; $releaseWorkspaceSymbols(handle: number, id: number): void; - $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise; - $resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; + $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise; + $resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise; $provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.CompletionContext, token: CancellationToken): Promise; $resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, suggestion: modes.CompletionItem, token: CancellationToken): Promise; $releaseCompletionItems(handle: number, id: number): void; - $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise; - $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise; - $resolveDocumentLink(handle: number, link: LinkDto, token: CancellationToken): Promise; + $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise; + $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise; + $resolveDocumentLink(handle: number, link: LinkDto, token: CancellationToken): Promise; $provideDocumentColors(handle: number, resource: UriComponents, token: CancellationToken): Promise; $provideColorPresentations(handle: number, resource: UriComponents, colorInfo: IRawColorInfo, token: CancellationToken): Promise; $provideFoldingRanges(handle: number, resource: UriComponents, context: modes.FoldingContext, token: CancellationToken): Promise; diff --git a/src/vs/workbench/api/node/extHostCommands.ts b/src/vs/workbench/api/node/extHostCommands.ts index 8b73f059351..cc707471087 100644 --- a/src/vs/workbench/api/node/extHostCommands.ts +++ b/src/vs/workbench/api/node/extHostCommands.ts @@ -138,7 +138,11 @@ export class ExtHostCommands implements ExtHostCommandsShape { } private _executeContributedCommand(id: string, args: any[]): Promise { - let { callback, thisArg, description } = this._commands.get(id); + const command = this._commands.get(id); + if (!command) { + throw new Error('Unknown command'); + } + let { callback, thisArg, description } = command; if (description) { for (let i = 0; i < description.args.length; i++) { try { @@ -207,7 +211,7 @@ export class CommandsConverter { this._commands.registerCommand(true, this._delegatingCommandId, this._executeConvertedCommand, this); } - toInternal(command: vscode.Command): CommandDto { + toInternal(command: vscode.Command | undefined): CommandDto | undefined { if (!command) { return undefined; @@ -237,7 +241,7 @@ export class CommandsConverter { return result; } - fromInternal(command: modes.Command): vscode.Command { + fromInternal(command: modes.Command | undefined): vscode.Command | undefined { if (!command) { return undefined; @@ -258,7 +262,7 @@ export class CommandsConverter { private _executeConvertedCommand(...args: any[]): Promise { const actualCmd = this._heap.get(args[0]); - return this._commands.executeCommand(actualCmd.command, ...actualCmd.arguments); + return this._commands.executeCommand(actualCmd.command, ...(actualCmd.arguments || [])); } } diff --git a/src/vs/workbench/api/node/extHostDocumentData.ts b/src/vs/workbench/api/node/extHostDocumentData.ts index d659a17e676..c05dbb6855d 100644 --- a/src/vs/workbench/api/node/extHostDocumentData.ts +++ b/src/vs/workbench/api/node/extHostDocumentData.ts @@ -14,7 +14,7 @@ import { EndOfLine, Position, Range } from 'vs/workbench/api/node/extHostTypes'; import * as vscode from 'vscode'; const _modeId2WordDefinition = new Map(); -export function setWordDefinitionFor(modeId: string, wordDefinition: RegExp): void { +export function setWordDefinitionFor(modeId: string, wordDefinition: RegExp | undefined): void { _modeId2WordDefinition.set(modeId, wordDefinition); } export function getWordDefinitionFor(modeId: string): RegExp | undefined { diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index 5928a917384..dfc39581f84 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -151,7 +151,7 @@ export class ExtHostDocuments implements ExtHostDocumentsShape { }); } - public setWordDefinitionFor(modeId: string, wordDefinition: RegExp): void { + public setWordDefinitionFor(modeId: string, wordDefinition: RegExp | undefined): void { setWordDefinitionFor(modeId, wordDefinition); } } diff --git a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts index bee6279e748..1cf6b396280 100644 --- a/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts +++ b/src/vs/workbench/api/node/extHostDocumentsAndEditors.ts @@ -52,7 +52,9 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha const id = uri.toString(); const data = this._documents.get(id); this._documents.delete(id); - removedDocuments.push(data); + if (data) { + removedDocuments.push(data); + } } } @@ -79,7 +81,9 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha for (const id of delta.removedEditors) { const editor = this._editors.get(id); this._editors.delete(id); - removedEditors.push(editor); + if (editor) { + removedEditors.push(editor); + } } } diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index 72cb8b1f545..9a1f33723b3 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -39,12 +39,12 @@ class DocumentSymbolAdapter { this._provider = provider; } - provideDocumentSymbols(resource: URI, token: CancellationToken): Promise { + provideDocumentSymbols(resource: URI, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); return asPromise(() => this._provider.provideDocumentSymbols(doc, token)).then(value => { if (isFalsyOrEmpty(value)) { return undefined; - } else if (value[0] instanceof DocumentSymbol) { + } else if (value![0] instanceof DocumentSymbol) { return (value).map(typeConvert.DocumentSymbol.from); } else { return DocumentSymbolAdapter._asDocumentSymbolTree(value); @@ -122,18 +122,18 @@ class CodeLensAdapter { }); } - resolveCodeLens(resource: URI, symbol: CodeLensDto, token: CancellationToken): Promise { + resolveCodeLens(resource: URI, symbol: CodeLensDto, token: CancellationToken): Promise { const lens = this._heapService.get(ObjectIdentifier.of(symbol)); if (!lens) { - return undefined; + return Promise.resolve(undefined); } - let resolve: Promise; + let resolve: Promise; if (typeof this._provider.resolveCodeLens !== 'function' || lens.isResolved) { resolve = Promise.resolve(lens); } else { - resolve = asPromise(() => this._provider.resolveCodeLens(lens, token)); + resolve = asPromise(() => this._provider.resolveCodeLens!(lens, token)); } return resolve.then(newLens => { @@ -150,7 +150,7 @@ function convertToLocationLinks(value: vscode.Definition): modes.LocationLink[] } else if (value) { return [typeConvert.DefinitionLink.from(value)]; } - return undefined; + return []; } class DefinitionAdapter { @@ -216,7 +216,7 @@ class HoverAdapter { private readonly _provider: vscode.HoverProvider, ) { } - public provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise { + public provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); let pos = typeConvert.Position.to(position); @@ -244,7 +244,7 @@ class DocumentHighlightAdapter { private readonly _provider: vscode.DocumentHighlightProvider ) { } - provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise { + provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); let pos = typeConvert.Position.to(position); @@ -265,7 +265,7 @@ class ReferenceAdapter { private readonly _provider: vscode.ReferenceProvider ) { } - provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise { + provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); let pos = typeConvert.Position.to(position); @@ -294,7 +294,7 @@ class CodeActionAdapter { private readonly _extensionId: ExtensionIdentifier ) { } - provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { + provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const ran = Selection.isISelection(rangeOrSelection) @@ -317,7 +317,7 @@ class CodeActionAdapter { }; return asPromise(() => this._provider.provideCodeActions(doc, ran, codeActionContext, token)).then(commandsOrActions => { - if (isFalsyOrEmpty(commandsOrActions)) { + if (!isNonEmptyArray(commandsOrActions)) { return undefined; } const result: CustomCodeAction[] = []; @@ -369,7 +369,7 @@ class DocumentFormattingAdapter { private readonly _provider: vscode.DocumentFormattingEditProvider ) { } - provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise { + provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise { const document = this._documents.getDocument(resource); @@ -389,7 +389,7 @@ class RangeFormattingAdapter { private readonly _provider: vscode.DocumentRangeFormattingEditProvider ) { } - provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise { + provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise { const document = this._documents.getDocument(resource); const ran = typeConvert.Range.to(range); @@ -412,7 +412,7 @@ class OnTypeFormattingAdapter { autoFormatTriggerCharacters: string[] = []; // not here - provideOnTypeFormattingEdits(resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise { + provideOnTypeFormattingEdits(resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise { const document = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); @@ -450,7 +450,7 @@ class NavigateTypeAdapter { continue; } const symbol = IdObject.mixin(typeConvert.WorkspaceSymbol.from(item)); - this._symbolCache[symbol._id] = item; + this._symbolCache[symbol._id!] = item; result.symbols.push(symbol); } } @@ -462,19 +462,19 @@ class NavigateTypeAdapter { }); } - resolveWorkspaceSymbol(symbol: WorkspaceSymbolDto, token: CancellationToken): Promise { + resolveWorkspaceSymbol(symbol: WorkspaceSymbolDto, token: CancellationToken): Promise { if (typeof this._provider.resolveWorkspaceSymbol !== 'function') { return Promise.resolve(symbol); } - const item = this._symbolCache[symbol._id]; + const item = this._symbolCache[symbol._id!]; if (item) { - return asPromise(() => this._provider.resolveWorkspaceSymbol(item, token)).then(value => { + return asPromise(() => this._provider.resolveWorkspaceSymbol!(item, token)).then(value => { return value && mixin(symbol, typeConvert.WorkspaceSymbol.from(value), true); }); } - return undefined; + return Promise.resolve(undefined); } releaseWorkspaceSymbols(id: number): any { @@ -512,7 +512,7 @@ class RenameAdapter { }, err => { let rejectReason = RenameAdapter._asMessage(err); if (rejectReason) { - return { rejectReason, edits: undefined }; + return { rejectReason, edits: undefined! }; } else { // generic error return Promise.reject(err); @@ -552,14 +552,14 @@ class RenameAdapter { }, err => { let rejectReason = RenameAdapter._asMessage(err); if (rejectReason) { - return { rejectReason, range: undefined, text: undefined }; + return { rejectReason, range: undefined!, text: undefined! }; } else { return Promise.reject(err); } }); } - private static _asMessage(err: any): string { + private static _asMessage(err: any): string | undefined { if (typeof err === 'string') { return err; } else if (err instanceof Error && typeof err.message === 'string') { @@ -643,12 +643,12 @@ class SuggestAdapter { } const { _parentId, _id } = (suggestion); - const item = this._cache.has(_parentId) && this._cache.get(_parentId)[_id]; + const item = this._cache.has(_parentId) ? this._cache.get(_parentId)![_id] : undefined; if (!item) { return Promise.resolve(suggestion); } - return asPromise(() => this._provider.resolveCompletionItem(item, token)).then(resolvedItem => { + return asPromise(() => this._provider.resolveCompletionItem!(item, token)).then(resolvedItem => { if (!resolvedItem) { return suggestion; @@ -684,7 +684,7 @@ class SuggestAdapter { label: item.label, kind: typeConvert.CompletionItemKind.from(item.kind), detail: item.detail, - documentation: typeConvert.MarkdownString.fromStrict(item.documentation), + documentation: typeof item.documentation === 'undefined' ? undefined : typeConvert.MarkdownString.fromStrict(item.documentation), filterText: item.filterText, sortText: item.sortText, preselect: item.preselect, @@ -740,7 +740,7 @@ class SignatureHelpAdapter { private readonly _heap: ExtHostHeapService, ) { } - provideSignatureHelp(resource: URI, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise { + provideSignatureHelp(resource: URI, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); const vscodeContext = this.reviveContext(context); @@ -779,7 +779,7 @@ class LinkProviderAdapter { private readonly _provider: vscode.DocumentLinkProvider ) { } - provideLinks(resource: URI, token: CancellationToken): Promise { + provideLinks(resource: URI, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); return asPromise(() => this._provider.provideDocumentLinks(doc, token)).then(links => { @@ -796,18 +796,18 @@ class LinkProviderAdapter { }); } - resolveLink(link: LinkDto, token: CancellationToken): Promise { + resolveLink(link: LinkDto, token: CancellationToken): Promise { if (typeof this._provider.resolveDocumentLink !== 'function') { - return undefined; + return Promise.resolve(undefined); } const id = ObjectIdentifier.of(link); const item = this._heapService.get(id); if (!item) { - return undefined; + return Promise.resolve(undefined); } - return asPromise(() => this._provider.resolveDocumentLink(item, token)).then(value => { + return asPromise(() => this._provider.resolveDocumentLink!(item, token)).then(value => { if (value) { return typeConvert.DocumentLink.from(value); } @@ -841,11 +841,14 @@ class ColorProviderAdapter { }); } - provideColorPresentations(resource: URI, raw: IRawColorInfo, token: CancellationToken): Promise { + provideColorPresentations(resource: URI, raw: IRawColorInfo, token: CancellationToken): Promise { const document = this._documents.getDocument(resource); const range = typeConvert.Range.to(raw.range); const color = typeConvert.Color.to(raw.color); return asPromise(() => this._provider.provideColorPresentations(color, { document, range }, token)).then(value => { + if (!Array.isArray(value)) { + return undefined; + } return value.map(typeConvert.ColorPresentation.from); }); } @@ -858,7 +861,7 @@ class FoldingProviderAdapter { private _provider: vscode.FoldingRangeProvider ) { } - provideFoldingRanges(resource: URI, context: modes.FoldingContext, token: CancellationToken): Promise { + provideFoldingRanges(resource: URI, context: modes.FoldingContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); return asPromise(() => this._provider.provideFoldingRanges(doc, context, token)).then(ranges => { if (!Array.isArray(ranges)) { @@ -965,7 +968,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return [this._doTransformDocumentSelector(selector)]; } - private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): ISerializedDocumentFilter { + private _doTransformDocumentSelector(selector: string | vscode.DocumentFilter): ISerializedDocumentFilter | undefined { if (typeof selector === 'string') { return { $serialized: true, @@ -1005,7 +1008,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { } private _withAdapter(handle: number, ctor: { new(...args: any[]): A }, callback: (adapter: A) => Promise): Promise { - let data = this._adapter.get(handle); + const data = this._adapter.get(handle); + if (!data) { + return Promise.reject(new Error('no adapter found')); + } + if (data.adapter instanceof ctor) { let t1: number; if (data.extension) { @@ -1013,11 +1020,12 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { this._logService.trace(`[${data.extension.identifier.value}] INVOKE provider '${(ctor as any).name}'`); } let p = callback(data.adapter); - if (data.extension) { + const extension = data.extension; + if (extension) { Promise.resolve(p).then( - () => this._logService.trace(`[${data.extension.identifier.value}] provider DONE after ${Date.now() - t1}ms`), + () => this._logService.trace(`[${extension.identifier.value}] provider DONE after ${Date.now() - t1}ms`), err => { - this._logService.error(`[${data.extension.identifier.value}] provider FAILED`); + this._logService.error(`[${extension.identifier.value}] provider FAILED`); this._logService.error(err); } ); @@ -1046,7 +1054,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise { + $provideDocumentSymbols(handle: number, resource: UriComponents, token: CancellationToken): Promise { return this._withAdapter(handle, DocumentSymbolAdapter, adapter => adapter.provideDocumentSymbols(URI.revive(resource), token)); } @@ -1061,7 +1069,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { let result = this._createDisposable(handle); if (eventHandle !== undefined) { - const subscription = provider.onDidChangeCodeLenses(_ => this._proxy.$emitCodeLensEvent(eventHandle)); + const subscription = provider.onDidChangeCodeLenses!(_ => this._proxy.$emitCodeLensEvent(eventHandle)); result = Disposable.from(result, subscription); } @@ -1126,7 +1134,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise { + $provideHover(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise { return this._withAdapter(handle, HoverAdapter, adapter => adapter.provideHover(URI.revive(resource), position, token)); } @@ -1138,7 +1146,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise { + $provideDocumentHighlights(handle: number, resource: UriComponents, position: IPosition, token: CancellationToken): Promise { return this._withAdapter(handle, DocumentHighlightAdapter, adapter => adapter.provideDocumentHighlights(URI.revive(resource), position, token)); } @@ -1150,7 +1158,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise { + $provideReferences(handle: number, resource: UriComponents, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise { return this._withAdapter(handle, ReferenceAdapter, adapter => adapter.provideReferences(URI.revive(resource), position, context, token)); } @@ -1158,12 +1166,12 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { registerCodeActionProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CodeActionProvider, metadata?: vscode.CodeActionProviderMetadata): vscode.Disposable { const handle = this._addNewAdapter(new CodeActionAdapter(this._documents, this._commands.converter, this._diagnostics, provider, this._logService, extension.identifier), extension); - this._proxy.$registerQuickFixSupport(handle, this._transformDocumentSelector(selector), metadata && metadata.providedCodeActionKinds ? metadata.providedCodeActionKinds.map(kind => kind.value) : undefined); + this._proxy.$registerQuickFixSupport(handle, this._transformDocumentSelector(selector), (metadata && metadata.providedCodeActionKinds) ? metadata.providedCodeActionKinds.map(kind => kind.value) : undefined); return this._createDisposable(handle); } - $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { + $provideCodeActions(handle: number, resource: UriComponents, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { return this._withAdapter(handle, CodeActionAdapter, adapter => adapter.provideCodeActions(URI.revive(resource), rangeOrSelection, context, token)); } @@ -1175,7 +1183,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise { + $provideDocumentFormattingEdits(handle: number, resource: UriComponents, options: modes.FormattingOptions, token: CancellationToken): Promise { return this._withAdapter(handle, DocumentFormattingAdapter, adapter => adapter.provideDocumentFormattingEdits(URI.revive(resource), options, token)); } @@ -1185,7 +1193,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise { + $provideDocumentRangeFormattingEdits(handle: number, resource: UriComponents, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise { return this._withAdapter(handle, RangeFormattingAdapter, adapter => adapter.provideDocumentRangeFormattingEdits(URI.revive(resource), range, options, token)); } @@ -1195,7 +1203,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise { + $provideOnTypeFormattingEdits(handle: number, resource: UriComponents, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise { return this._withAdapter(handle, OnTypeFormattingAdapter, adapter => adapter.provideOnTypeFormattingEdits(URI.revive(resource), position, ch, options, token)); } @@ -1211,7 +1219,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.provideWorkspaceSymbols(search, token)); } - $resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise { + $resolveWorkspaceSymbol(handle: number, symbol: WorkspaceSymbolDto, token: CancellationToken): Promise { return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.resolveWorkspaceSymbol(symbol, token)); } @@ -1227,11 +1235,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise { + $provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string, token: CancellationToken): Promise { return this._withAdapter(handle, RenameAdapter, adapter => adapter.provideRenameEdits(URI.revive(resource), position, newName, token)); } - $resolveRenameLocation(handle: number, resource: URI, position: IPosition, token: CancellationToken): Promise { + $resolveRenameLocation(handle: number, resource: URI, position: IPosition, token: CancellationToken): Promise { return this._withAdapter(handle, RenameAdapter, adapter => adapter.resolveRenameLocation(URI.revive(resource), position, token)); } @@ -1257,8 +1265,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { // --- parameter hints - registerSignatureHelpProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, metadataOrTriggerChars?: string[] | vscode.SignatureHelpProviderMetadata): vscode.Disposable { - const metadata: ISerializedSignatureHelpProviderMetadata = Array.isArray(metadataOrTriggerChars) + registerSignatureHelpProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.SignatureHelpProvider, metadataOrTriggerChars: string[] | vscode.SignatureHelpProviderMetadata): vscode.Disposable { + const metadata: ISerializedSignatureHelpProviderMetadata | undefined = Array.isArray(metadataOrTriggerChars) ? { triggerCharacters: metadataOrTriggerChars, retriggerCharacters: [] } : metadataOrTriggerChars; @@ -1267,7 +1275,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise { + $provideSignatureHelp(handle: number, resource: UriComponents, position: IPosition, context: modes.SignatureHelpContext, token: CancellationToken): Promise { return this._withAdapter(handle, SignatureHelpAdapter, adapter => adapter.provideSignatureHelp(URI.revive(resource), position, context, token)); } @@ -1279,11 +1287,11 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { return this._createDisposable(handle); } - $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise { + $provideDocumentLinks(handle: number, resource: UriComponents, token: CancellationToken): Promise { return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.provideLinks(URI.revive(resource), token)); } - $resolveDocumentLink(handle: number, link: modes.ILink, token: CancellationToken): Promise { + $resolveDocumentLink(handle: number, link: modes.ILink, token: CancellationToken): Promise { return this._withAdapter(handle, LinkProviderAdapter, adapter => adapter.resolveLink(link, token)); } @@ -1362,7 +1370,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { }; } - private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] { + private static _serializeOnEnterRules(onEnterRules: vscode.OnEnterRule[]): ISerializedOnEnterRule[] | undefined | null { if (typeof onEnterRules === 'undefined') { return undefined; } @@ -1384,7 +1392,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { if (wordPattern) { this._documents.setWordDefinitionFor(languageId, wordPattern); } else { - this._documents.setWordDefinitionFor(languageId, null); + this._documents.setWordDefinitionFor(languageId, undefined); } const handle = this._nextHandle(); diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index 83786a14276..cfe6b70e50f 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -659,7 +659,7 @@ export namespace CompletionContext { export namespace CompletionItemKind { - export function from(kind: types.CompletionItemKind): modes.CompletionItemKind { + export function from(kind: types.CompletionItemKind | undefined): modes.CompletionItemKind { switch (kind) { case types.CompletionItemKind.Method: return modes.CompletionItemKind.Method; case types.CompletionItemKind.Function: return modes.CompletionItemKind.Function; @@ -812,7 +812,7 @@ export namespace DocumentLink { } export function to(link: modes.ILink): vscode.DocumentLink { - return new types.DocumentLink(Range.to(link.range), link.url && URI.parse(link.url)); + return new types.DocumentLink(Range.to(link.range), link.url ? URI.parse(link.url) : undefined); } } diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index f9d1658215e..6fd5b4064d4 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -1365,9 +1365,9 @@ export class DocumentLink { range: Range; - target: URI; + target?: URI; - constructor(range: Range, target: URI) { + constructor(range: Range, target: URI | undefined) { if (target && !(target instanceof URI)) { throw illegalArgument('target'); }