@@ -14,7 +14,7 @@ macro_rules! find_function_def_str {
1414 (
1515 (function_declarator
1616 (identifier) @function)
17- (#match? @function "{} ")
17+ (#match? @function "^{}$ ")
1818 )
1919 "#
2020 } ;
@@ -26,11 +26,33 @@ macro_rules! find_function_refs_str {
2626 (
2727 (call_expression
2828 (identifier) @call)
29- (#match? @call "{} ")
29+ (#match? @call "^{}$ ")
3030 )
3131 "#
3232 } ;
3333}
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+
3456pub struct ParserContext < ' a > {
3557 source : String ,
3658 tree : Tree ,
@@ -65,40 +87,23 @@ impl<'a> ParserContext<'a> {
6587 None => return Ok ( None ) ,
6688 } ;
6789
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 ( ) ) {
6993 ( _, "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) ?
71102 }
72103 _ => return Ok ( None ) ,
73104 } ;
74105
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) ) ;
102107
103108 Ok ( Some ( locations) )
104109 }
@@ -114,19 +119,79 @@ impl<'a> ParserContext<'a> {
114119 None => return Ok ( None ) ,
115120 } ;
116121
117- let query = match ( current_node. kind ( ) , parent. kind ( ) ) {
122+ let locations = match ( current_node. kind ( ) , parent. kind ( ) ) {
118123 ( _, "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) ?
120126 }
121127 _ => return Ok ( None ) ,
122128 } ;
123129
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) ?;
125190 let mut query_cursor = QueryCursor :: new ( ) ;
126191
127192 let mut locations = vec ! [ ] ;
128193
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 ( ) ) {
130195 for capture in m. captures {
131196 let start = capture. node . start_position ( ) ;
132197 let end = capture. node . end_position ( ) ;
@@ -147,7 +212,7 @@ impl<'a> ParserContext<'a> {
147212 }
148213 }
149214
150- Ok ( Some ( locations) )
215+ Ok ( locations)
151216 }
152217
153218 fn root_node ( & self ) -> Node {
0 commit comments