1
1
import { RecursiveVisitor } from "@server/psi/visitor"
2
2
import type { File } from "@server/psi/File"
3
3
import { Reference } from "@server/psi/Reference"
4
- import type { Node as SyntaxNode } from "web-tree-sitter"
5
- import { NamedNode } from "@server/psi/Node"
4
+ import { NamedNode , Node } from "@server/psi/Node"
6
5
import * as lsp from "vscode-languageserver"
7
6
import type { SemanticTokens } from "vscode-languageserver"
8
- import { isNamedFunNode } from "@server/psi/utils"
9
-
10
- export function collect ( file : File ) : SemanticTokens {
11
- const builder = new lsp . SemanticTokensBuilder ( )
12
-
13
- function pushToken ( n : SyntaxNode , tokenType : lsp . SemanticTokenTypes ) : void {
14
- builder . push (
15
- n . startPosition . row ,
16
- n . startPosition . column ,
17
- n . endPosition . column - n . startPosition . column ,
18
- Object . keys ( lsp . SemanticTokenTypes ) . indexOf ( tokenType ) ,
19
- 0 ,
20
- )
21
- }
7
+ import { isDocCommentOwner , isNamedFunNode } from "@server/psi/utils"
8
+ import { createTactParser } from "@server/parser"
9
+ import { extractCommentsDocContent } from "@server/documentation/documentation"
10
+ import { processDocComment } from "@server/semantic_tokens/comments"
11
+ import { Tokens } from "@server/semantic_tokens/tokens"
12
+
13
+ export function collect (
14
+ file : File ,
15
+ highlighting : {
16
+ highlightCodeInComments : boolean
17
+ } ,
18
+ ) : SemanticTokens {
19
+ const tokens = new Tokens ( )
20
+
21
+ const parser = createTactParser ( )
22
22
23
23
RecursiveVisitor . visit ( file . rootNode , ( n ) : boolean => {
24
24
const type = n . type
25
25
26
26
// asm fun foo() {}
27
27
// ^^^ this
28
28
if ( type === "asm" && n . parent ?. type === "asm_function" ) {
29
- pushToken ( n , lsp . SemanticTokenTypes . keyword )
29
+ tokens . node ( n , lsp . SemanticTokenTypes . keyword )
30
30
return true
31
31
}
32
32
33
33
if ( type === "global_constant" ) {
34
34
const name = n . childForFieldName ( "name" )
35
35
if ( ! name ) return true
36
- pushToken ( name , lsp . SemanticTokenTypes . property )
36
+ tokens . node ( name , lsp . SemanticTokenTypes . property )
37
37
return true
38
38
}
39
39
40
40
if ( type === "storage_function" ) {
41
41
const name = n . childForFieldName ( "name" )
42
42
if ( ! name ) return true
43
- pushToken ( name , lsp . SemanticTokenTypes . function )
43
+ tokens . node ( name , lsp . SemanticTokenTypes . function )
44
44
return true
45
45
}
46
46
47
47
if ( type === "parameter" ) {
48
48
const name = n . childForFieldName ( "name" )
49
49
if ( ! name ) return true
50
- pushToken ( name , lsp . SemanticTokenTypes . parameter )
50
+ tokens . node ( name , lsp . SemanticTokenTypes . parameter )
51
51
return true
52
52
}
53
53
54
54
if ( type === "let_statement" ) {
55
55
const name = n . childForFieldName ( "name" )
56
56
if ( ! name ) return true
57
- pushToken ( name , lsp . SemanticTokenTypes . variable )
57
+ tokens . node ( name , lsp . SemanticTokenTypes . variable )
58
58
return true
59
59
}
60
60
61
61
if ( type === "field" || type === "storage_variable" ) {
62
62
const name = n . childForFieldName ( "name" )
63
63
if ( ! name ) return true
64
- pushToken ( name , lsp . SemanticTokenTypes . property )
64
+ tokens . node ( name , lsp . SemanticTokenTypes . property )
65
65
return true
66
66
}
67
67
68
68
if ( type === "constant" || type === "storage_constant" ) {
69
69
const name = n . childForFieldName ( "name" )
70
70
if ( ! name ) return true
71
- pushToken ( name , lsp . SemanticTokenTypes . enumMember )
71
+ tokens . node ( name , lsp . SemanticTokenTypes . enumMember )
72
72
return true
73
73
}
74
74
75
75
// asm fun foo() { ONE }
76
76
// ^^^ this
77
77
if ( type === "tvm_instruction" ) {
78
- pushToken ( n , lsp . SemanticTokenTypes . macro )
78
+ tokens . node ( n , lsp . SemanticTokenTypes . macro )
79
79
return true
80
80
}
81
81
82
82
if ( type === "asm_stack_register" ) {
83
- pushToken ( n , lsp . SemanticTokenTypes . parameter )
83
+ tokens . node ( n , lsp . SemanticTokenTypes . parameter )
84
84
return true
85
85
}
86
86
@@ -92,31 +92,43 @@ export function collect(file: File): SemanticTokens {
92
92
93
93
switch ( resolvedType ) {
94
94
case "parameter" : {
95
- pushToken ( n , lsp . SemanticTokenTypes . parameter )
95
+ tokens . node ( n , lsp . SemanticTokenTypes . parameter )
96
96
break
97
97
}
98
98
case "field" :
99
99
case "storage_variable" : {
100
- pushToken ( n , lsp . SemanticTokenTypes . property )
100
+ tokens . node ( n , lsp . SemanticTokenTypes . property )
101
101
break
102
102
}
103
103
case "constant" :
104
104
case "storage_constant" : {
105
- pushToken ( n , lsp . SemanticTokenTypes . enumMember )
105
+ tokens . node ( n , lsp . SemanticTokenTypes . enumMember )
106
106
break
107
107
}
108
108
default : {
109
109
if ( isNamedFunNode ( resolved . node ) ) {
110
- pushToken ( n , lsp . SemanticTokenTypes . function )
110
+ tokens . node ( n , lsp . SemanticTokenTypes . function )
111
111
} else if ( resolved . node . parent ?. type === "let_statement" ) {
112
- pushToken ( n , lsp . SemanticTokenTypes . variable )
112
+ tokens . node ( n , lsp . SemanticTokenTypes . variable )
113
113
}
114
114
}
115
115
}
116
116
}
117
117
118
+ if ( highlighting . highlightCodeInComments && isDocCommentOwner ( n ) ) {
119
+ const node = new Node ( n , file )
120
+
121
+ const comment = extractCommentsDocContent ( node )
122
+ if ( ! comment ) return true
123
+
124
+ processDocComment ( tokens , comment , parser )
125
+ }
126
+
118
127
return true
119
128
} )
120
129
121
- return builder . build ( )
130
+ return {
131
+ resultId : Date . now ( ) . toString ( ) ,
132
+ data : tokens . result ( ) ,
133
+ }
122
134
}
0 commit comments