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" ;
29
310import * 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" ;
617
718type SymbolType = "subroutine" | "function" | "variable" ;
19+ type ParserFunc = ( line : TextLine ) => SymbolInformation | undefined ;
820
921export class FortranDocumentSymbolProvider
1022 implements vscode . DocumentSymbolProvider {
@@ -16,75 +28,88 @@ export class FortranDocumentSymbolProvider
1628 document : TextDocument ,
1729 token : CancellationToken
1830 ) : 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 ] ) ;
3339 }
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 {
3862 switch ( type ) {
3963 case "subroutine" :
40- this . updateSubroutineDefinitions ( document ) ;
41- return this . subroutines ;
64+ return this . parseSubroutineDefinition ;
4265 case "function" :
43- this . updateFunctionDefinitions ( document ) ;
44- return this . functions ;
66+ return this . parseFunctionDefinition ;
67+
4568 case "variable" :
46- this . updateVariablesDefiniton ( document ) ;
47- return this . vars ;
69+ return this . parseVariableDefinition ;
4870 default :
49- return [ ] ;
71+ return ( ) => undefined ;
5072 }
5173 }
5274
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+ }
6289 }
6390
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+
6796 return new vscode . SymbolInformation (
68- fun . name ,
97+ subroutine . name ,
6998 vscode . SymbolKind . Function ,
7099 range
71100 ) ;
72- } ) ;
101+ }
73102 }
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 ) ;
82107 return new vscode . SymbolInformation (
83108 variable . name ,
84109 vscode . SymbolKind . Variable ,
85110 range
86111 ) ;
87- } ) ;
112+ }
88113 }
89114 getSymbolTypes ( ) {
90115 let config = vscode . workspace . getConfiguration ( "fortran" ) ;
0 commit comments