1
- import { CancellationToken , TextDocument , Position , Hover } from "vscode" ;
1
+ import {
2
+ CancellationToken ,
3
+ TextDocument ,
4
+ Position ,
5
+ Hover ,
6
+ TextLine ,
7
+ SymbolInformation
8
+ } from "vscode" ;
2
9
3
10
import * as vscode from "vscode" ;
4
- import { getDeclaredFunctions , getDeclaredSubroutines } from "../lib/functions" ;
5
- import { getDeclaredVars } from "../lib/variables" ;
11
+ import {
12
+ parseFunction as getDeclaredFunction ,
13
+ parseSubroutine as getDeclaredSubroutine
14
+ } from "../lib/functions" ;
15
+ import { parseVars as getDeclaredVar } from "../lib/variables" ;
16
+ import { error } from "util" ;
6
17
7
18
type SymbolType = "subroutine" | "function" | "variable" ;
19
+ type ParserFunc = ( line : TextLine ) => SymbolInformation | undefined ;
8
20
9
21
export class FortranDocumentSymbolProvider
10
22
implements vscode . DocumentSymbolProvider {
@@ -16,75 +28,88 @@ export class FortranDocumentSymbolProvider
16
28
document : TextDocument ,
17
29
token : CancellationToken
18
30
) : Thenable < vscode . SymbolInformation [ ] > {
19
- return new Promise < vscode . SymbolInformation [ ] > ( ( resolve , reject ) => {
20
- token . onCancellationRequested ( e => {
21
- reject ( ) ;
22
- } ) ;
23
- const symbolTypes = this . getSymbolTypes ( ) ;
24
- const documentSymbols = symbolTypes . reduce < vscode . SymbolInformation [ ] > (
25
- ( symbols , type : SymbolType ) => {
26
- return [ ...symbols , ...this . getSymbolsOfType ( type , document ) ] ;
27
- } ,
28
- [ ]
29
- ) ;
30
-
31
- resolve ( documentSymbols ) ;
32
- } ) ;
31
+ const cancel = new Promise < vscode . SymbolInformation [ ] > (
32
+ ( resolve , reject ) => {
33
+ token . onCancellationRequested ( evt => {
34
+ reject ( error ) ;
35
+ } ) ;
36
+ }
37
+ ) ;
38
+ return Promise . race ( [ this . parseDoc ( document ) , cancel ] ) ;
33
39
}
34
- getSymbolsOfType (
35
- type : "subroutine" | "function" | "variable" ,
36
- document : TextDocument
37
- ) {
40
+ parseDoc = async ( document : TextDocument ) => {
41
+ let lines = document . lineCount ;
42
+ let symbols = [ ] ;
43
+ const symbolTypes = this . getSymbolTypes ( ) ;
44
+
45
+ for ( let i = 0 ; i < lines ; i ++ ) {
46
+ let line : vscode . TextLine = document . lineAt ( i ) ;
47
+ line = { ...line , text : line . text . trim ( ) } ;
48
+ if ( line . isEmptyOrWhitespace ) continue ;
49
+ let initialCharacter = line . text . trim ( ) . charAt ( 0 ) ;
50
+ if ( initialCharacter === "!" || initialCharacter === "#" ) continue ;
51
+ const symbolsInLine = symbolTypes
52
+ . map ( type => this . getSymbolsOfType ( type ) )
53
+ . map ( fn => fn ( line ) )
54
+ . filter ( symb => symb != undefined ) ;
55
+ if ( symbolsInLine . length > 0 ) {
56
+ symbols = symbols . concat ( symbolsInLine ) ;
57
+ }
58
+ }
59
+ return symbols ;
60
+ } ;
61
+ getSymbolsOfType ( type : "subroutine" | "function" | "variable" ) : ParserFunc {
38
62
switch ( type ) {
39
63
case "subroutine" :
40
- this . updateSubroutineDefinitions ( document ) ;
41
- return this . subroutines ;
64
+ return this . parseSubroutineDefinition ;
42
65
case "function" :
43
- this . updateFunctionDefinitions ( document ) ;
44
- return this . functions ;
66
+ return this . parseFunctionDefinition ;
67
+
45
68
case "variable" :
46
- this . updateVariablesDefiniton ( document ) ;
47
- return this . vars ;
69
+ return this . parseVariableDefinition ;
48
70
default :
49
- return [ ] ;
71
+ return ( ) => undefined ;
50
72
}
51
73
}
52
74
53
- private updateFunctionDefinitions ( document : TextDocument ) {
54
- this . functions = getDeclaredFunctions ( document ) . map ( fun => {
55
- let range = new vscode . Range ( fun . lineNumber , 0 , fun . lineNumber , 100 ) ;
56
- return new vscode . SymbolInformation (
57
- fun . name ,
58
- vscode . SymbolKind . Function ,
59
- range
60
- ) ;
61
- } ) ;
75
+ private parseSubroutineDefinition ( line : TextLine ) {
76
+ try {
77
+ const fun = getDeclaredSubroutine ( line ) ;
78
+ if ( fun ) {
79
+ let range = new vscode . Range ( line . range . start , line . range . end ) ;
80
+ return new vscode . SymbolInformation (
81
+ fun . name ,
82
+ vscode . SymbolKind . Method ,
83
+ range
84
+ ) ;
85
+ }
86
+ } catch ( err ) {
87
+ console . log ( err ) ;
88
+ }
62
89
}
63
90
64
- private updateSubroutineDefinitions ( document : TextDocument ) {
65
- this . subroutines = getDeclaredSubroutines ( document ) . map ( fun => {
66
- let range = new vscode . Range ( fun . lineNumber , 0 , fun . lineNumber , 100 ) ;
91
+ private parseFunctionDefinition ( line : TextLine ) {
92
+ const subroutine = getDeclaredFunction ( line ) ;
93
+ if ( subroutine ) {
94
+ let range = new vscode . Range ( line . range . start , line . range . end ) ;
95
+
67
96
return new vscode . SymbolInformation (
68
- fun . name ,
97
+ subroutine . name ,
69
98
vscode . SymbolKind . Function ,
70
99
range
71
100
) ;
72
- } ) ;
101
+ }
73
102
}
74
- private updateVariablesDefiniton ( document : TextDocument ) {
75
- this . vars = getDeclaredVars ( document ) . map ( variable => {
76
- let range = new vscode . Range (
77
- variable . lineNumber ,
78
- 0 ,
79
- variable . lineNumber ,
80
- 100
81
- ) ;
103
+ private parseVariableDefinition ( line : TextLine ) {
104
+ const variable = getDeclaredVar ( line ) ;
105
+ if ( variable ) {
106
+ let range = new vscode . Range ( line . range . start , line . range . end ) ;
82
107
return new vscode . SymbolInformation (
83
108
variable . name ,
84
109
vscode . SymbolKind . Variable ,
85
110
range
86
111
) ;
87
- } ) ;
112
+ }
88
113
}
89
114
getSymbolTypes ( ) {
90
115
let config = vscode . workspace . getConfiguration ( "fortran" ) ;
0 commit comments