Skip to content

Commit

Permalink
use a parent pointer instead of 2d array, #67872
Browse files Browse the repository at this point in the history
  • Loading branch information
jrieken committed Mar 12, 2019
1 parent a86ff6a commit 4f8dbd4
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 24 deletions.
9 changes: 5 additions & 4 deletions extensions/css-language-features/client/src/cssMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 [];
Expand Down
7 changes: 4 additions & 3 deletions extensions/html-language-features/client/src/htmlMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 [];
Expand Down
7 changes: 4 additions & 3 deletions extensions/json-language-features/client/src/jsonMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 [];
Expand Down
3 changes: 2 additions & 1 deletion src/vs/editor/contrib/smartSelect/smartSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -237,7 +238,7 @@ export function provideSelectionRanges(model: ITextModel, positions: Position[],
}
}
}
}));
}, onUnexpectedExternalError));
}

return Promise.all(work).then(() => {
Expand Down
5 changes: 3 additions & 2 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
9 changes: 7 additions & 2 deletions src/vs/workbench/api/node/extHostLanguageFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion src/vs/workbench/api/node/extHostTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))),
];
}
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))),
];
}
}));

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

0 comments on commit 4f8dbd4

Please # to comment.