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", "spdlog": "^0.13.0",
"sudo-prompt": "9.2.1", "sudo-prompt": "9.2.1",
"tas-client-umd": "0.1.4", "tas-client-umd": "0.1.4",
"v8-inspect-profiler": "^0.0.21", "v8-inspect-profiler": "^0.0.22",
"vscode-oniguruma": "1.5.1", "vscode-oniguruma": "1.5.1",
"vscode-proxy-agent": "^0.11.0", "vscode-proxy-agent": "^0.11.0",
"vscode-regexpp": "^3.1.0", "vscode-regexpp": "^3.1.0",

View file

@ -235,6 +235,11 @@ export class SuggestModel implements IDisposable {
return; return;
} }
if (LineContext.shouldAutoTrigger(this._editor)) {
// don't trigger by trigger characters when this is a case for quick suggest
return;
}
if (!text) { if (!text) {
// came here from the compositionEnd-event // came here from the compositionEnd-event
const position = this._editor.getPosition()!; 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 { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands'; import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics'; import { ExtHostDiagnostics } from 'vs/workbench/api/common/extHostDiagnostics';
import { asPromise } from 'vs/base/common/async';
import * as extHostProtocol from './extHost.protocol'; import * as extHostProtocol from './extHost.protocol';
import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings'; import { regExpLeadsToEndlessLoop, regExpFlags } from 'vs/base/common/strings';
import { IPosition } from 'vs/editor/common/core/position'; import { IPosition } from 'vs/editor/common/core/position';
@ -47,17 +46,16 @@ class DocumentSymbolAdapter {
this._provider = provider; 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); const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideDocumentSymbols(doc, token)).then(value => { const value = await this._provider.provideDocumentSymbols(doc, token);
if (isFalsyOrEmpty(value)) { if (isFalsyOrEmpty(value)) {
return undefined; return undefined;
} else if (value![0] instanceof DocumentSymbol) { } else if (value![0] instanceof DocumentSymbol) {
return (<DocumentSymbol[]>value).map(typeConvert.DocumentSymbol.from); return (<DocumentSymbol[]>value).map(typeConvert.DocumentSymbol.from);
} else { } else {
return DocumentSymbolAdapter._asDocumentSymbolTree(<SymbolInformation[]>value); return DocumentSymbolAdapter._asDocumentSymbolTree(<SymbolInformation[]>value);
} }
});
} }
private static _asDocumentSymbolTree(infos: SymbolInformation[]): modes.DocumentSymbol[] { private static _asDocumentSymbolTree(infos: SymbolInformation[]): modes.DocumentSymbol[] {
@ -194,10 +192,11 @@ class DefinitionAdapter {
private readonly _provider: vscode.DefinitionProvider 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); 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 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); 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 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); 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 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); 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, 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
return asPromise(() => this._provider.provideHover(doc, pos, token)).then(value => { const value = await this._provider.provideHover(doc, pos, token);
if (!value || isFalsyOrEmpty(value.contents)) { if (!value || isFalsyOrEmpty(value.contents)) {
return undefined; return undefined;
} }
if (!value.range) { if (!value.range) {
value.range = doc.getWordRangeAtPosition(pos); value.range = doc.getWordRangeAtPosition(pos);
} }
if (!value.range) { if (!value.range) {
value.range = new Range(pos, pos); value.range = new Range(pos, pos);
} }
return typeConvert.Hover.from(value);
return typeConvert.Hover.from(value);
});
} }
} }
@ -278,17 +278,16 @@ class EvaluatableExpressionAdapter {
private readonly _provider: vscode.EvaluatableExpressionProvider, 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
return asPromise(() => this._provider.provideEvaluatableExpression(doc, pos, token)).then(value => { const value = await this._provider.provideEvaluatableExpression(doc, pos, token);
if (value) { if (value) {
return typeConvert.EvaluatableExpression.from(value); return typeConvert.EvaluatableExpression.from(value);
} }
return undefined; return undefined;
});
} }
} }
@ -299,14 +298,13 @@ class InlineValuesAdapter {
private readonly _provider: vscode.InlineValuesProvider, 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); const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideInlineValues(doc, typeConvert.Range.to(viewPort), typeConvert.InlineValueContext.to(context), token)).then(value => { const value = await this._provider.provideInlineValues(doc, typeConvert.Range.to(viewPort), typeConvert.InlineValueContext.to(context), token);
if (Array.isArray(value)) { if (Array.isArray(value)) {
return value.map(iv => typeConvert.InlineValue.from(iv)); return value.map(iv => typeConvert.InlineValue.from(iv));
} }
return undefined; return undefined;
});
} }
} }
@ -317,17 +315,16 @@ class DocumentHighlightAdapter {
private readonly _provider: vscode.DocumentHighlightProvider 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
return asPromise(() => this._provider.provideDocumentHighlights(doc, pos, token)).then(value => { const value = await this._provider.provideDocumentHighlights(doc, pos, token);
if (Array.isArray(value)) { if (Array.isArray(value)) {
return value.map(typeConvert.DocumentHighlight.from); return value.map(typeConvert.DocumentHighlight.from);
} }
return undefined; return undefined;
});
} }
} }
@ -337,20 +334,19 @@ class LinkedEditingRangeAdapter {
private readonly _provider: vscode.LinkedEditingRangeProvider 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
return asPromise(() => this._provider.provideLinkedEditingRanges(doc, pos, token)).then(value => { const value = await this._provider.provideLinkedEditingRanges(doc, pos, token);
if (value && Array.isArray(value.ranges)) { if (value && Array.isArray(value.ranges)) {
return { return {
ranges: coalesce(value.ranges.map(typeConvert.Range.from)), ranges: coalesce(value.ranges.map(typeConvert.Range.from)),
wordPattern: value.wordPattern wordPattern: value.wordPattern
}; };
} }
return undefined; return undefined;
});
} }
} }
@ -361,16 +357,15 @@ class ReferenceAdapter {
private readonly _provider: vscode.ReferenceProvider 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
return asPromise(() => this._provider.provideReferences(doc, pos, context, token)).then(value => { const value = await this._provider.provideReferences(doc, pos, context, token);
if (Array.isArray(value)) { if (Array.isArray(value)) {
return value.map(typeConvert.location.from); return value.map(typeConvert.location.from);
} }
return undefined; return undefined;
});
} }
} }
@ -394,7 +389,7 @@ class CodeActionAdapter {
private readonly _apiDeprecation: IExtHostApiDeprecationService, 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 doc = this._documents.getDocument(resource);
const ran = Selection.isISelection(rangeOrSelection) const ran = Selection.isISelection(rangeOrSelection)
@ -417,57 +412,52 @@ class CodeActionAdapter {
triggerKind: typeConvert.CodeActionTriggerKind.to(context.trigger), triggerKind: typeConvert.CodeActionTriggerKind.to(context.trigger),
}; };
return asPromise(() => this._provider.provideCodeActions(doc, ran, codeActionContext, token)).then((commandsOrActions): extHostProtocol.ICodeActionListDto | undefined => { const commandsOrActions = await this._provider.provideCodeActions(doc, ran, codeActionContext, token);
if (!isNonEmptyArray(commandsOrActions) || token.isCancellationRequested) { if (!isNonEmptyArray(commandsOrActions) || token.isCancellationRequested) {
return undefined; 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); actions.push({
const disposables = new DisposableStore(); _isSynthetic: true,
this._disposables.set(cacheId, disposables); title: candidate.title,
command: this._commands.toInternal(candidate, disposables),
const actions: CustomCodeAction[] = []; });
for (let i = 0; i < commandsOrActions.length; i++) { } else {
const candidate = commandsOrActions[i]; if (codeActionContext.only) {
if (!candidate) { if (!candidate.kind) {
continue; 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)) {
if (CodeActionAdapter._isCommand(candidate)) { 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.`);
// 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.`);
}
} }
// 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> { public async resolveCodeAction(id: extHostProtocol.ChainedCacheId, token: CancellationToken): Promise<extHostProtocol.IWorkspaceEditDto | undefined> {
@ -503,16 +493,15 @@ class DocumentFormattingAdapter {
private readonly _provider: vscode.DocumentFormattingEditProvider 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); const document = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideDocumentFormattingEdits(document, <any>options, token)).then(value => { const value = await this._provider.provideDocumentFormattingEdits(document, <any>options, token);
if (Array.isArray(value)) { if (Array.isArray(value)) {
return value.map(typeConvert.TextEdit.from); return value.map(typeConvert.TextEdit.from);
} }
return undefined; return undefined;
});
} }
} }
@ -523,17 +512,16 @@ class RangeFormattingAdapter {
private readonly _provider: vscode.DocumentRangeFormattingEditProvider 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 document = this._documents.getDocument(resource);
const ran = typeConvert.Range.to(range); const ran = typeConvert.Range.to(range);
return asPromise(() => this._provider.provideDocumentRangeFormattingEdits(document, ran, <any>options, token)).then(value => { const value = await this._provider.provideDocumentRangeFormattingEdits(document, ran, <any>options, token);
if (Array.isArray(value)) { if (Array.isArray(value)) {
return value.map(typeConvert.TextEdit.from); return value.map(typeConvert.TextEdit.from);
} }
return undefined; return undefined;
});
} }
} }
@ -546,17 +534,16 @@ class OnTypeFormattingAdapter {
autoFormatTriggerCharacters: string[] = []; // not here 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 document = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
return asPromise(() => this._provider.provideOnTypeFormattingEdits(document, pos, ch, <any>options, token)).then(value => { const value = await this._provider.provideOnTypeFormattingEdits(document, pos, ch, <any>options, token);
if (Array.isArray(value)) { if (Array.isArray(value)) {
return value.map(typeConvert.TextEdit.from); return value.map(typeConvert.TextEdit.from);
} }
return undefined; return undefined;
});
} }
} }
@ -570,30 +557,28 @@ class NavigateTypeAdapter {
private readonly _logService: ILogService 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: [] }); const result: extHostProtocol.IWorkspaceSymbolsDto = extHostProtocol.IdObject.mixin({ symbols: [] });
return asPromise(() => this._provider.provideWorkspaceSymbols(search, token)).then(value => { const value = await this._provider.provideWorkspaceSymbols(search, token);
if (isNonEmptyArray(value)) { if (isNonEmptyArray(value)) {
for (const item of value) { for (const item of value) {
if (!item) { if (!item) {
// drop // drop
continue; 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);
} }
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) { if (result.symbols.length > 0) {
this._resultCache.set(result._id!, [result.symbols[0]._id!, result.symbols[result.symbols.length - 1]._id!]); this._resultCache.set(result._id!, [result.symbols[0]._id!, result.symbols[result.symbols.length - 1]._id!]);
} }
return result; return result;
});
} }
async resolveWorkspaceSymbol(symbol: extHostProtocol.IWorkspaceSymbolDto, token: CancellationToken): Promise<extHostProtocol.IWorkspaceSymbolDto | undefined> { async resolveWorkspaceSymbol(symbol: extHostProtocol.IWorkspaceSymbolDto, token: CancellationToken): Promise<extHostProtocol.IWorkspaceSymbolDto | undefined> {
@ -603,7 +588,7 @@ class NavigateTypeAdapter {
const item = this._symbolCache.get(symbol._id!); const item = this._symbolCache.get(symbol._id!);
if (item) { 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 value && mixin(symbol, typeConvert.WorkspaceSymbol.from(value), true);
} }
return undefined; return undefined;
@ -632,17 +617,19 @@ class RenameAdapter {
private readonly _logService: ILogService 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); 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) { if (!value) {
return undefined; return undefined;
} }
return typeConvert.WorkspaceEdit.from(value); return typeConvert.WorkspaceEdit.from(value);
}, err => {
} catch (err) {
const rejectReason = RenameAdapter._asMessage(err); const rejectReason = RenameAdapter._asMessage(err);
if (rejectReason) { if (rejectReason) {
return <extHostProtocol.IWorkspaceEditDto>{ rejectReason, edits: undefined! }; return <extHostProtocol.IWorkspaceEditDto>{ rejectReason, edits: undefined! };
@ -650,10 +637,10 @@ class RenameAdapter {
// generic error // generic error
return Promise.reject<extHostProtocol.IWorkspaceEditDto>(err); 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') { if (typeof this._provider.prepareRename !== 'function') {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
@ -661,7 +648,8 @@ class RenameAdapter {
const doc = this._documents.getDocument(resource); const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); 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 range: vscode.Range | undefined;
let text: string | undefined; let text: string | undefined;
@ -674,7 +662,7 @@ class RenameAdapter {
text = rangeOrLocation.placeholder; text = rangeOrLocation.placeholder;
} }
if (!range) { if (!range || !text) {
return undefined; return undefined;
} }
if (range.start.line > pos.line || range.end.line < pos.line) { if (range.start.line > pos.line || range.end.line < pos.line) {
@ -682,14 +670,15 @@ class RenameAdapter {
return undefined; return undefined;
} }
return { range: typeConvert.Range.from(range), text }; return { range: typeConvert.Range.from(range), text };
}, err => {
} catch (err) {
const rejectReason = RenameAdapter._asMessage(err); const rejectReason = RenameAdapter._asMessage(err);
if (rejectReason) { if (rejectReason) {
return <modes.RenameLocation & modes.Rejection>{ rejectReason, range: undefined!, text: undefined! }; return <modes.RenameLocation & modes.Rejection>{ rejectReason, range: undefined!, text: undefined! };
} else { } else {
return Promise.reject<any>(err); return Promise.reject<any>(err);
} }
}); }
} }
private static _asMessage(err: any): string | undefined { private static _asMessage(err: any): string | undefined {
@ -729,24 +718,21 @@ export class DocumentSemanticTokensAdapter {
this._previousResults = new Map<number, SemanticTokensPreviousResult>(); 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 doc = this._documents.getDocument(resource);
const previousResult = (previousResultId !== 0 ? this._previousResults.get(previousResultId) : null); const previousResult = (previousResultId !== 0 ? this._previousResults.get(previousResultId) : null);
return asPromise(() => { let value = typeof previousResult?.resultId === 'string' && typeof this._provider.provideDocumentSemanticTokensEdits === 'function'
if (previousResult && typeof previousResult.resultId === 'string' && typeof this._provider.provideDocumentSemanticTokensEdits === 'function') { ? await this._provider.provideDocumentSemanticTokensEdits(doc, previousResult.resultId, token)
return this._provider.provideDocumentSemanticTokensEdits(doc, previousResult.resultId, token); : await this._provider.provideDocumentSemanticTokens(doc, token);
}
return this._provider.provideDocumentSemanticTokens(doc, token); if (previousResult) {
}).then((value: ProvidedSemanticTokens | ProvidedSemanticTokensEdits | null | undefined) => { this._previousResults.delete(previousResultId);
if (previousResult) { }
this._previousResults.delete(previousResultId); if (!value) {
} return null;
if (!value) { }
return null; value = DocumentSemanticTokensAdapter._fixProvidedSemanticTokens(value);
} return this._send(DocumentSemanticTokensAdapter._convertToEdits(previousResult, value), value);
value = DocumentSemanticTokensAdapter._fixProvidedSemanticTokens(value);
return this._send(DocumentSemanticTokensAdapter._convertToEdits(previousResult, value), value);
});
} }
async releaseDocumentSemanticColoring(semanticColoringResultId: number): Promise<void> { 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); const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideDocumentRangeSemanticTokens(doc, typeConvert.Range.to(range), token)).then(value => { const value = await this._provider.provideDocumentRangeSemanticTokens(doc, typeConvert.Range.to(range), token);
if (!value) { if (!value) {
return null; return null;
} }
return this._send(value); return this._send(value);
});
} }
private _send(value: vscode.SemanticTokens): VSBuffer | null { private _send(value: vscode.SemanticTokens): VSBuffer {
return encodeSemanticTokensDto({ return encodeSemanticTokensDto({
id: 0, id: 0,
type: 'full', type: 'full',
@ -911,7 +896,7 @@ class SuggestAdapter {
const insertRange = replaceRange.with({ end: pos }); const insertRange = replaceRange.with({ end: pos });
const sw = new StopWatch(true); 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) { if (!itemsOrList) {
// undefined and null are valid results // undefined and null are valid results
@ -961,7 +946,7 @@ class SuggestAdapter {
return undefined; return undefined;
} }
const resolvedItem = await asPromise(() => this._provider.resolveCompletionItem!(item, token)); const resolvedItem = await this._provider.resolveCompletionItem!(item, token);
if (!resolvedItem) { if (!resolvedItem) {
return undefined; return undefined;
@ -1052,7 +1037,7 @@ class InlineCompletionAdapter {
const doc = this._documents.getDocument(resource); const doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); 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) { if (!result) {
// undefined and null are valid results // undefined and null are valid results
@ -1140,18 +1125,17 @@ class SignatureHelpAdapter {
private readonly _provider: vscode.SignatureHelpProvider, 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 doc = this._documents.getDocument(resource);
const pos = typeConvert.Position.to(position); const pos = typeConvert.Position.to(position);
const vscodeContext = this.reviveContext(context); const vscodeContext = this.reviveContext(context);
return asPromise(() => this._provider.provideSignatureHelp(doc, pos, token, vscodeContext)).then(value => { const value = await this._provider.provideSignatureHelp(doc, pos, token, vscodeContext);
if (value) { if (value) {
const id = this._cache.add([value]); const id = this._cache.add([value]);
return { ...typeConvert.SignatureHelp.from(value), id }; return { ...typeConvert.SignatureHelp.from(value), id };
} }
return undefined; return undefined;
});
} }
private reviveContext(context: extHostProtocol.ISignatureHelpContextDto): vscode.SignatureHelpContext { private reviveContext(context: extHostProtocol.ISignatureHelpContextDto): vscode.SignatureHelpContext {
@ -1181,11 +1165,10 @@ class InlayHintsAdapter {
private readonly _provider: vscode.InlayHintsProvider, 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); const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideInlayHints(doc, typeConvert.Range.to(range), token)).then(value => { const value = await this._provider.provideInlayHints(doc, typeConvert.Range.to(range), token);
return value ? { hints: value.map(typeConvert.InlayHint.from) } : undefined; 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> { async provideLinks(resource: URI, token: CancellationToken): Promise<extHostProtocol.ILinksListDto | undefined> {
const doc = this._documents.getDocument(resource); 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) { if (!Array.isArray(links) || links.length === 0) {
// bad result // bad result
return undefined; return undefined;
@ -1249,7 +1232,7 @@ class LinkProviderAdapter {
if (!item) { if (!item) {
return undefined; return undefined;
} }
const link = await asPromise(() => this._provider.resolveDocumentLink!(item, token)); const link = await this._provider.resolveDocumentLink!(item, token);
if (!link || !LinkProviderAdapter._validateLink(link)) { if (!link || !LinkProviderAdapter._validateLink(link)) {
return undefined; return undefined;
} }
@ -1268,34 +1251,30 @@ class ColorProviderAdapter {
private _provider: vscode.DocumentColorProvider 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); const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideDocumentColors(doc, token)).then(colors => { const colors = await this._provider.provideDocumentColors(doc, token);
if (!Array.isArray(colors)) { if (!Array.isArray(colors)) {
return []; return [];
} }
const colorInfos: extHostProtocol.IRawColorInfo[] = colors.map(ci => {
const colorInfos: extHostProtocol.IRawColorInfo[] = colors.map(ci => { return {
return { color: typeConvert.Color.from(ci.color),
color: typeConvert.Color.from(ci.color), range: typeConvert.Range.from(ci.range)
range: typeConvert.Range.from(ci.range) };
};
});
return colorInfos;
}); });
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 document = this._documents.getDocument(resource);
const range = typeConvert.Range.to(raw.range); const range = typeConvert.Range.to(raw.range);
const color = typeConvert.Color.to(raw.color); const color = typeConvert.Color.to(raw.color);
return asPromise(() => this._provider.provideColorPresentations(color, { document, range }, token)).then(value => { const value = await this._provider.provideColorPresentations(color, { document, range }, token);
if (!Array.isArray(value)) { if (!Array.isArray(value)) {
return undefined; return undefined;
} }
return value.map(typeConvert.ColorPresentation.from); return value.map(typeConvert.ColorPresentation.from);
});
} }
} }
@ -1306,14 +1285,13 @@ class FoldingProviderAdapter {
private _provider: vscode.FoldingRangeProvider 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); const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideFoldingRanges(doc, context, token)).then(ranges => { const ranges = await this._provider.provideFoldingRanges(doc, context, token);
if (!Array.isArray(ranges)) { if (!Array.isArray(ranges)) {
return undefined; return undefined;
} }
return ranges.map(typeConvert.FoldingRange.from); return ranges.map(typeConvert.FoldingRange.from);
});
} }
} }
@ -1325,41 +1303,39 @@ class SelectionRangeAdapter {
private readonly _logService: ILogService 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 document = this._documents.getDocument(resource);
const positions = pos.map(typeConvert.Position.to); const positions = pos.map(typeConvert.Position.to);
return asPromise(() => this._provider.provideSelectionRanges(document, positions, token)).then(allProviderRanges => { const allProviderRanges = await this._provider.provideSelectionRanges(document, positions, token);
if (!isNonEmptyArray(allProviderRanges)) { if (!isNonEmptyArray(allProviderRanges)) {
return []; return [];
} }
if (allProviderRanges.length !== positions.length) { if (allProviderRanges.length !== positions.length) {
this._logService.warn('BAD selection ranges, provider must return ranges for each position'); this._logService.warn('BAD selection ranges, provider must return ranges for each position');
return []; return [];
} }
const allResults: modes.SelectionRange[][] = [];
for (let i = 0; i < positions.length; i++) {
const oneResult: modes.SelectionRange[] = [];
allResults.push(oneResult);
const allResults: modes.SelectionRange[][] = []; let last: vscode.Position | vscode.Range = positions[i];
for (let i = 0; i < positions.length; i++) { let selectionRange = allProviderRanges[i];
const oneResult: modes.SelectionRange[] = [];
allResults.push(oneResult);
let last: vscode.Position | vscode.Range = positions[i]; while (true) {
let selectionRange = allProviderRanges[i]; if (!selectionRange.range.contains(last)) {
throw new Error('INVALID selection range, must contain the previous range');
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;
} }
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" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132"
integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==
v8-inspect-profiler@^0.0.21: v8-inspect-profiler@^0.0.22:
version "0.0.21" version "0.0.22"
resolved "https://registry.yarnpkg.com/v8-inspect-profiler/-/v8-inspect-profiler-0.0.21.tgz#2ded4fd59508f52d5887d3ae2bbace3e33509c41" resolved "https://registry.yarnpkg.com/v8-inspect-profiler/-/v8-inspect-profiler-0.0.22.tgz#34d3ba35a965c437ed28279d31cd42d7698a4002"
integrity sha512-6lo22vhua2Zg2Cq8Wtc2FELlTA+pmu+5epyPX65jNVAbAoKXY/XI3t33CreYiK8THKgkMeoWeviAxcJaefjyrg== integrity sha512-r2p7UkbFlFopAWUVprbECP+EpdjuEKPFQLhqpnHx9KxeTTLVaHuGpUNHye53MtYMoJFl9nJiMyIM7J2yY+dTQg==
dependencies: dependencies:
chrome-remote-interface "0.28.2" chrome-remote-interface "0.28.2"