Skip to content

Commit 9e9eb70

Browse files
committed
Make document symbol provider async
1 parent de060b5 commit 9e9eb70

File tree

2 files changed

+135
-112
lines changed

2 files changed

+135
-112
lines changed
Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,64 @@
1-
2-
31
import { CancellationToken, TextDocument, Position, Hover } from "vscode";
42

5-
import * as vscode from 'vscode';
6-
import { getDeclaredFunctions, getDeclaredSubroutines} from '../lib/functions';
7-
import { getDeclaredVars } from '../lib/variables';
8-
9-
export class FortranDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
10-
11-
public provideDocumentSymbols(document: TextDocument, token: CancellationToken){
12-
13-
let functions = getDeclaredFunctions(document).map(fun => {
3+
import * as vscode from "vscode";
4+
import { getDeclaredFunctions, getDeclaredSubroutines } from "../lib/functions";
5+
import { getDeclaredVars } from "../lib/variables";
146

15-
let range = new vscode.Range(fun.lineNumber, 0, fun.lineNumber, 100);
16-
return new vscode.SymbolInformation(fun.name, vscode.SymbolKind.Function, range );
17-
});
18-
let subroutines = getDeclaredSubroutines(document).map(fun => {
7+
export class FortranDocumentSymbolProvider
8+
implements vscode.DocumentSymbolProvider {
9+
vars: Array<vscode.SymbolInformation>;
10+
functions: Array<vscode.SymbolInformation>;
11+
subroutines: Array<vscode.SymbolInformation>;
1912

20-
let range = new vscode.Range(fun.lineNumber, 0, fun.lineNumber, 100);
21-
return new vscode.SymbolInformation(fun.name, vscode.SymbolKind.Function, range );
22-
});
23-
let vars = getDeclaredVars(document).map(variable => {
24-
let range = new vscode.Range(variable.lineNumber, 0, variable.lineNumber, 100);
25-
return new vscode.SymbolInformation(variable.name, vscode.SymbolKind.Variable, range );
26-
});
13+
public provideDocumentSymbols(
14+
document: TextDocument,
15+
token: CancellationToken
16+
): Thenable<vscode.SymbolInformation[]> {
17+
return new Promise<vscode.SymbolInformation[]>((resolve, reject) => {
18+
token.onCancellationRequested(e => {
19+
reject();
20+
});
21+
this.updateFunctionDefinitions(document);
22+
this.updateSubroutineDefinitions(document);
23+
this.updateVariablesDefiniton(document);
24+
resolve([...this.functions, ...this.subroutines, ...this.vars]);
25+
});
26+
}
2727

28-
return [...functions, ...subroutines, ...vars];
29-
}
28+
private updateFunctionDefinitions(document: TextDocument) {
29+
this.functions = getDeclaredFunctions(document).map(fun => {
30+
let range = new vscode.Range(fun.lineNumber, 0, fun.lineNumber, 100);
31+
return new vscode.SymbolInformation(
32+
fun.name,
33+
vscode.SymbolKind.Function,
34+
range
35+
);
36+
});
37+
}
3038

31-
}
39+
private updateSubroutineDefinitions(document: TextDocument) {
40+
this.subroutines = getDeclaredSubroutines(document).map(fun => {
41+
let range = new vscode.Range(fun.lineNumber, 0, fun.lineNumber, 100);
42+
return new vscode.SymbolInformation(
43+
fun.name,
44+
vscode.SymbolKind.Function,
45+
range
46+
);
47+
});
48+
}
49+
private updateVariablesDefiniton(document: TextDocument) {
50+
this.vars = getDeclaredVars(document).map(variable => {
51+
let range = new vscode.Range(
52+
variable.lineNumber,
53+
0,
54+
variable.lineNumber,
55+
100
56+
);
57+
return new vscode.SymbolInformation(
58+
variable.name,
59+
vscode.SymbolKind.Variable,
60+
range
61+
);
62+
});
63+
}
64+
}

src/lib/functions.ts

Lines changed: 77 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,102 @@
1-
2-
import * as vscode from 'vscode';
1+
import * as vscode from "vscode";
32

43
export interface Variable {
5-
name: string;
6-
type?: string;
7-
lineNumber?: number;
4+
name: string;
5+
type?: string;
6+
lineNumber?: number;
87
}
98

10-
119
export interface Subroutine {
12-
13-
name: string;
14-
args: Variable[];
15-
docstr: string;
16-
lineNumber: number
10+
name: string;
11+
args: Variable[];
12+
docstr: string;
13+
lineNumber: number;
1714
}
1815

19-
export interface Function extends Subroutine {
20-
21-
return: Variable; // function is a subroutine with return type
16+
export interface Function extends Subroutine {
17+
return: Variable; // function is a subroutine with return type
2218
}
2319

2420
export enum MethodType {
25-
Subroutine,
26-
Function
27-
};
28-
29-
30-
31-
export function getDeclaredFunctions(document: vscode.TextDocument): Function[] {
32-
33-
let lines = document.lineCount;
34-
let funcs = [];
21+
Subroutine,
22+
Function
23+
}
3524

36-
for (let i = 0; i < lines; i++) {
37-
let line: vscode.TextLine = document.lineAt(i);
38-
if (line.isEmptyOrWhitespace) continue;
39-
let newFunc = parseFunction(line.text)
40-
if(newFunc){
41-
funcs.push({...newFunc, lineNumber: i });
42-
}
25+
export function getDeclaredFunctions(
26+
document: vscode.TextDocument
27+
): Function[] {
28+
let lines = document.lineCount;
29+
let funcs = [];
30+
31+
for (let i = 0; i < lines; i++) {
32+
let line: vscode.TextLine = document.lineAt(i);
33+
if (line.isEmptyOrWhitespace) continue;
34+
let newFunc = parseFunction(line.text);
35+
if (newFunc) {
36+
funcs.push({ ...newFunc, lineNumber: i });
4337
}
44-
return funcs;
38+
}
39+
return funcs;
4540
}
4641

47-
export function getDeclaredSubroutines(document: vscode.TextDocument):Subroutine[]{
48-
49-
let lines = document.lineCount;
50-
let subroutines = [];
51-
52-
for (let i = 0; i < lines; i++) {
53-
let line: vscode.TextLine = document.lineAt(i);
54-
if (line.isEmptyOrWhitespace) continue;
55-
let newSubroutine = parseSubroutine(line.text)
56-
if(newSubroutine){
57-
subroutines.push({...newSubroutine, lineNumber: i });
58-
}
42+
export function getDeclaredSubroutines(
43+
document: vscode.TextDocument
44+
): Subroutine[] {
45+
let lines = document.lineCount;
46+
let subroutines = [];
47+
48+
for (let i = 0; i < lines; i++) {
49+
let line: vscode.TextLine = document.lineAt(i);
50+
if (line.isEmptyOrWhitespace) continue;
51+
let newSubroutine = parseSubroutine(line.text);
52+
if (newSubroutine) {
53+
subroutines.push({ ...newSubroutine, lineNumber: i });
5954
}
60-
return subroutines;
55+
}
56+
return subroutines;
6157
}
6258

63-
64-
6559
export const parseFunction = (line: string) => {
66-
67-
return _parse(line, MethodType.Function);
68-
}
60+
return _parse(line, MethodType.Function);
61+
};
6962

7063
export const parseSubroutine = (line: string) => {
71-
72-
return _parse(line, MethodType.Subroutine);
73-
}
64+
return _parse(line, MethodType.Subroutine);
65+
};
7466
export const _parse = (line: string, type: MethodType) => {
75-
76-
const functionRegEx = /([a-zA-Z]+(\([\w.=]+\))*)*\s*function\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\((\s*[a-zA-Z_][a-zA-Z0-9_,\s]*)*\s*\)\s*(result\([a-zA-Z_][\w]*\))*/g;
77-
const subroutineRegEx = /subroutine\s*([a-zA-Z][a-zA-Z0-9_]*)\s*\((\s*[a-zA-Z][a-zA-z0-9_,\s]*)*\s*\)/g;
78-
const regEx = (type === MethodType.Subroutine) ? subroutineRegEx : functionRegEx;
79-
if (line.match(regEx) && type === MethodType.Function) {
80-
let [attr, kind_descriptor, name, argsstr, result] = regEx.exec(line).slice(1, 5);
81-
let args = (argsstr) ? parseArgs(argsstr) : [];
82-
return {
83-
name: name,
84-
args: args
85-
};
86-
} else if (line.match(regEx) && type === MethodType.Subroutine) {
87-
let [name, argsstr] = regEx.exec(line).slice(1);
88-
let args = (argsstr) ? parseArgs(argsstr) : [];
89-
return {
90-
name: name,
91-
args: args
92-
};
93-
}
94-
95-
}
96-
97-
98-
67+
const functionRegEx = /([a-zA-Z]+(\([\w.=]+\))*)*\s*function\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\((\s*[a-zA-Z_][a-zA-Z0-9_,\s]*)*\s*\)\s*(result\([a-zA-Z_][\w]*\))*/gi;
68+
const subroutineRegEx = /subroutine\s*([a-zA-Z][a-zA-Z0-9_]*)\s*\((\s*[a-zA-Z][a-zA-z0-9_,\s]*)*\s*\)/gi;
69+
const regEx =
70+
type === MethodType.Subroutine ? subroutineRegEx : functionRegEx;
71+
if (line.match(regEx) && type === MethodType.Function) {
72+
let [attr, kind_descriptor, name, argsstr, result] = regEx
73+
.exec(line)
74+
.slice(1, 5);
75+
let args = argsstr ? parseArgs(argsstr) : [];
76+
return {
77+
name: name,
78+
args: args
79+
};
80+
} else if (line.match(regEx) && type === MethodType.Subroutine) {
81+
let [name, argsstr] = regEx.exec(line).slice(1);
82+
let args = argsstr ? parseArgs(argsstr) : [];
83+
return {
84+
name: name,
85+
args: args
86+
};
87+
}
88+
};
9989

10090
export const parseArgs = (argsstr: string) => {
101-
let args = argsstr.trim().split(',');
102-
let variables: Variable[] = args.filter(name => validVariableName(name))
103-
.map(name => {
104-
return { name: name };
105-
});
106-
return variables;
107-
}
91+
let args = argsstr.trim().split(",");
92+
let variables: Variable[] = args
93+
.filter(name => validVariableName(name))
94+
.map(name => {
95+
return { name: name };
96+
});
97+
return variables;
98+
};
10899

109100
export const validVariableName = (name: string) => {
110-
return name.trim().match(/^[a-zA-Z_][a-zA-Z0-9_]*$/) !== null;
111-
}
112-
101+
return name.trim().match(/^[a-zA-Z_][a-zA-Z0-9_]*$/) !== null;
102+
};

0 commit comments

Comments
 (0)