diff --git a/package.json b/package.json index 3513fb0e652..61924a8e35c 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "spdlog": "^0.13.0", "sudo-prompt": "9.2.1", "tas-client-umd": "0.1.4", - "v8-inspect-profiler": "^0.0.21", + "v8-inspect-profiler": "^0.0.22", "vscode-oniguruma": "1.5.1", "vscode-proxy-agent": "^0.11.0", "vscode-regexpp": "^3.1.0", diff --git a/src/vs/editor/contrib/suggest/suggestModel.ts b/src/vs/editor/contrib/suggest/suggestModel.ts index 7089173d954..c6ff958aa6c 100644 --- a/src/vs/editor/contrib/suggest/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/suggestModel.ts @@ -235,6 +235,11 @@ export class SuggestModel implements IDisposable { return; } + if (LineContext.shouldAutoTrigger(this._editor)) { + // don't trigger by trigger characters when this is a case for quick suggest + return; + } + if (!text) { // came here from the compositionEnd-event const position = this._editor.getPosition()!; diff --git a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts index 882e001e735..af9fc5697a1 100644 --- a/src/vs/editor/contrib/suggest/test/suggestModel.test.ts +++ b/src/vs/editor/contrib/suggest/test/suggestModel.test.ts @@ -864,4 +864,59 @@ suite('SuggestModel - TriggerAndCancelOracle', function () { }); }); }); + + test('registerCompletionItemProvider with letters as trigger characters block other completion items to show up #127815', async function () { + + disposables.push(CompletionProviderRegistry.register({ scheme: 'test' }, { + provideCompletionItems(doc, pos) { + return { + suggestions: [{ + kind: CompletionItemKind.Class, + label: 'AAAA', + insertText: 'WordTriggerA', + range: new Range(pos.lineNumber, pos.column, pos.lineNumber, pos.column) + }], + }; + } + })); + disposables.push(CompletionProviderRegistry.register({ scheme: 'test' }, { + triggerCharacters: ['a', '.'], + provideCompletionItems(doc, pos) { + return { + suggestions: [{ + kind: CompletionItemKind.Class, + label: 'AAAA', + insertText: 'AutoTriggerA', + range: new Range(pos.lineNumber, pos.column, pos.lineNumber, pos.column) + }], + }; + }, + })); + + return withOracle(async (model, editor) => { + + await assertEvent(model.onDidSuggest, () => { + editor.setValue(''); + editor.setSelection(new Selection(1, 1, 1, 1)); + editor.trigger('keyboard', Handler.Type, { text: '.' }); + + }, event => { + assert.strictEqual(event.auto, true); + assert.strictEqual(event.completionModel.items.length, 1); + }); + + + editor.getModel().setValue(''); + + await assertEvent(model.onDidSuggest, () => { + editor.setValue(''); + editor.setSelection(new Selection(1, 1, 1, 1)); + editor.trigger('keyboard', Handler.Type, { text: 'a' }); + + }, event => { + assert.strictEqual(event.auto, true); + assert.strictEqual(event.completionModel.items.length, 2); + }); + }); + }); }); diff --git a/src/vs/workbench/api/common/extHostLanguageFeatures.ts b/src/vs/workbench/api/common/extHostLanguageFeatures.ts index f21bb9cd290..d94cfc164de 100644 --- a/src/vs/workbench/api/common/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/common/extHostLanguageFeatures.ts @@ -13,7 +13,6 @@ import * as modes from 'vs/editor/common/modes'; import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; -import { asPromise } from 'vs/base/common/async'; import * as extHostProtocol from './extHost.protocol'; import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings'; import { IPosition } from 'vs/editor/common/core/position'; @@ -47,17 +46,16 @@ class DocumentSymbolAdapter { this._provider = provider; } - provideDocumentSymbols(resource: URI, token: CancellationToken): Promise { + async 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) { - return (value).map(typeConvert.DocumentSymbol.from); - } else { - return DocumentSymbolAdapter._asDocumentSymbolTree(value); - } - }); + const value = await this._provider.provideDocumentSymbols(doc, token); + if (isFalsyOrEmpty(value)) { + return undefined; + } else if (value![0] instanceof DocumentSymbol) { + return (value).map(typeConvert.DocumentSymbol.from); + } else { + return DocumentSymbolAdapter._asDocumentSymbolTree(value); + } } private static _asDocumentSymbolTree(infos: SymbolInformation[]): modes.DocumentSymbol[] { @@ -194,10 +192,11 @@ class DefinitionAdapter { private readonly _provider: vscode.DefinitionProvider ) { } - provideDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise { + async provideDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideDefinition(doc, pos, token)).then(convertToLocationLinks); + const value = await this._provider.provideDefinition(doc, pos, token); + return convertToLocationLinks(value); } } @@ -208,10 +207,11 @@ class DeclarationAdapter { private readonly _provider: vscode.DeclarationProvider ) { } - provideDeclaration(resource: URI, position: IPosition, token: CancellationToken): Promise { + async provideDeclaration(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideDeclaration(doc, pos, token)).then(convertToLocationLinks); + const value = await this._provider.provideDeclaration(doc, pos, token); + return convertToLocationLinks(value); } } @@ -222,10 +222,11 @@ class ImplementationAdapter { private readonly _provider: vscode.ImplementationProvider ) { } - provideImplementation(resource: URI, position: IPosition, token: CancellationToken): Promise { + async provideImplementation(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideImplementation(doc, pos, token)).then(convertToLocationLinks); + const value = await this._provider.provideImplementation(doc, pos, token); + return convertToLocationLinks(value); } } @@ -236,10 +237,11 @@ class TypeDefinitionAdapter { private readonly _provider: vscode.TypeDefinitionProvider ) { } - provideTypeDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise { + async provideTypeDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideTypeDefinition(doc, pos, token)).then(convertToLocationLinks); + const value = await this._provider.provideTypeDefinition(doc, pos, token); + return convertToLocationLinks(value); } } @@ -250,24 +252,22 @@ class HoverAdapter { private readonly _provider: vscode.HoverProvider, ) { } - public provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise { + public async provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideHover(doc, pos, token)).then(value => { - if (!value || isFalsyOrEmpty(value.contents)) { - return undefined; - } - if (!value.range) { - value.range = doc.getWordRangeAtPosition(pos); - } - if (!value.range) { - value.range = new Range(pos, pos); - } - - return typeConvert.Hover.from(value); - }); + const value = await this._provider.provideHover(doc, pos, token); + if (!value || isFalsyOrEmpty(value.contents)) { + return undefined; + } + if (!value.range) { + value.range = doc.getWordRangeAtPosition(pos); + } + if (!value.range) { + value.range = new Range(pos, pos); + } + return typeConvert.Hover.from(value); } } @@ -278,17 +278,16 @@ class EvaluatableExpressionAdapter { private readonly _provider: vscode.EvaluatableExpressionProvider, ) { } - public provideEvaluatableExpression(resource: URI, position: IPosition, token: CancellationToken): Promise { + async provideEvaluatableExpression(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideEvaluatableExpression(doc, pos, token)).then(value => { - if (value) { - return typeConvert.EvaluatableExpression.from(value); - } - return undefined; - }); + const value = await this._provider.provideEvaluatableExpression(doc, pos, token); + if (value) { + return typeConvert.EvaluatableExpression.from(value); + } + return undefined; } } @@ -299,14 +298,13 @@ class InlineValuesAdapter { private readonly _provider: vscode.InlineValuesProvider, ) { } - public provideInlineValues(resource: URI, viewPort: IRange, context: extHostProtocol.IInlineValueContextDto, token: CancellationToken): Promise { + async provideInlineValues(resource: URI, viewPort: IRange, context: extHostProtocol.IInlineValueContextDto, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - return asPromise(() => this._provider.provideInlineValues(doc, typeConvert.Range.to(viewPort), typeConvert.InlineValueContext.to(context), token)).then(value => { - if (Array.isArray(value)) { - return value.map(iv => typeConvert.InlineValue.from(iv)); - } - return undefined; - }); + const value = await this._provider.provideInlineValues(doc, typeConvert.Range.to(viewPort), typeConvert.InlineValueContext.to(context), token); + if (Array.isArray(value)) { + return value.map(iv => typeConvert.InlineValue.from(iv)); + } + return undefined; } } @@ -317,17 +315,16 @@ class DocumentHighlightAdapter { private readonly _provider: vscode.DocumentHighlightProvider ) { } - provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise { + async provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideDocumentHighlights(doc, pos, token)).then(value => { - if (Array.isArray(value)) { - return value.map(typeConvert.DocumentHighlight.from); - } - return undefined; - }); + const value = await this._provider.provideDocumentHighlights(doc, pos, token); + if (Array.isArray(value)) { + return value.map(typeConvert.DocumentHighlight.from); + } + return undefined; } } @@ -337,20 +334,19 @@ class LinkedEditingRangeAdapter { private readonly _provider: vscode.LinkedEditingRangeProvider ) { } - provideLinkedEditingRanges(resource: URI, position: IPosition, token: CancellationToken): Promise { + async provideLinkedEditingRanges(resource: URI, position: IPosition, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideLinkedEditingRanges(doc, pos, token)).then(value => { - if (value && Array.isArray(value.ranges)) { - return { - ranges: coalesce(value.ranges.map(typeConvert.Range.from)), - wordPattern: value.wordPattern - }; - } - return undefined; - }); + const value = await this._provider.provideLinkedEditingRanges(doc, pos, token); + if (value && Array.isArray(value.ranges)) { + return { + ranges: coalesce(value.ranges.map(typeConvert.Range.from)), + wordPattern: value.wordPattern + }; + } + return undefined; } } @@ -361,16 +357,15 @@ class ReferenceAdapter { private readonly _provider: vscode.ReferenceProvider ) { } - provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise { + async provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideReferences(doc, pos, context, token)).then(value => { - if (Array.isArray(value)) { - return value.map(typeConvert.location.from); - } - return undefined; - }); + const value = await this._provider.provideReferences(doc, pos, context, token); + if (Array.isArray(value)) { + return value.map(typeConvert.location.from); + } + return undefined; } } @@ -394,7 +389,7 @@ class CodeActionAdapter { private readonly _apiDeprecation: IExtHostApiDeprecationService, ) { } - provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { + async provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const ran = Selection.isISelection(rangeOrSelection) @@ -417,57 +412,52 @@ class CodeActionAdapter { triggerKind: typeConvert.CodeActionTriggerKind.to(context.trigger), }; - return asPromise(() => this._provider.provideCodeActions(doc, ran, codeActionContext, token)).then((commandsOrActions): extHostProtocol.ICodeActionListDto | undefined => { - if (!isNonEmptyArray(commandsOrActions) || token.isCancellationRequested) { - return undefined; + const commandsOrActions = await this._provider.provideCodeActions(doc, ran, codeActionContext, token); + if (!isNonEmptyArray(commandsOrActions) || token.isCancellationRequested) { + return undefined; + } + const cacheId = this._cache.add(commandsOrActions); + const disposables = new DisposableStore(); + this._disposables.set(cacheId, disposables); + const actions: CustomCodeAction[] = []; + for (let i = 0; i < commandsOrActions.length; i++) { + const candidate = commandsOrActions[i]; + if (!candidate) { + continue; } + if (CodeActionAdapter._isCommand(candidate)) { + // old school: synthetic code action + this._apiDeprecation.report('CodeActionProvider.provideCodeActions - return commands', this._extension, + `Return 'CodeAction' instances instead.`); - const cacheId = this._cache.add(commandsOrActions); - const disposables = new DisposableStore(); - this._disposables.set(cacheId, disposables); - - const actions: CustomCodeAction[] = []; - for (let i = 0; i < commandsOrActions.length; i++) { - const candidate = commandsOrActions[i]; - if (!candidate) { - continue; - } - if (CodeActionAdapter._isCommand(candidate)) { - // old school: synthetic code action - - this._apiDeprecation.report('CodeActionProvider.provideCodeActions - return commands', this._extension, - `Return 'CodeAction' instances instead.`); - - actions.push({ - _isSynthetic: true, - title: candidate.title, - command: this._commands.toInternal(candidate, disposables), - }); - } else { - if (codeActionContext.only) { - if (!candidate.kind) { - this._logService.warn(`${this._extension.identifier.value} - Code actions of kind '${codeActionContext.only.value} 'requested but returned code action does not have a 'kind'. Code action will be dropped. Please set 'CodeAction.kind'.`); - } else if (!codeActionContext.only.contains(candidate.kind)) { - this._logService.warn(`${this._extension.identifier.value} - Code actions of kind '${codeActionContext.only.value} 'requested but returned code action is of kind '${candidate.kind.value}'. Code action will be dropped. Please check 'CodeActionContext.only' to only return requested code actions.`); - } + actions.push({ + _isSynthetic: true, + title: candidate.title, + command: this._commands.toInternal(candidate, disposables), + }); + } else { + if (codeActionContext.only) { + if (!candidate.kind) { + this._logService.warn(`${this._extension.identifier.value} - Code actions of kind '${codeActionContext.only.value} 'requested but returned code action does not have a 'kind'. Code action will be dropped. Please set 'CodeAction.kind'.`); + } else if (!codeActionContext.only.contains(candidate.kind)) { + this._logService.warn(`${this._extension.identifier.value} - Code actions of kind '${codeActionContext.only.value} 'requested but returned code action is of kind '${candidate.kind.value}'. Code action will be dropped. Please check 'CodeActionContext.only' to only return requested code actions.`); } - - // new school: convert code action - actions.push({ - cacheId: [cacheId, i], - title: candidate.title, - command: candidate.command && this._commands.toInternal(candidate.command, disposables), - diagnostics: candidate.diagnostics && candidate.diagnostics.map(typeConvert.Diagnostic.from), - edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit), - kind: candidate.kind && candidate.kind.value, - isPreferred: candidate.isPreferred, - disabled: candidate.disabled?.reason - }); } - } - return { cacheId, actions }; - }); + // new school: convert code action + actions.push({ + cacheId: [cacheId, i], + title: candidate.title, + command: candidate.command && this._commands.toInternal(candidate.command, disposables), + diagnostics: candidate.diagnostics && candidate.diagnostics.map(typeConvert.Diagnostic.from), + edit: candidate.edit && typeConvert.WorkspaceEdit.from(candidate.edit), + kind: candidate.kind && candidate.kind.value, + isPreferred: candidate.isPreferred, + disabled: candidate.disabled?.reason + }); + } + } + return { cacheId, actions }; } public async resolveCodeAction(id: extHostProtocol.ChainedCacheId, token: CancellationToken): Promise { @@ -503,16 +493,15 @@ class DocumentFormattingAdapter { private readonly _provider: vscode.DocumentFormattingEditProvider ) { } - provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise { + async provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise { const document = this._documents.getDocument(resource); - return asPromise(() => this._provider.provideDocumentFormattingEdits(document, options, token)).then(value => { - if (Array.isArray(value)) { - return value.map(typeConvert.TextEdit.from); - } - return undefined; - }); + const value = await this._provider.provideDocumentFormattingEdits(document, options, token); + if (Array.isArray(value)) { + return value.map(typeConvert.TextEdit.from); + } + return undefined; } } @@ -523,17 +512,16 @@ class RangeFormattingAdapter { private readonly _provider: vscode.DocumentRangeFormattingEditProvider ) { } - provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise { + async provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise { const document = this._documents.getDocument(resource); const ran = typeConvert.Range.to(range); - return asPromise(() => this._provider.provideDocumentRangeFormattingEdits(document, ran, options, token)).then(value => { - if (Array.isArray(value)) { - return value.map(typeConvert.TextEdit.from); - } - return undefined; - }); + const value = await this._provider.provideDocumentRangeFormattingEdits(document, ran, options, token); + if (Array.isArray(value)) { + return value.map(typeConvert.TextEdit.from); + } + return undefined; } } @@ -546,17 +534,16 @@ class OnTypeFormattingAdapter { autoFormatTriggerCharacters: string[] = []; // not here - provideOnTypeFormattingEdits(resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise { + async 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); - return asPromise(() => this._provider.provideOnTypeFormattingEdits(document, pos, ch, options, token)).then(value => { - if (Array.isArray(value)) { - return value.map(typeConvert.TextEdit.from); - } - return undefined; - }); + const value = await this._provider.provideOnTypeFormattingEdits(document, pos, ch, options, token); + if (Array.isArray(value)) { + return value.map(typeConvert.TextEdit.from); + } + return undefined; } } @@ -570,30 +557,28 @@ class NavigateTypeAdapter { private readonly _logService: ILogService ) { } - provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { + async provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { const result: extHostProtocol.IWorkspaceSymbolsDto = extHostProtocol.IdObject.mixin({ symbols: [] }); - return asPromise(() => this._provider.provideWorkspaceSymbols(search, token)).then(value => { - if (isNonEmptyArray(value)) { - for (const item of value) { - if (!item) { - // drop - continue; - } - if (!item.name) { - this._logService.warn('INVALID SymbolInformation, lacks name', item); - continue; - } - const symbol = extHostProtocol.IdObject.mixin(typeConvert.WorkspaceSymbol.from(item)); - this._symbolCache.set(symbol._id!, item); - result.symbols.push(symbol); + const value = await this._provider.provideWorkspaceSymbols(search, token); + if (isNonEmptyArray(value)) { + for (const item of value) { + if (!item) { + // drop + continue; } + if (!item.name) { + this._logService.warn('INVALID SymbolInformation, lacks name', item); + continue; + } + const symbol = extHostProtocol.IdObject.mixin(typeConvert.WorkspaceSymbol.from(item)); + this._symbolCache.set(symbol._id!, item); + result.symbols.push(symbol); } - }).then(() => { - if (result.symbols.length > 0) { - this._resultCache.set(result._id!, [result.symbols[0]._id!, result.symbols[result.symbols.length - 1]._id!]); - } - return result; - }); + } + if (result.symbols.length > 0) { + this._resultCache.set(result._id!, [result.symbols[0]._id!, result.symbols[result.symbols.length - 1]._id!]); + } + return result; } async resolveWorkspaceSymbol(symbol: extHostProtocol.IWorkspaceSymbolDto, token: CancellationToken): Promise { @@ -603,7 +588,7 @@ class NavigateTypeAdapter { const item = this._symbolCache.get(symbol._id!); if (item) { - const value = await asPromise(() => this._provider.resolveWorkspaceSymbol!(item, token)); + const value = await this._provider.resolveWorkspaceSymbol(item, token); return value && mixin(symbol, typeConvert.WorkspaceSymbol.from(value), true); } return undefined; @@ -632,17 +617,19 @@ class RenameAdapter { private readonly _logService: ILogService ) { } - provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise { + async provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.provideRenameEdits(doc, pos, newName, token)).then(value => { + try { + const value = await this._provider.provideRenameEdits(doc, pos, newName, token); if (!value) { return undefined; } return typeConvert.WorkspaceEdit.from(value); - }, err => { + + } catch (err) { const rejectReason = RenameAdapter._asMessage(err); if (rejectReason) { return { rejectReason, edits: undefined! }; @@ -650,10 +637,10 @@ class RenameAdapter { // generic error return Promise.reject(err); } - }); + } } - resolveRenameLocation(resource: URI, position: IPosition, token: CancellationToken): Promise<(modes.RenameLocation & modes.Rejection) | undefined> { + async resolveRenameLocation(resource: URI, position: IPosition, token: CancellationToken): Promise<(modes.RenameLocation & modes.Rejection) | undefined> { if (typeof this._provider.prepareRename !== 'function') { return Promise.resolve(undefined); } @@ -661,7 +648,8 @@ class RenameAdapter { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - return asPromise(() => this._provider.prepareRename!(doc, pos, token)).then(rangeOrLocation => { + try { + const rangeOrLocation = await this._provider.prepareRename(doc, pos, token); let range: vscode.Range | undefined; let text: string | undefined; @@ -674,7 +662,7 @@ class RenameAdapter { text = rangeOrLocation.placeholder; } - if (!range) { + if (!range || !text) { return undefined; } if (range.start.line > pos.line || range.end.line < pos.line) { @@ -682,14 +670,15 @@ class RenameAdapter { return undefined; } return { range: typeConvert.Range.from(range), text }; - }, err => { + + } catch (err) { const rejectReason = RenameAdapter._asMessage(err); if (rejectReason) { return { rejectReason, range: undefined!, text: undefined! }; } else { return Promise.reject(err); } - }); + } } private static _asMessage(err: any): string | undefined { @@ -729,24 +718,21 @@ export class DocumentSemanticTokensAdapter { this._previousResults = new Map(); } - provideDocumentSemanticTokens(resource: URI, previousResultId: number, token: CancellationToken): Promise { + async provideDocumentSemanticTokens(resource: URI, previousResultId: number, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const previousResult = (previousResultId !== 0 ? this._previousResults.get(previousResultId) : null); - return asPromise(() => { - if (previousResult && typeof previousResult.resultId === 'string' && typeof this._provider.provideDocumentSemanticTokensEdits === 'function') { - return this._provider.provideDocumentSemanticTokensEdits(doc, previousResult.resultId, token); - } - return this._provider.provideDocumentSemanticTokens(doc, token); - }).then((value: ProvidedSemanticTokens | ProvidedSemanticTokensEdits | null | undefined) => { - if (previousResult) { - this._previousResults.delete(previousResultId); - } - if (!value) { - return null; - } - value = DocumentSemanticTokensAdapter._fixProvidedSemanticTokens(value); - return this._send(DocumentSemanticTokensAdapter._convertToEdits(previousResult, value), value); - }); + let value = typeof previousResult?.resultId === 'string' && typeof this._provider.provideDocumentSemanticTokensEdits === 'function' + ? await this._provider.provideDocumentSemanticTokensEdits(doc, previousResult.resultId, token) + : await this._provider.provideDocumentSemanticTokens(doc, token); + + if (previousResult) { + this._previousResults.delete(previousResultId); + } + if (!value) { + return null; + } + value = DocumentSemanticTokensAdapter._fixProvidedSemanticTokens(value); + return this._send(DocumentSemanticTokensAdapter._convertToEdits(previousResult, value), value); } async releaseDocumentSemanticColoring(semanticColoringResultId: number): Promise { @@ -863,17 +849,16 @@ export class DocumentRangeSemanticTokensAdapter { ) { } - provideDocumentRangeSemanticTokens(resource: URI, range: IRange, token: CancellationToken): Promise { + async provideDocumentRangeSemanticTokens(resource: URI, range: IRange, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - return asPromise(() => this._provider.provideDocumentRangeSemanticTokens(doc, typeConvert.Range.to(range), token)).then(value => { - if (!value) { - return null; - } - return this._send(value); - }); + const value = await this._provider.provideDocumentRangeSemanticTokens(doc, typeConvert.Range.to(range), token); + if (!value) { + return null; + } + return this._send(value); } - private _send(value: vscode.SemanticTokens): VSBuffer | null { + private _send(value: vscode.SemanticTokens): VSBuffer { return encodeSemanticTokensDto({ id: 0, type: 'full', @@ -911,7 +896,7 @@ class SuggestAdapter { const insertRange = replaceRange.with({ end: pos }); const sw = new StopWatch(true); - const itemsOrList = await asPromise(() => this._provider.provideCompletionItems(doc, pos, token, typeConvert.CompletionContext.to(context))); + const itemsOrList = await this._provider.provideCompletionItems(doc, pos, token, typeConvert.CompletionContext.to(context)); if (!itemsOrList) { // undefined and null are valid results @@ -961,7 +946,7 @@ class SuggestAdapter { return undefined; } - const resolvedItem = await asPromise(() => this._provider.resolveCompletionItem!(item, token)); + const resolvedItem = await this._provider.resolveCompletionItem!(item, token); if (!resolvedItem) { return undefined; @@ -1052,7 +1037,7 @@ class InlineCompletionAdapter { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); - const result = await asPromise(() => this._provider.provideInlineCompletionItems(doc, pos, context, token)); + const result = await this._provider.provideInlineCompletionItems(doc, pos, context, token); if (!result) { // undefined and null are valid results @@ -1140,18 +1125,17 @@ class SignatureHelpAdapter { private readonly _provider: vscode.SignatureHelpProvider, ) { } - provideSignatureHelp(resource: URI, position: IPosition, context: extHostProtocol.ISignatureHelpContextDto, token: CancellationToken): Promise { + async provideSignatureHelp(resource: URI, position: IPosition, context: extHostProtocol.ISignatureHelpContextDto, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); const pos = typeConvert.Position.to(position); const vscodeContext = this.reviveContext(context); - return asPromise(() => this._provider.provideSignatureHelp(doc, pos, token, vscodeContext)).then(value => { - if (value) { - const id = this._cache.add([value]); - return { ...typeConvert.SignatureHelp.from(value), id }; - } - return undefined; - }); + const value = await this._provider.provideSignatureHelp(doc, pos, token, vscodeContext); + if (value) { + const id = this._cache.add([value]); + return { ...typeConvert.SignatureHelp.from(value), id }; + } + return undefined; } private reviveContext(context: extHostProtocol.ISignatureHelpContextDto): vscode.SignatureHelpContext { @@ -1181,11 +1165,10 @@ class InlayHintsAdapter { private readonly _provider: vscode.InlayHintsProvider, ) { } - provideInlayHints(resource: URI, range: IRange, token: CancellationToken): Promise { + async provideInlayHints(resource: URI, range: IRange, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - return asPromise(() => this._provider.provideInlayHints(doc, typeConvert.Range.to(range), token)).then(value => { - return value ? { hints: value.map(typeConvert.InlayHint.from) } : undefined; - }); + const value = await this._provider.provideInlayHints(doc, typeConvert.Range.to(range), token); + return value ? { hints: value.map(typeConvert.InlayHint.from) } : undefined; } } @@ -1201,7 +1184,7 @@ class LinkProviderAdapter { async provideLinks(resource: URI, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - const links = await asPromise(() => this._provider.provideDocumentLinks(doc, token)); + const links = await this._provider.provideDocumentLinks(doc, token); if (!Array.isArray(links) || links.length === 0) { // bad result return undefined; @@ -1249,7 +1232,7 @@ class LinkProviderAdapter { if (!item) { return undefined; } - const link = await asPromise(() => this._provider.resolveDocumentLink!(item, token)); + const link = await this._provider.resolveDocumentLink!(item, token); if (!link || !LinkProviderAdapter._validateLink(link)) { return undefined; } @@ -1268,34 +1251,30 @@ class ColorProviderAdapter { private _provider: vscode.DocumentColorProvider ) { } - provideColors(resource: URI, token: CancellationToken): Promise { + async provideColors(resource: URI, token: CancellationToken): Promise { const doc = this._documents.getDocument(resource); - return asPromise(() => this._provider.provideDocumentColors(doc, token)).then(colors => { - if (!Array.isArray(colors)) { - return []; - } - - const colorInfos: extHostProtocol.IRawColorInfo[] = colors.map(ci => { - return { - color: typeConvert.Color.from(ci.color), - range: typeConvert.Range.from(ci.range) - }; - }); - - return colorInfos; + const colors = await this._provider.provideDocumentColors(doc, token); + if (!Array.isArray(colors)) { + return []; + } + const colorInfos: extHostProtocol.IRawColorInfo[] = colors.map(ci => { + return { + color: typeConvert.Color.from(ci.color), + range: typeConvert.Range.from(ci.range) + }; }); + return colorInfos; } - provideColorPresentations(resource: URI, raw: extHostProtocol.IRawColorInfo, token: CancellationToken): Promise { + async provideColorPresentations(resource: URI, raw: extHostProtocol.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); - }); + const value = await this._provider.provideColorPresentations(color, { document, range }, token); + if (!Array.isArray(value)) { + return undefined; + } + return value.map(typeConvert.ColorPresentation.from); } } @@ -1306,14 +1285,13 @@ class FoldingProviderAdapter { private _provider: vscode.FoldingRangeProvider ) { } - provideFoldingRanges(resource: URI, context: modes.FoldingContext, token: CancellationToken): Promise { + async 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)) { - return undefined; - } - return ranges.map(typeConvert.FoldingRange.from); - }); + const ranges = await this._provider.provideFoldingRanges(doc, context, token); + if (!Array.isArray(ranges)) { + return undefined; + } + return ranges.map(typeConvert.FoldingRange.from); } } @@ -1325,41 +1303,39 @@ class SelectionRangeAdapter { private readonly _logService: ILogService ) { } - provideSelectionRanges(resource: URI, pos: IPosition[], token: CancellationToken): Promise { + async provideSelectionRanges(resource: URI, pos: IPosition[], token: CancellationToken): Promise { const document = this._documents.getDocument(resource); const positions = pos.map(typeConvert.Position.to); - return asPromise(() => this._provider.provideSelectionRanges(document, positions, token)).then(allProviderRanges => { - if (!isNonEmptyArray(allProviderRanges)) { - return []; - } - if (allProviderRanges.length !== positions.length) { - this._logService.warn('BAD selection ranges, provider must return ranges for each position'); - return []; - } + const allProviderRanges = await this._provider.provideSelectionRanges(document, positions, token); + if (!isNonEmptyArray(allProviderRanges)) { + return []; + } + if (allProviderRanges.length !== positions.length) { + this._logService.warn('BAD selection ranges, provider must return ranges for each position'); + return []; + } + const allResults: modes.SelectionRange[][] = []; + for (let i = 0; i < positions.length; i++) { + const oneResult: modes.SelectionRange[] = []; + allResults.push(oneResult); - const allResults: modes.SelectionRange[][] = []; - for (let i = 0; i < positions.length; i++) { - const oneResult: modes.SelectionRange[] = []; - allResults.push(oneResult); + let last: vscode.Position | vscode.Range = positions[i]; + let selectionRange = allProviderRanges[i]; - let last: vscode.Position | vscode.Range = positions[i]; - let selectionRange = allProviderRanges[i]; - - while (true) { - if (!selectionRange.range.contains(last)) { - throw new Error('INVALID selection range, must contain the previous range'); - } - oneResult.push(typeConvert.SelectionRange.from(selectionRange)); - if (!selectionRange.parent) { - break; - } - last = selectionRange.range; - selectionRange = selectionRange.parent; + while (true) { + if (!selectionRange.range.contains(last)) { + throw new Error('INVALID selection range, must contain the previous range'); } + oneResult.push(typeConvert.SelectionRange.from(selectionRange)); + if (!selectionRange.parent) { + break; + } + last = selectionRange.range; + selectionRange = selectionRange.parent; } - return allResults; - }); + } + return allResults; } } diff --git a/yarn.lock b/yarn.lock index 62c3a19de68..d3bb4bbfb18 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9819,10 +9819,10 @@ v8-compile-cache@^2.0.3, v8-compile-cache@^2.1.1: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== -v8-inspect-profiler@^0.0.21: - version "0.0.21" - resolved "https://registry.yarnpkg.com/v8-inspect-profiler/-/v8-inspect-profiler-0.0.21.tgz#2ded4fd59508f52d5887d3ae2bbace3e33509c41" - integrity sha512-6lo22vhua2Zg2Cq8Wtc2FELlTA+pmu+5epyPX65jNVAbAoKXY/XI3t33CreYiK8THKgkMeoWeviAxcJaefjyrg== +v8-inspect-profiler@^0.0.22: + version "0.0.22" + resolved "https://registry.yarnpkg.com/v8-inspect-profiler/-/v8-inspect-profiler-0.0.22.tgz#34d3ba35a965c437ed28279d31cd42d7698a4002" + integrity sha512-r2p7UkbFlFopAWUVprbECP+EpdjuEKPFQLhqpnHx9KxeTTLVaHuGpUNHye53MtYMoJFl9nJiMyIM7J2yY+dTQg== dependencies: chrome-remote-interface "0.28.2"