@@ -14,7 +14,7 @@ macro_rules! find_function_def_str {
14
14
(
15
15
(function_declarator
16
16
(identifier) @function)
17
- (#match? @function "{} ")
17
+ (#match? @function "^{}$ ")
18
18
)
19
19
"#
20
20
} ;
@@ -26,11 +26,33 @@ macro_rules! find_function_refs_str {
26
26
(
27
27
(call_expression
28
28
(identifier) @call)
29
- (#match? @call "{} ")
29
+ (#match? @call "^{}$ ")
30
30
)
31
31
"#
32
32
} ;
33
33
}
34
+
35
+ macro_rules! find_variable_def_str {
36
+ ( ) => {
37
+ r#"
38
+ (
39
+ [
40
+ (init_declarator
41
+ (identifier) @variable)
42
+
43
+ (parameter_declaration
44
+ (identifier) @variable)
45
+
46
+ (declaration
47
+ (identifier) @variable)
48
+
49
+ (#match? @variable "^{}$")
50
+ ]
51
+ )
52
+ "#
53
+ } ;
54
+ }
55
+
34
56
pub struct ParserContext < ' a > {
35
57
source : String ,
36
58
tree : Tree ,
@@ -65,40 +87,23 @@ impl<'a> ParserContext<'a> {
65
87
None => return Ok ( None ) ,
66
88
} ;
67
89
68
- let query = match ( current_node. kind ( ) , parent. kind ( ) ) {
90
+ debug ! ( "matching location lookup method for parent-child tuple" ; "parent" => parent. kind( ) , "child" => current_node. kind( ) ) ;
91
+
92
+ let locations = match ( current_node. kind ( ) , parent. kind ( ) ) {
69
93
( _, "call_expression" ) => {
70
- format ! ( find_function_def_str!( ) , current_node. utf8_text( self . source. as_bytes( ) ) ?)
94
+ let query_str = format ! ( find_function_def_str!( ) , current_node. utf8_text( self . source. as_bytes( ) ) ?) ;
95
+ self . simple_global_search ( path, & query_str) ?
96
+ }
97
+ ( "identifier" , "argument_list" ) |
98
+ ( "identifier" , "field_expression" ) |
99
+ ( "identifier" , "binary_expression" ) |
100
+ ( "identifier" , "assignment_expression" ) => {
101
+ self . tree_climbing_search ( path, current_node) ?
71
102
}
72
103
_ => return Ok ( None ) ,
73
104
} ;
74
105
75
- let ts_query = Query :: new ( tree_sitter_glsl:: language ( ) , query. as_str ( ) ) ?;
76
- let mut query_cursor = QueryCursor :: new ( ) ;
77
-
78
- let mut locations = vec ! [ ] ;
79
-
80
- for m in query_cursor. matches ( & ts_query, self . root_node ( ) , self . source . as_bytes ( ) ) {
81
- for capture in m. captures {
82
- let start = capture. node . start_position ( ) ;
83
- let end = capture. node . end_position ( ) ;
84
-
85
- locations. push ( Location {
86
- uri : Url :: from_file_path ( path) . unwrap ( ) ,
87
- range : Range {
88
- start : Position {
89
- line : start. row as u32 ,
90
- character : start. column as u32 ,
91
- } ,
92
- end : Position {
93
- line : end. row as u32 ,
94
- character : end. column as u32 ,
95
- } ,
96
- } ,
97
- } ) ;
98
- }
99
- }
100
-
101
- info ! ( "finished searching for definitions" ; "definitions" => format!( "{:?}" , locations) ) ;
106
+ info ! ( "finished searching for definitions" ; "count" => locations. len( ) , "definitions" => format!( "{:?}" , locations) ) ;
102
107
103
108
Ok ( Some ( locations) )
104
109
}
@@ -114,19 +119,79 @@ impl<'a> ParserContext<'a> {
114
119
None => return Ok ( None ) ,
115
120
} ;
116
121
117
- let query = match ( current_node. kind ( ) , parent. kind ( ) ) {
122
+ let locations = match ( current_node. kind ( ) , parent. kind ( ) ) {
118
123
( _, "function_declarator" ) => {
119
- format ! ( find_function_refs_str!( ) , current_node. utf8_text( self . source. as_bytes( ) ) ?)
124
+ let query_str = format ! ( find_function_refs_str!( ) , current_node. utf8_text( self . source. as_bytes( ) ) ?) ;
125
+ self . simple_global_search ( path, & query_str) ?
120
126
}
121
127
_ => return Ok ( None ) ,
122
128
} ;
123
129
124
- let ts_query = Query :: new ( tree_sitter_glsl:: language ( ) , query. as_str ( ) ) ?;
130
+ info ! ( "finished searching for references" ; "count" => locations. len( ) , "references" => format!( "{:?}" , locations) ) ;
131
+
132
+ Ok ( Some ( locations) )
133
+ }
134
+
135
+ fn tree_climbing_search ( & self , path : & Path , start_node : Node ) -> Result < Vec < Location > > {
136
+ let mut locations = vec ! [ ] ;
137
+
138
+ let node_text = start_node. utf8_text ( self . source . as_bytes ( ) ) ?;
139
+
140
+ let query_str = format ! ( find_variable_def_str!( ) , node_text) ;
141
+
142
+ debug ! ( "built query string" ; "query" => & query_str) ;
143
+
144
+ let mut parent = start_node. parent ( ) ;
145
+
146
+ loop {
147
+ if parent. is_none ( ) {
148
+ trace ! ( "no more parent left, found nothing" ) ;
149
+ break ;
150
+ }
151
+
152
+ let query = Query :: new ( tree_sitter_glsl:: language ( ) , & query_str) ?;
153
+ let mut query_cursor = QueryCursor :: new ( ) ;
154
+
155
+ trace ! ( "running tree-sitter query for node" ; "node" => format!( "{:?}" , parent. unwrap( ) ) , "node_text" => parent. unwrap( ) . utf8_text( self . source. as_bytes( ) ) . unwrap( ) ) ;
156
+
157
+ for m in query_cursor. matches ( & query, parent. unwrap ( ) , self . source . as_bytes ( ) ) {
158
+ for capture in m. captures {
159
+ let start = capture. node . start_position ( ) ;
160
+ let end = capture. node . end_position ( ) ;
161
+
162
+ locations. push ( Location {
163
+ uri : Url :: from_file_path ( path) . unwrap ( ) ,
164
+ range : Range {
165
+ start : Position {
166
+ line : start. row as u32 ,
167
+ character : start. column as u32 ,
168
+ } ,
169
+ end : Position {
170
+ line : end. row as u32 ,
171
+ character : end. column as u32 ,
172
+ } ,
173
+ } ,
174
+ } ) ;
175
+ }
176
+ }
177
+
178
+ if !locations. is_empty ( ) {
179
+ break ;
180
+ }
181
+
182
+ parent = parent. unwrap ( ) . parent ( ) ;
183
+ }
184
+
185
+ Ok ( locations)
186
+ }
187
+
188
+ fn simple_global_search ( & self , path : & Path , query_str : & str ) -> Result < Vec < Location > > {
189
+ let query = Query :: new ( tree_sitter_glsl:: language ( ) , query_str) ?;
125
190
let mut query_cursor = QueryCursor :: new ( ) ;
126
191
127
192
let mut locations = vec ! [ ] ;
128
193
129
- for m in query_cursor. matches ( & ts_query , self . root_node ( ) , self . source . as_bytes ( ) ) {
194
+ for m in query_cursor. matches ( & query , self . root_node ( ) , self . source . as_bytes ( ) ) {
130
195
for capture in m. captures {
131
196
let start = capture. node . start_position ( ) ;
132
197
let end = capture. node . end_position ( ) ;
@@ -147,7 +212,7 @@ impl<'a> ParserContext<'a> {
147
212
}
148
213
}
149
214
150
- Ok ( Some ( locations) )
215
+ Ok ( locations)
151
216
}
152
217
153
218
fn root_node ( & self ) -> Node {
0 commit comments