Merge branch 'joh/next' into main

This commit is contained in:
Johannes Rieken 2021-07-02 14:09:27 +02:00
commit 3598075dd0
No known key found for this signature in database
GPG key ID: 96634B5AF12F8798
5 changed files with 308 additions and 272 deletions

View file

@ -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",

View file

@ -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()!;

View file

@ -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);
});
});
});
});

View file

@ -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<modes.DocumentSymbol[] | undefined> {
async provideDocumentSymbols(resource: URI, token: CancellationToken): Promise<modes.DocumentSymbol[] | undefined> {
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 (<DocumentSymbol[]>value).map(typeConvert.DocumentSymbol.from);
} else {
return DocumentSymbolAdapter._asDocumentSymbolTree(<SymbolInformation[]>value);
}
});
const value = await this._provider.provideDocumentSymbols(doc, token);
if (isFalsyOrEmpty(value)) {
return undefined;
} else if (value![0] instanceof DocumentSymbol) {
return (<DocumentSymbol[]>value).map(typeConvert.DocumentSymbol.from);
} else {
return DocumentSymbolAdapter._asDocumentSymbolTree(<SymbolInformation[]>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<modes.LocationLink[]> {
async provideDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
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<modes.LocationLink[]> {
async provideDeclaration(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
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<modes.LocationLink[]> {
async provideImplementation(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
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<modes.LocationLink[]> {
async provideTypeDefinition(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LocationLink[]> {
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<modes.Hover | undefined> {
public async provideHover(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.Hover | undefined> {
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<modes.EvaluatableExpression | undefined> {
async provideEvaluatableExpression(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.EvaluatableExpression | undefined> {
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<modes.InlineValue[] | undefined> {
async provideInlineValues(resource: URI, viewPort: IRange, context: extHostProtocol.IInlineValueContextDto, token: CancellationToken): Promise<modes.InlineValue[] | undefined> {
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<modes.DocumentHighlight[] | undefined> {
async provideDocumentHighlights(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.DocumentHighlight[] | undefined> {
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<modes.LinkedEditingRanges | undefined> {
async provideLinkedEditingRanges(resource: URI, position: IPosition, token: CancellationToken): Promise<modes.LinkedEditingRanges | undefined> {
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<modes.Location[] | undefined> {
async provideReferences(resource: URI, position: IPosition, context: modes.ReferenceContext, token: CancellationToken): Promise<modes.Location[] | undefined> {
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<extHostProtocol.ICodeActionListDto | undefined> {
async provideCodeActions(resource: URI, rangeOrSelection: IRange | ISelection, context: modes.CodeActionContext, token: CancellationToken): Promise<extHostProtocol.ICodeActionListDto | undefined> {
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<extHostProtocol.IWorkspaceEditDto | undefined> {
@ -503,16 +493,15 @@ class DocumentFormattingAdapter {
private readonly _provider: vscode.DocumentFormattingEditProvider
) { }
provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
async provideDocumentFormattingEdits(resource: URI, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
const document = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideDocumentFormattingEdits(document, <any>options, token)).then(value => {
if (Array.isArray(value)) {
return value.map(typeConvert.TextEdit.from);
}
return undefined;
});
const value = await this._provider.provideDocumentFormattingEdits(document, <any>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<ISingleEditOperation[] | undefined> {
async provideDocumentRangeFormattingEdits(resource: URI, range: IRange, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
const document = this._documents.getDocument(resource);
const ran = typeConvert.Range.to(range);
return asPromise(() => this._provider.provideDocumentRangeFormattingEdits(document, ran, <any>options, token)).then(value => {
if (Array.isArray(value)) {
return value.map(typeConvert.TextEdit.from);
}
return undefined;
});
const value = await this._provider.provideDocumentRangeFormattingEdits(document, ran, <any>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<ISingleEditOperation[] | undefined> {
async provideOnTypeFormattingEdits(resource: URI, position: IPosition, ch: string, options: modes.FormattingOptions, token: CancellationToken): Promise<ISingleEditOperation[] | undefined> {
const document = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position);
return asPromise(() => this._provider.provideOnTypeFormattingEdits(document, pos, ch, <any>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, <any>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<extHostProtocol.IWorkspaceSymbolsDto> {
async provideWorkspaceSymbols(search: string, token: CancellationToken): Promise<extHostProtocol.IWorkspaceSymbolsDto> {
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<extHostProtocol.IWorkspaceSymbolDto | undefined> {
@ -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<extHostProtocol.IWorkspaceEditDto | undefined> {
async provideRenameEdits(resource: URI, position: IPosition, newName: string, token: CancellationToken): Promise<extHostProtocol.IWorkspaceEditDto | undefined> {
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 <extHostProtocol.IWorkspaceEditDto>{ rejectReason, edits: undefined! };
@ -650,10 +637,10 @@ class RenameAdapter {
// generic error
return Promise.reject<extHostProtocol.IWorkspaceEditDto>(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 <modes.RenameLocation & modes.Rejection>{ rejectReason, range: undefined!, text: undefined! };
} else {
return Promise.reject<any>(err);
}
});
}
}
private static _asMessage(err: any): string | undefined {
@ -729,24 +718,21 @@ export class DocumentSemanticTokensAdapter {
this._previousResults = new Map<number, SemanticTokensPreviousResult>();
}
provideDocumentSemanticTokens(resource: URI, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null> {
async provideDocumentSemanticTokens(resource: URI, previousResultId: number, token: CancellationToken): Promise<VSBuffer | null> {
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<void> {
@ -863,17 +849,16 @@ export class DocumentRangeSemanticTokensAdapter {
) {
}
provideDocumentRangeSemanticTokens(resource: URI, range: IRange, token: CancellationToken): Promise<VSBuffer | null> {
async provideDocumentRangeSemanticTokens(resource: URI, range: IRange, token: CancellationToken): Promise<VSBuffer | null> {
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<extHostProtocol.ISignatureHelpDto | undefined> {
async provideSignatureHelp(resource: URI, position: IPosition, context: extHostProtocol.ISignatureHelpContextDto, token: CancellationToken): Promise<extHostProtocol.ISignatureHelpDto | undefined> {
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<extHostProtocol.IInlayHintsDto | undefined> {
async provideInlayHints(resource: URI, range: IRange, token: CancellationToken): Promise<extHostProtocol.IInlayHintsDto | undefined> {
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<extHostProtocol.ILinksListDto | undefined> {
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<extHostProtocol.IRawColorInfo[]> {
async provideColors(resource: URI, token: CancellationToken): Promise<extHostProtocol.IRawColorInfo[]> {
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<modes.IColorPresentation[] | undefined> {
async provideColorPresentations(resource: URI, raw: extHostProtocol.IRawColorInfo, token: CancellationToken): Promise<modes.IColorPresentation[] | undefined> {
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<modes.FoldingRange[] | undefined> {
async provideFoldingRanges(resource: URI, context: modes.FoldingContext, token: CancellationToken): Promise<modes.FoldingRange[] | undefined> {
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<modes.SelectionRange[][]> {
async provideSelectionRanges(resource: URI, pos: IPosition[], token: CancellationToken): Promise<modes.SelectionRange[][]> {
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;
}
}

View file

@ -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"