Skip to content

Commit 7745f8b

Browse files
committed
Factorize shareable logic
1 parent 63a08e5 commit 7745f8b

File tree

3 files changed

+61
-48
lines changed

3 files changed

+61
-48
lines changed

integration/vscode/ada/src/AdaCodeLensProvider.ts

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ import {
1010
TextDocument,
1111
commands,
1212
} from 'vscode';
13-
import { getMains } from './helpers';
1413
import { CMD_BUILD_AND_DEBUG_MAIN, CMD_BUILD_AND_RUN_MAIN } from './commands';
14+
import { getMains, getSymbols } from './helpers';
1515

1616
export class AdaCodeLensProvider implements CodeLensProvider {
1717
static readonly ENABLE_SPARK_CODELENS = false;
1818

1919
onDidChangeCodeLenses?: Event<void> | undefined;
2020
provideCodeLenses(
2121
document: TextDocument,
22-
_token?: CancellationToken
22+
token?: CancellationToken
2323
): ProviderResult<CodeLens[]> {
2424
const symbols = commands.executeCommand<DocumentSymbol[]>(
2525
'vscode.executeDocumentSymbolProvider',
@@ -70,33 +70,14 @@ export class AdaCodeLensProvider implements CodeLensProvider {
7070
* This is tentative deactivated code in preparation of SPARK support.
7171
*/
7272
res2 = symbols.then<CodeLens[]>((symbols) => {
73-
// Create a named reduce function to implement a recursive visit of symbols
74-
const reduce = (acc: DocumentSymbol[], cur: DocumentSymbol) => {
75-
if (_token?.isCancellationRequested) {
76-
throw new CancellationError();
77-
}
78-
if (cur.kind == SymbolKind.Function) {
79-
// Include functions in the accumulated result
80-
acc.push(cur);
81-
}
73+
const symbolKinds = [SymbolKind.Function];
74+
const recurseInto = [SymbolKind.Module, SymbolKind.Package, SymbolKind.Function];
8275

83-
// Search for Functions among the children of these symbol kinds
84-
if (
85-
[SymbolKind.Module, SymbolKind.Package, SymbolKind.Function].includes(
86-
cur.kind
87-
)
88-
) {
89-
cur.children.reduce(reduce, acc);
90-
}
91-
92-
return acc;
93-
};
94-
95-
// Collect functions recursively
96-
const functions = symbols.reduce(reduce, []);
76+
// Create a named reduce function to implement a recursive visit of symbols
77+
const functions = getSymbols(symbols, symbolKinds, recurseInto, token);
9778

9879
return functions.map((f) => {
99-
if (_token?.isCancellationRequested) {
80+
if (token?.isCancellationRequested) {
10081
throw new CancellationError();
10182
}
10283
// TODO make SPARK codelenses conditional to the availability of SPARK on PATH

integration/vscode/ada/src/helpers.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import * as vscode from 'vscode';
2121
import { ExecuteCommandRequest, LanguageClient } from 'vscode-languageclient/node';
2222
import winston from 'winston';
2323
import { adaExtState, logger } from './extension';
24+
import { DocumentSymbol, SymbolKind, CancellationToken, CancellationError } from 'vscode';
2425

2526
/**
2627
* Substitue any variable reference present in the given string. VS Code
@@ -389,3 +390,47 @@ export async function findAdaMain(mainPath: string): Promise<AdaMain | undefined
389390
);
390391
return adaMain;
391392
}
393+
/**
394+
* Starting from an array of symbols {@link rootSymbols} (usually obtained for a
395+
* document using the vscode.executeDocumentSymbolProvider command), iterate the
396+
* symbols recursively and return an array of the symbols of a given set of
397+
* kinds {@link symbolKinds}.
398+
*
399+
* Recursion is control by another set of symbols kinds {@link recurseInto}.
400+
* Only the children of these kinds of symbols are recursed into.
401+
*
402+
* @param rootSymbols - the array of symbols to start from
403+
* @param symbolKinds - kinds of symbols to include in the result
404+
* @param recurseInto - kinds of symbols to recurse into
405+
* @param token - a cancellation token to abort the search
406+
* @returns an array of {@link DocumentSymbol}s of the kinds requested in symbolKinds.
407+
*/
408+
409+
export function getSymbols(
410+
rootSymbols: DocumentSymbol[],
411+
symbolKinds: SymbolKind[],
412+
recurseInto: SymbolKind[] = [SymbolKind.Module, SymbolKind.Package, SymbolKind.Function],
413+
token?: CancellationToken
414+
): DocumentSymbol[] {
415+
const reduce = (acc: DocumentSymbol[], cur: DocumentSymbol) => {
416+
if (token?.isCancellationRequested) {
417+
throw new CancellationError();
418+
}
419+
if (symbolKinds.includes(cur.kind)) {
420+
// Include targeted symbol kinds in the result
421+
acc.push(cur);
422+
}
423+
424+
// Recurse into symbols of the specified kinds
425+
if (recurseInto.includes(cur.kind)) {
426+
cur.children.reduce(reduce, acc);
427+
}
428+
429+
return acc;
430+
};
431+
432+
// Collect symbols recursively
433+
const allSymbols = rootSymbols.reduce(reduce, []);
434+
435+
return allSymbols;
436+
}

integration/vscode/ada/src/taskProviders.ts

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
import assert from 'assert';
1919
import commandExists from 'command-exists';
2020
import * as vscode from 'vscode';
21-
import { adaExtState } from './extension';
22-
import { AdaMain, getAdaMains, getProjectFile } from './helpers';
21+
import { adaExtState, logger } from './extension';
22+
import { AdaMain, getAdaMains, getProjectFile, getSymbols } from './helpers';
23+
import { SymbolKind } from 'vscode';
2324

2425
export const ADA_TASK_TYPE = 'ada';
2526

@@ -376,24 +377,10 @@ export async function getEnclosingSymbol(
376377
);
377378

378379
// Then filter them according to the specified kinds
379-
const filtered_symbols: vscode.DocumentSymbol[] = [];
380-
381-
const getAllSymbols = (symbols: vscode.DocumentSymbol[]) => {
382-
let sym;
383-
for (sym of symbols) {
384-
if (kinds.includes(sym.kind)) {
385-
filtered_symbols.push(sym);
386-
}
387-
if (
388-
sym.kind == vscode.SymbolKind.Function ||
389-
sym.kind == vscode.SymbolKind.Module
390-
) {
391-
getAllSymbols(sym.children);
392-
}
393-
}
394-
};
395-
396-
getAllSymbols(symbols);
380+
const filtered_symbols = getSymbols(symbols, kinds, [
381+
SymbolKind.Function,
382+
SymbolKind.Module,
383+
]);
397384

398385
// Finally select from the filtered symbols the smallest one containing the current line
399386
const scopeSymbols = filtered_symbols.filter(
@@ -413,9 +400,9 @@ export async function getEnclosingSymbol(
413400
return null;
414401
}
415402

416-
const getSelectedRegion = (editor: vscode.TextEditor | undefined): string => {
403+
export const getSelectedRegion = (editor: vscode.TextEditor | undefined): string => {
417404
if (editor) {
418-
const selection = editor.selections[0];
405+
const selection = editor.selection;
419406
// Line numbers start at 0 in VS Code, and at 1 in GNAT
420407
return (selection.start.line + 1).toString() + ':' + (selection.end.line + 1).toString();
421408
} else {

0 commit comments

Comments
 (0)