提交 4f8dbd45 编写于 作者: J Johannes Rieken

use a parent pointer instead of 2d array, #67872

上级 a86ff6a4
......@@ -81,16 +81,17 @@ export function activate(context: ExtensionContext) {
documentSelector.forEach(selector => {
context.subscriptions.push(languages.registerSelectionRangeProvider(selector, {
async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise<SelectionRange[][]> {
async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise<SelectionRange[]> {
const textDocument = client.code2ProtocolConverter.asTextDocumentIdentifier(document);
const rawResult = await client.sendRequest<SelectionRange[][]>('$/textDocument/selectionRanges', { textDocument, positions: positions.map(client.code2ProtocolConverter.asPosition) });
if (Array.isArray(rawResult)) {
return rawResult.map(rawSelectionRanges => {
return rawSelectionRanges.map(selectionRange => {
return rawSelectionRanges.reduceRight((parent: SelectionRange | undefined, selectionRange: SelectionRange) => {
return {
range: client.protocol2CodeConverter.asRange(selectionRange.range)
range: client.protocol2CodeConverter.asRange(selectionRange.range),
parent
};
});
}, undefined)!;
});
}
return [];
......
......@@ -90,16 +90,17 @@ export function activate(context: ExtensionContext) {
documentSelector.forEach(selector => {
context.subscriptions.push(languages.registerSelectionRangeProvider(selector, {
async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise<SelectionRange[][]> {
async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise<SelectionRange[]> {
const textDocument = client.code2ProtocolConverter.asTextDocumentIdentifier(document);
const rawResult = await client.sendRequest<SelectionRange[][]>('$/textDocument/selectionRanges', { textDocument, positions: positions.map(client.code2ProtocolConverter.asPosition) });
if (Array.isArray(rawResult)) {
return rawResult.map(rawSelectionRanges => {
return rawSelectionRanges.map(selectionRange => {
return rawSelectionRanges.reduceRight((parent: SelectionRange | undefined, selectionRange: SelectionRange) => {
return {
range: client.protocol2CodeConverter.asRange(selectionRange.range),
parent
};
});
}, undefined)!;
});
}
return [];
......
......@@ -214,16 +214,17 @@ export function activate(context: ExtensionContext) {
documentSelector.forEach(selector => {
toDispose.push(languages.registerSelectionRangeProvider(selector, {
async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise<SelectionRange[][]> {
async provideSelectionRanges(document: TextDocument, positions: Position[]): Promise<SelectionRange[]> {
const textDocument = client.code2ProtocolConverter.asTextDocumentIdentifier(document);
const rawResult = await client.sendRequest<SelectionRange[][]>('$/textDocument/selectionRanges', { textDocument, positions: positions.map(client.code2ProtocolConverter.asPosition) });
if (Array.isArray(rawResult)) {
return rawResult.map(rawSelectionRanges => {
return rawSelectionRanges.map(selectionRange => {
return rawSelectionRanges.reduceRight((parent: SelectionRange | undefined, selectionRange: SelectionRange) => {
return {
range: client.protocol2CodeConverter.asRange(selectionRange.range),
parent,
};
});
}, undefined)!;
});
}
return [];
......
......@@ -22,6 +22,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { WordSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/wordSelections';
import { BracketSelectionRangeProvider } from 'vs/editor/contrib/smartSelect/bracketSelections';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
class SelectionRanges {
......@@ -237,7 +238,7 @@ export function provideSelectionRanges(model: ITextModel, positions: Position[],
}
}
}
}));
}, onUnexpectedExternalError));
}
return Promise.all(work).then(() => {
......
......@@ -86,7 +86,8 @@ declare module 'vscode' {
export class SelectionRange {
range: Range;
constructor(range: Range);
parent?: SelectionRange;
constructor(range: Range, parent?: SelectionRange);
}
export interface SelectionRangeProvider {
......@@ -97,7 +98,7 @@ declare module 'vscode' {
*
* todo@joh
*/
provideSelectionRanges(document: TextDocument, positions: Position[], token: CancellationToken): ProviderResult<SelectionRange[][]>;
provideSelectionRanges(document: TextDocument, positions: Position[], token: CancellationToken): ProviderResult<SelectionRange[]>;
}
export namespace languages {
......
......@@ -944,14 +944,19 @@ class SelectionRangeAdapter {
const oneResult: modes.SelectionRange[] = [];
allResults.push(oneResult);
const oneProviderRanges = allProviderRanges[i];
let last: vscode.Position | vscode.Range = positions[i];
for (const selectionRange of oneProviderRanges) {
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;
}
}
return allResults;
......
......@@ -1098,9 +1098,11 @@ CodeActionKind.SourceFixAll = CodeActionKind.Source.append('fixAll');
export class SelectionRange {
range: Range;
parent?: SelectionRange;
constructor(range: Range) {
constructor(range: Range, parent?: SelectionRange) {
this.range = range;
this.parent = parent;
}
}
......
......@@ -799,10 +799,9 @@ suite('ExtHostLanguageFeatureCommands', function () {
disposables.push(extHost.registerSelectionRangeProvider(nullExtensionDescription, defaultSelector, <vscode.SelectionRangeProvider>{
provideSelectionRanges() {
return [[
new types.SelectionRange(new types.Range(0, 10, 0, 18)),
new types.SelectionRange(new types.Range(0, 2, 0, 20))
]];
return [
new types.SelectionRange(new types.Range(0, 10, 0, 18), new types.SelectionRange(new types.Range(0, 2, 0, 20))),
];
}
}));
......
......@@ -1104,10 +1104,9 @@ suite('ExtHostLanguageFeatures', function () {
test('Selection Ranges, data conversion', async () => {
disposables.push(extHost.registerSelectionRangeProvider(defaultExtension, defaultSelector, new class implements vscode.SelectionRangeProvider {
provideSelectionRanges() {
return [[
new types.SelectionRange(new types.Range(0, 10, 0, 18)),
new types.SelectionRange(new types.Range(0, 2, 0, 20))
]];
return [
new types.SelectionRange(new types.Range(0, 10, 0, 18), new types.SelectionRange(new types.Range(0, 2, 0, 20))),
];
}
}));
......@@ -1118,4 +1117,21 @@ suite('ExtHostLanguageFeatures', function () {
assert.ok(ranges[0].length >= 2);
});
});
test('Selection Ranges, bad data', async () => {
disposables.push(extHost.registerSelectionRangeProvider(defaultExtension, defaultSelector, new class implements vscode.SelectionRangeProvider {
provideSelectionRanges() {
return [
new types.SelectionRange(new types.Range(0, 10, 0, 18),
new types.SelectionRange(new types.Range(0, 11, 0, 18))),
];
}
}));
await rpcProtocol.sync();
provideSelectionRanges(model, [new Position(1, 17)], CancellationToken.None).then(ranges => {
assert.equal(ranges.length, 0);
});
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册