Skip to main content

infiniloom_engine/parser/
query_builder.rs

1//! Tree-sitter query builders for symbol extraction
2//!
3//! This module contains functions that create compiled tree-sitter queries
4//! for extracting symbols from source code. Each language has two query types:
5//!
6//! - **Basic queries** (`*_query`): Extract only symbol definitions
7//! - **Super-queries** (`*_super_query`): Extract symbols AND imports in one pass
8//!
9//! Super-queries are more efficient for full file analysis as they require
10//! only a single AST traversal.
11
12use super::core::ParserError;
13use tree_sitter::Query;
14
15// ==========================================================================
16// Python
17// ==========================================================================
18
19pub fn python_query() -> Result<Query, ParserError> {
20    let query_string = r#"
21        (function_definition
22          name: (identifier) @name) @function
23
24        (class_definition
25          name: (identifier) @name) @class
26
27        (class_definition
28          body: (block
29            (function_definition
30              name: (identifier) @name))) @method
31    "#;
32
33    Query::new(&tree_sitter_python::LANGUAGE.into(), query_string)
34        .map_err(|e| ParserError::QueryError(e.to_string()))
35}
36
37pub fn python_super_query() -> Result<Query, ParserError> {
38    let query_string = r#"
39        ; Functions
40        (function_definition
41          name: (identifier) @name) @function
42
43        ; Classes
44        (class_definition
45          name: (identifier) @name) @class
46
47        ; Methods inside classes
48        (class_definition
49          body: (block
50            (function_definition
51              name: (identifier) @name))) @method
52
53        ; Imports
54        (import_statement) @import
55        (import_from_statement) @import
56    "#;
57
58    Query::new(&tree_sitter_python::LANGUAGE.into(), query_string)
59        .map_err(|e| ParserError::QueryError(e.to_string()))
60}
61
62// ==========================================================================
63// JavaScript
64// ==========================================================================
65
66pub fn javascript_query() -> Result<Query, ParserError> {
67    let query_string = r#"
68        (function_declaration
69          name: (_) @name) @function
70
71        (class_declaration
72          name: (_) @name) @class
73
74        (method_definition
75          name: (property_identifier) @name) @method
76
77        (arrow_function) @function
78
79        (function_expression) @function
80    "#;
81
82    Query::new(&tree_sitter_javascript::LANGUAGE.into(), query_string)
83        .map_err(|e| ParserError::QueryError(e.to_string()))
84}
85
86pub fn javascript_super_query() -> Result<Query, ParserError> {
87    let query_string = r#"
88        ; Functions
89        (function_declaration
90          name: (identifier) @name) @function
91
92        ; Async functions
93        (function_declaration
94          "async"
95          name: (identifier) @name) @function
96
97        ; Generator functions
98        (generator_function_declaration
99          name: (identifier) @name) @function
100
101        ; Async generator functions
102        (generator_function_declaration
103          "async"
104          name: (identifier) @name) @function
105
106        ; Classes
107        (class_declaration
108          name: (identifier) @name) @class
109
110        ; Methods
111        (method_definition
112          name: (property_identifier) @name) @method
113
114        ; Async methods
115        (method_definition
116          "async"
117          name: (property_identifier) @name) @method
118
119        ; Generator methods
120        (method_definition
121          "*"
122          name: (property_identifier) @name) @method
123
124        ; Arrow functions (named via variable)
125        (lexical_declaration
126          (variable_declarator
127            name: (identifier) @name
128            value: (arrow_function))) @function
129
130        ; Async arrow functions (named via variable)
131        (lexical_declaration
132          (variable_declarator
133            name: (identifier) @name
134            value: (arrow_function
135              "async"))) @function
136
137        ; Imports
138        (import_statement) @import
139
140        ; Exports
141        (export_statement) @export
142    "#;
143
144    Query::new(&tree_sitter_javascript::LANGUAGE.into(), query_string)
145        .map_err(|e| ParserError::QueryError(e.to_string()))
146}
147
148// ==========================================================================
149// TypeScript
150// ==========================================================================
151
152pub fn typescript_query() -> Result<Query, ParserError> {
153    let query_string = r#"
154        (function_declaration
155          name: (identifier) @name) @function
156
157        (class_declaration
158          name: (type_identifier) @name) @class
159
160        (interface_declaration
161          name: (type_identifier) @name) @interface
162
163        (method_definition
164          name: (property_identifier) @name) @method
165
166        (enum_declaration
167          name: (identifier) @name) @enum
168
169        ; Arrow functions (named via variable) - Bug #1 fix
170        (lexical_declaration
171          (variable_declarator
172            name: (identifier) @name
173            value: (arrow_function))) @function
174    "#;
175
176    Query::new(&tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(), query_string)
177        .map_err(|e| ParserError::QueryError(e.to_string()))
178}
179
180pub fn typescript_super_query() -> Result<Query, ParserError> {
181    let query_string = r#"
182        ; Functions
183        (function_declaration
184          name: (identifier) @name) @function
185
186        ; Async functions
187        (function_declaration
188          "async"
189          name: (identifier) @name) @function
190
191        ; Generator functions
192        (generator_function_declaration
193          name: (identifier) @name) @function
194
195        ; Classes
196        (class_declaration
197          name: (type_identifier) @name) @class
198
199        ; Decorated classes (NestJS, Angular, etc.)
200        (export_statement
201          (decorator
202            (call_expression
203              function: (identifier)))
204          declaration: (class_declaration
205            name: (type_identifier) @name)) @class
206
207        ; Interfaces
208        (interface_declaration
209          name: (type_identifier) @name) @interface
210
211        ; Methods
212        (method_definition
213          name: (property_identifier) @name) @method
214
215        ; Decorated methods
216        (method_definition
217          (decorator)
218          name: (property_identifier) @name) @method
219
220        ; Enums
221        (enum_declaration
222          name: (identifier) @name) @enum
223
224        ; Arrow functions (named via variable) - Bug #1 fix
225        (lexical_declaration
226          (variable_declarator
227            name: (identifier) @name
228            value: (arrow_function))) @function
229
230        ; Arrow functions (exported)
231        (export_statement
232          declaration: (lexical_declaration
233            (variable_declarator
234              name: (identifier) @name
235              value: (arrow_function)))) @function
236
237        ; Type aliases
238        (type_alias_declaration
239          name: (type_identifier) @name) @struct
240
241        ; Imports
242        (import_statement) @import
243
244        ; Exports (re-exports)
245        (export_statement) @export
246
247        ; Decorators (standalone capture for analysis)
248        (decorator) @decorator
249    "#;
250
251    Query::new(&tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(), query_string)
252        .map_err(|e| ParserError::QueryError(e.to_string()))
253}
254
255// ==========================================================================
256// Rust
257// ==========================================================================
258
259pub fn rust_query() -> Result<Query, ParserError> {
260    let query_string = r#"
261        (function_item
262          name: (identifier) @name) @function
263
264        (struct_item
265          name: (type_identifier) @name) @struct
266
267        (enum_item
268          name: (type_identifier) @name) @enum
269
270        (trait_item
271          name: (type_identifier) @name) @trait
272    "#;
273
274    Query::new(&tree_sitter_rust::LANGUAGE.into(), query_string)
275        .map_err(|e| ParserError::QueryError(e.to_string()))
276}
277
278pub fn rust_super_query() -> Result<Query, ParserError> {
279    let query_string = r#"
280        ; Functions
281        (function_item
282          name: (identifier) @name) @function
283
284        ; Structs
285        (struct_item
286          name: (type_identifier) @name) @struct
287
288        ; Enums
289        (enum_item
290          name: (type_identifier) @name) @enum
291
292        ; Traits
293        (trait_item
294          name: (type_identifier) @name) @trait
295
296        ; Use statements (imports)
297        (use_declaration) @import
298    "#;
299
300    Query::new(&tree_sitter_rust::LANGUAGE.into(), query_string)
301        .map_err(|e| ParserError::QueryError(e.to_string()))
302}
303
304// ==========================================================================
305// Go
306// ==========================================================================
307
308pub fn go_query() -> Result<Query, ParserError> {
309    let query_string = r#"
310        (function_declaration
311          name: (identifier) @name) @function
312
313        (method_declaration
314          name: (field_identifier) @name) @method
315
316        (type_declaration
317          (type_spec
318            name: (type_identifier) @name
319            type: (struct_type))) @struct
320
321        (type_declaration
322          (type_spec
323            name: (type_identifier) @name
324            type: (interface_type))) @interface
325    "#;
326
327    Query::new(&tree_sitter_go::LANGUAGE.into(), query_string)
328        .map_err(|e| ParserError::QueryError(e.to_string()))
329}
330
331pub fn go_super_query() -> Result<Query, ParserError> {
332    let query_string = r#"
333        ; Functions
334        (function_declaration
335          name: (identifier) @name) @function
336
337        ; Methods
338        (method_declaration
339          name: (field_identifier) @name) @method
340
341        ; Structs
342        (type_declaration
343          (type_spec
344            name: (type_identifier) @name
345            type: (struct_type))) @struct
346
347        ; Interfaces
348        (type_declaration
349          (type_spec
350            name: (type_identifier) @name
351            type: (interface_type))) @interface
352
353        ; Imports
354        (import_declaration) @import
355    "#;
356
357    Query::new(&tree_sitter_go::LANGUAGE.into(), query_string)
358        .map_err(|e| ParserError::QueryError(e.to_string()))
359}
360
361// ==========================================================================
362// Java
363// ==========================================================================
364
365pub fn java_query() -> Result<Query, ParserError> {
366    let query_string = r#"
367        (method_declaration
368          name: (identifier) @name) @method
369
370        (class_declaration
371          name: (identifier) @name) @class
372
373        (interface_declaration
374          name: (identifier) @name) @interface
375
376        (enum_declaration
377          name: (identifier) @name) @enum
378    "#;
379
380    Query::new(&tree_sitter_java::LANGUAGE.into(), query_string)
381        .map_err(|e| ParserError::QueryError(e.to_string()))
382}
383
384pub fn java_super_query() -> Result<Query, ParserError> {
385    let query_string = r#"
386        ; Methods
387        (method_declaration
388          name: (identifier) @name) @method
389
390        ; Classes
391        (class_declaration
392          name: (identifier) @name) @class
393
394        ; Interfaces
395        (interface_declaration
396          name: (identifier) @name) @interface
397
398        ; Enums
399        (enum_declaration
400          name: (identifier) @name) @enum
401
402        ; Imports
403        (import_declaration) @import
404    "#;
405
406    Query::new(&tree_sitter_java::LANGUAGE.into(), query_string)
407        .map_err(|e| ParserError::QueryError(e.to_string()))
408}
409
410// ==========================================================================
411// C
412// ==========================================================================
413
414pub fn c_query() -> Result<Query, ParserError> {
415    let query_string = r#"
416        (function_definition
417          declarator: (function_declarator
418            declarator: (identifier) @name)) @function
419
420        (struct_specifier
421          name: (type_identifier) @name) @struct
422
423        (enum_specifier
424          name: (type_identifier) @name) @enum
425    "#;
426
427    Query::new(&tree_sitter_c::LANGUAGE.into(), query_string)
428        .map_err(|e| ParserError::QueryError(e.to_string()))
429}
430
431pub fn c_super_query() -> Result<Query, ParserError> {
432    let query_string = r#"
433        ; Functions
434        (function_definition
435          declarator: (function_declarator
436            declarator: (identifier) @name)) @function
437
438        ; Structs
439        (struct_specifier
440          name: (type_identifier) @name) @struct
441
442        ; Enums
443        (enum_specifier
444          name: (type_identifier) @name) @enum
445
446        ; Includes (imports)
447        (preproc_include) @import
448    "#;
449
450    Query::new(&tree_sitter_c::LANGUAGE.into(), query_string)
451        .map_err(|e| ParserError::QueryError(e.to_string()))
452}
453
454// ==========================================================================
455// C++
456// ==========================================================================
457
458pub fn cpp_query() -> Result<Query, ParserError> {
459    let query_string = r#"
460        (function_definition
461          declarator: (function_declarator
462            declarator: (identifier) @name)) @function
463
464        (class_specifier
465          name: (type_identifier) @name) @class
466
467        (struct_specifier
468          name: (type_identifier) @name) @struct
469
470        (enum_specifier
471          name: (type_identifier) @name) @enum
472    "#;
473
474    Query::new(&tree_sitter_cpp::LANGUAGE.into(), query_string)
475        .map_err(|e| ParserError::QueryError(e.to_string()))
476}
477
478pub fn cpp_super_query() -> Result<Query, ParserError> {
479    let query_string = r#"
480        ; Functions
481        (function_definition
482          declarator: (function_declarator
483            declarator: (identifier) @name)) @function
484
485        ; Classes
486        (class_specifier
487          name: (type_identifier) @name) @class
488
489        ; Structs
490        (struct_specifier
491          name: (type_identifier) @name) @struct
492
493        ; Enums
494        (enum_specifier
495          name: (type_identifier) @name) @enum
496
497        ; Includes (imports)
498        (preproc_include) @import
499    "#;
500
501    Query::new(&tree_sitter_cpp::LANGUAGE.into(), query_string)
502        .map_err(|e| ParserError::QueryError(e.to_string()))
503}
504
505// ==========================================================================
506// C#
507// ==========================================================================
508
509pub fn csharp_query() -> Result<Query, ParserError> {
510    let query_string = r#"
511        (method_declaration
512          name: (identifier) @name) @method
513
514        (class_declaration
515          name: (identifier) @name) @class
516
517        (interface_declaration
518          name: (identifier) @name) @interface
519
520        (struct_declaration
521          name: (identifier) @name) @struct
522
523        (enum_declaration
524          name: (identifier) @name) @enum
525    "#;
526
527    Query::new(&tree_sitter_c_sharp::LANGUAGE.into(), query_string)
528        .map_err(|e| ParserError::QueryError(e.to_string()))
529}
530
531pub fn csharp_super_query() -> Result<Query, ParserError> {
532    let query_string = r#"
533        ; Methods
534        (method_declaration
535          name: (identifier) @name) @method
536
537        ; Classes
538        (class_declaration
539          name: (identifier) @name) @class
540
541        ; Interfaces
542        (interface_declaration
543          name: (identifier) @name) @interface
544
545        ; Structs
546        (struct_declaration
547          name: (identifier) @name) @struct
548
549        ; Enums
550        (enum_declaration
551          name: (identifier) @name) @enum
552
553        ; Imports (using directives)
554        (using_directive) @import
555    "#;
556
557    Query::new(&tree_sitter_c_sharp::LANGUAGE.into(), query_string)
558        .map_err(|e| ParserError::QueryError(e.to_string()))
559}
560
561// ==========================================================================
562// Ruby
563// ==========================================================================
564
565pub fn ruby_query() -> Result<Query, ParserError> {
566    let query_string = r#"
567        (method
568          name: (identifier) @name) @function
569
570        (class
571          name: (constant) @name) @class
572
573        (module
574          name: (constant) @name) @class
575    "#;
576
577    Query::new(&tree_sitter_ruby::LANGUAGE.into(), query_string)
578        .map_err(|e| ParserError::QueryError(e.to_string()))
579}
580
581pub fn ruby_super_query() -> Result<Query, ParserError> {
582    let query_string = r#"
583        ; Methods
584        (method
585          name: (identifier) @name) @function
586
587        ; Classes
588        (class
589          name: (constant) @name) @class
590
591        ; Modules
592        (module
593          name: (constant) @name) @class
594
595        ; Requires (imports)
596        (call
597          method: (identifier) @_method
598          (#match? @_method "^require")
599          arguments: (argument_list)) @import
600    "#;
601
602    Query::new(&tree_sitter_ruby::LANGUAGE.into(), query_string)
603        .map_err(|e| ParserError::QueryError(e.to_string()))
604}
605
606// ==========================================================================
607// Bash
608// ==========================================================================
609
610pub fn bash_query() -> Result<Query, ParserError> {
611    let query_string = r#"
612        (function_definition
613          name: (word) @name) @function
614    "#;
615
616    Query::new(&tree_sitter_bash::LANGUAGE.into(), query_string)
617        .map_err(|e| ParserError::QueryError(e.to_string()))
618}
619
620pub fn bash_super_query() -> Result<Query, ParserError> {
621    let query_string = r#"
622        ; Functions
623        (function_definition
624          name: (word) @name) @function
625
626        ; Source commands (imports)
627        (command
628          name: (command_name) @_cmd
629          (#match? @_cmd "^(source|\\.)$")
630          argument: (word)) @import
631    "#;
632
633    Query::new(&tree_sitter_bash::LANGUAGE.into(), query_string)
634        .map_err(|e| ParserError::QueryError(e.to_string()))
635}
636
637// ==========================================================================
638// PHP
639// ==========================================================================
640
641pub fn php_query() -> Result<Query, ParserError> {
642    let query_string = r#"
643        (function_definition
644          name: (name) @name) @function
645
646        (method_declaration
647          name: (name) @name) @method
648
649        (class_declaration
650          name: (name) @name) @class
651
652        (interface_declaration
653          name: (name) @name) @interface
654
655        (trait_declaration
656          name: (name) @name) @trait
657    "#;
658
659    Query::new(&tree_sitter_php::LANGUAGE_PHP.into(), query_string)
660        .map_err(|e| ParserError::QueryError(e.to_string()))
661}
662
663pub fn php_super_query() -> Result<Query, ParserError> {
664    let query_string = r#"
665        ; Functions
666        (function_definition
667          name: (name) @name) @function
668
669        ; Methods
670        (method_declaration
671          name: (name) @name) @method
672
673        ; Classes
674        (class_declaration
675          name: (name) @name) @class
676
677        ; Interfaces
678        (interface_declaration
679          name: (name) @name) @interface
680
681        ; Traits
682        (trait_declaration
683          name: (name) @name) @trait
684
685        ; Use statements (imports)
686        (namespace_use_declaration) @import
687    "#;
688
689    Query::new(&tree_sitter_php::LANGUAGE_PHP.into(), query_string)
690        .map_err(|e| ParserError::QueryError(e.to_string()))
691}
692
693// ==========================================================================
694// Kotlin
695// ==========================================================================
696
697pub fn kotlin_query() -> Result<Query, ParserError> {
698    let query_string = r#"
699        (function_declaration
700          name: (_) @name) @function
701
702        (class_declaration
703          name: (_) @name) @class
704
705        (object_declaration
706          name: (_) @name) @class
707    "#;
708
709    Query::new(&tree_sitter_kotlin_ng::LANGUAGE.into(), query_string)
710        .map_err(|e| ParserError::QueryError(e.to_string()))
711}
712
713pub fn kotlin_super_query() -> Result<Query, ParserError> {
714    let query_string = r#"
715        ; Functions
716        (function_declaration
717          name: (_) @name) @function
718
719        ; Classes
720        (class_declaration
721          name: (_) @name) @class
722
723        ; Objects
724        (object_declaration
725          name: (_) @name) @class
726
727        ; Imports
728        (import) @import
729    "#;
730
731    Query::new(&tree_sitter_kotlin_ng::LANGUAGE.into(), query_string)
732        .map_err(|e| ParserError::QueryError(e.to_string()))
733}
734
735// ==========================================================================
736// Swift
737// ==========================================================================
738
739pub fn swift_query() -> Result<Query, ParserError> {
740    let query_string = r#"
741        (function_declaration
742          name: (simple_identifier) @name) @function
743
744        (class_declaration
745          declaration_kind: "class"
746          name: (type_identifier) @name) @class
747
748        (protocol_declaration
749          name: (type_identifier) @name) @interface
750
751        (class_declaration
752          declaration_kind: "struct"
753          name: (type_identifier) @name) @struct
754
755        (class_declaration
756          declaration_kind: "enum"
757          name: (type_identifier) @name) @enum
758    "#;
759
760    Query::new(&tree_sitter_swift::LANGUAGE.into(), query_string)
761        .map_err(|e| ParserError::QueryError(e.to_string()))
762}
763
764pub fn swift_super_query() -> Result<Query, ParserError> {
765    let query_string = r#"
766        ; Functions
767        (function_declaration
768          name: (simple_identifier) @name) @function
769
770        ; Classes
771        (class_declaration
772          declaration_kind: "class"
773          name: (type_identifier) @name) @class
774
775        ; Protocols (interfaces)
776        (protocol_declaration
777          name: (type_identifier) @name) @interface
778
779        ; Structs
780        (class_declaration
781          declaration_kind: "struct"
782          name: (type_identifier) @name) @struct
783
784        ; Enums
785        (class_declaration
786          declaration_kind: "enum"
787          name: (type_identifier) @name) @enum
788
789        ; Imports
790        (import_declaration) @import
791    "#;
792
793    Query::new(&tree_sitter_swift::LANGUAGE.into(), query_string)
794        .map_err(|e| ParserError::QueryError(e.to_string()))
795}
796
797// ==========================================================================
798// Scala
799// ==========================================================================
800
801pub fn scala_query() -> Result<Query, ParserError> {
802    let query_string = r#"
803        (function_definition
804          name: (identifier) @name) @function
805
806        (class_definition
807          name: (identifier) @name) @class
808
809        (object_definition
810          name: (identifier) @name) @class
811
812        (trait_definition
813          name: (identifier) @name) @trait
814    "#;
815
816    Query::new(&tree_sitter_scala::LANGUAGE.into(), query_string)
817        .map_err(|e| ParserError::QueryError(e.to_string()))
818}
819
820pub fn scala_super_query() -> Result<Query, ParserError> {
821    let query_string = r#"
822        ; Functions
823        (function_definition
824          name: (identifier) @name) @function
825
826        ; Classes
827        (class_definition
828          name: (identifier) @name) @class
829
830        ; Objects
831        (object_definition
832          name: (identifier) @name) @class
833
834        ; Traits
835        (trait_definition
836          name: (identifier) @name) @trait
837
838        ; Imports
839        (import_declaration) @import
840    "#;
841
842    Query::new(&tree_sitter_scala::LANGUAGE.into(), query_string)
843        .map_err(|e| ParserError::QueryError(e.to_string()))
844}
845
846// ==========================================================================
847// Haskell
848// ==========================================================================
849
850pub fn haskell_query() -> Result<Query, ParserError> {
851    let query_string = r#"
852        (function
853          name: (variable) @name) @function
854
855        (signature
856          name: (variable) @name) @function
857
858        (function
859          name: (prefix_id) @name) @function
860
861        (signature
862          name: (prefix_id) @name) @function
863
864        (newtype
865          name: (name) @name) @struct
866
867        (type_synomym
868          name: (name) @name) @struct
869
870        (data_type
871          name: (name) @name) @enum
872    "#;
873
874    Query::new(&tree_sitter_haskell::LANGUAGE.into(), query_string)
875        .map_err(|e| ParserError::QueryError(e.to_string()))
876}
877
878pub fn haskell_super_query() -> Result<Query, ParserError> {
879    let query_string = r#"
880        ; Functions
881        (function
882          name: (variable) @name) @function
883
884        ; Type signatures
885        (signature
886          name: (variable) @name) @function
887
888        ; Type aliases
889        (function
890          name: (prefix_id) @name) @function
891
892        (signature
893          name: (prefix_id) @name) @function
894
895        ; Newtypes
896        (newtype
897          name: (name) @name) @struct
898
899        ; ADTs (data declarations)
900        (type_synomym
901          name: (name) @name) @struct
902
903        (data_type
904          name: (name) @name) @enum
905
906        ; Imports
907        (import) @import
908    "#;
909
910    Query::new(&tree_sitter_haskell::LANGUAGE.into(), query_string)
911        .map_err(|e| ParserError::QueryError(e.to_string()))
912}
913
914// ==========================================================================
915// Elixir
916// ==========================================================================
917
918pub fn elixir_query() -> Result<Query, ParserError> {
919    let query_string = r#"
920        (call
921          target: (identifier) @_type
922          (#match? @_type "^(def|defp|defmacro|defmacrop)$")
923          (arguments
924            (call
925              target: (identifier) @name))) @function
926
927        (call
928          target: (identifier) @_type
929          (#match? @_type "^defmodule$")
930          (arguments
931            (alias) @name)) @class
932    "#;
933
934    Query::new(&tree_sitter_elixir::LANGUAGE.into(), query_string)
935        .map_err(|e| ParserError::QueryError(e.to_string()))
936}
937
938pub fn elixir_super_query() -> Result<Query, ParserError> {
939    let query_string = r#"
940        ; Functions (def, defp, defmacro)
941        (call
942          target: (identifier) @_type
943          (#match? @_type "^(def|defp|defmacro|defmacrop)$")
944          (arguments
945            (call
946              target: (identifier) @name))) @function
947
948        ; Modules
949        (call
950          target: (identifier) @_type
951          (#match? @_type "^defmodule$")
952          (arguments
953            (alias) @name)) @class
954
955        ; Imports (alias, import, use, require)
956        (call
957          target: (identifier) @_type
958          (#match? @_type "^(alias|import|use|require)$")) @import
959    "#;
960
961    Query::new(&tree_sitter_elixir::LANGUAGE.into(), query_string)
962        .map_err(|e| ParserError::QueryError(e.to_string()))
963}
964
965// ==========================================================================
966// Clojure
967// ==========================================================================
968
969/// NOTE: Clojure queries are unavailable because tree-sitter-clojure 0.1.0
970/// depends on tree-sitter ^0.25 (normal dep), which conflicts with tree-sitter 0.26.
971pub fn clojure_query() -> Result<Query, ParserError> {
972    Err(ParserError::QueryError(
973        "Clojure queries unavailable: tree-sitter-clojure incompatible with tree-sitter 0.26"
974            .to_owned(),
975    ))
976}
977
978pub fn clojure_super_query() -> Result<Query, ParserError> {
979    Err(ParserError::QueryError(
980        "Clojure queries unavailable: tree-sitter-clojure incompatible with tree-sitter 0.26"
981            .to_owned(),
982    ))
983}
984
985// ==========================================================================
986// OCaml
987// ==========================================================================
988
989pub fn ocaml_query() -> Result<Query, ParserError> {
990    // Note: OCaml grammar uses different field names than expected
991    // module_binding doesn't have a "name" field - use child pattern instead
992    let query_string = r#"
993        (value_definition
994          (let_binding
995            pattern: (value_name) @name)) @function
996
997        (type_definition
998          (type_binding
999            name: (type_constructor) @name)) @struct
1000
1001        (module_definition
1002          (module_binding
1003            (module_name) @name)) @class
1004    "#;
1005
1006    Query::new(&tree_sitter_ocaml::LANGUAGE_OCAML.into(), query_string)
1007        .map_err(|e| ParserError::QueryError(e.to_string()))
1008}
1009
1010pub fn ocaml_super_query() -> Result<Query, ParserError> {
1011    // Note: OCaml grammar uses different field names than expected
1012    // module_binding doesn't have a "name" field - use child pattern instead
1013    let query_string = r#"
1014        ; Functions (let bindings)
1015        (value_definition
1016          (let_binding
1017            pattern: (value_name) @name)) @function
1018
1019        ; Types
1020        (type_definition
1021          (type_binding
1022            name: (type_constructor) @name)) @struct
1023
1024        ; Modules
1025        (module_definition
1026          (module_binding
1027            (module_name) @name)) @class
1028
1029        ; Opens (imports)
1030        (open_module) @import
1031    "#;
1032
1033    Query::new(&tree_sitter_ocaml::LANGUAGE_OCAML.into(), query_string)
1034        .map_err(|e| ParserError::QueryError(e.to_string()))
1035}
1036
1037// ==========================================================================
1038// Lua
1039// ==========================================================================
1040
1041pub fn lua_query() -> Result<Query, ParserError> {
1042    let query_string = r#"
1043        (function_declaration
1044          name: (identifier) @name) @function
1045
1046        (function_declaration
1047          name: (dot_index_expression) @name) @method
1048
1049        (function_declaration
1050          name: (method_index_expression) @name) @method
1051    "#;
1052
1053    Query::new(&tree_sitter_lua::LANGUAGE.into(), query_string)
1054        .map_err(|e| ParserError::QueryError(e.to_string()))
1055}
1056
1057pub fn lua_super_query() -> Result<Query, ParserError> {
1058    let query_string = r#"
1059        ; Global functions
1060        (function_declaration
1061          name: (identifier) @name) @function
1062
1063        ; Method-like functions
1064        (function_declaration
1065          name: (dot_index_expression) @name) @method
1066
1067        (function_declaration
1068          name: (method_index_expression) @name) @method
1069
1070        ; Requires (imports)
1071        (function_call
1072          name: (variable
1073            (identifier) @_func)
1074          (#eq? @_func "require")
1075          arguments: (arguments)) @import
1076    "#;
1077
1078    Query::new(&tree_sitter_lua::LANGUAGE.into(), query_string)
1079        .map_err(|e| ParserError::QueryError(e.to_string()))
1080}
1081
1082// ==========================================================================
1083// R
1084// ==========================================================================
1085
1086pub fn r_query() -> Result<Query, ParserError> {
1087    let query_string = r#"
1088        (binary_operator
1089          lhs: (identifier) @name
1090          operator: "<-"
1091          rhs: (function_definition)) @function
1092
1093        (binary_operator
1094          lhs: (identifier) @name
1095          operator: "="
1096          rhs: (function_definition)) @function
1097    "#;
1098
1099    Query::new(&tree_sitter_r::LANGUAGE.into(), query_string)
1100        .map_err(|e| ParserError::QueryError(e.to_string()))
1101}
1102
1103pub fn r_super_query() -> Result<Query, ParserError> {
1104    let query_string = r#"
1105        ; Functions (left assignment)
1106        (binary_operator
1107          lhs: (identifier) @name
1108          operator: "<-"
1109          rhs: (function_definition)) @function
1110
1111        ; Functions (equals assignment)
1112        (binary_operator
1113          lhs: (identifier) @name
1114          operator: "="
1115          rhs: (function_definition)) @function
1116
1117        ; Library/require calls (imports)
1118        (call
1119          function: (identifier) @_func
1120          (#match? @_func "^(library|require|source)$")) @import
1121    "#;
1122
1123    Query::new(&tree_sitter_r::LANGUAGE.into(), query_string)
1124        .map_err(|e| ParserError::QueryError(e.to_string()))
1125}
1126
1127// ==========================================================================
1128// HCL
1129// ==========================================================================
1130
1131pub fn hcl_query() -> Result<Query, ParserError> {
1132    let query_string = r#"
1133        ; locals blocks (no label, identifier-only)
1134        (block
1135          (identifier) @name
1136          (body)
1137          (#eq? @name "locals")) @constant
1138
1139        ; module blocks
1140        (block
1141          (identifier) @_type
1142          (string_lit
1143            (template_literal) @name)
1144          (#eq? @_type "module")) @module
1145
1146        ; dynamic blocks
1147        (block
1148          (identifier) @_type
1149          (string_lit
1150            (template_literal) @name)
1151          (#eq? @_type "dynamic")) @function
1152
1153        ; Single-label blocks (variable, output, etc.)
1154        (block
1155          (identifier) @_type
1156          (string_lit
1157            (template_literal) @name)) @function
1158
1159        ; Double-label blocks (resource, data, etc.)
1160        (block
1161          (identifier) @_type
1162          (string_lit
1163            (template_literal) @_subtype)
1164          (string_lit
1165            (template_literal) @name)) @function
1166    "#;
1167
1168    Query::new(&tree_sitter_hcl::LANGUAGE.into(), query_string)
1169        .map_err(|e| ParserError::QueryError(e.to_string()))
1170}
1171
1172pub fn hcl_super_query() -> Result<Query, ParserError> {
1173    let query_string = r#"
1174        ; locals blocks (no label, identifier-only)
1175        (block
1176          (identifier) @name
1177          (body)
1178          (#eq? @name "locals")) @constant
1179
1180        ; module blocks
1181        (block
1182          (identifier) @_type
1183          (string_lit
1184            (template_literal) @name)
1185          (#eq? @_type "module")) @module
1186
1187        ; dynamic blocks
1188        (block
1189          (identifier) @_type
1190          (string_lit
1191            (template_literal) @name)
1192          (#eq? @_type "dynamic")) @function
1193
1194        ; Single-label blocks (variable, output, etc.)
1195        (block
1196          (identifier) @_type
1197          (string_lit
1198            (template_literal) @name)) @function
1199
1200        ; Double-label blocks (resource, data, etc.)
1201        (block
1202          (identifier) @_type
1203          (string_lit
1204            (template_literal) @_subtype)
1205          (string_lit
1206            (template_literal) @name)) @function
1207    "#;
1208
1209    Query::new(&tree_sitter_hcl::LANGUAGE.into(), query_string)
1210        .map_err(|e| ParserError::QueryError(e.to_string()))
1211}
1212
1213// ==========================================================================
1214// Zig
1215// ==========================================================================
1216
1217pub fn zig_query() -> Result<Query, ParserError> {
1218    let query_string = r#"
1219        (function_declaration
1220          name: (identifier) @name) @function
1221
1222        (test_declaration
1223          (string) @name) @function
1224    "#;
1225
1226    Query::new(&tree_sitter_zig::LANGUAGE.into(), query_string)
1227        .map_err(|e| ParserError::QueryError(e.to_string()))
1228}
1229
1230pub fn zig_super_query() -> Result<Query, ParserError> {
1231    let query_string = r#"
1232        ; Function declarations
1233        (function_declaration
1234          name: (identifier) @name) @function
1235
1236        ; Test declarations
1237        (test_declaration
1238          (string) @name) @function
1239
1240        ; Imports (const x = @import("..."))
1241        (variable_declaration
1242          (identifier) @name
1243          (builtin_function
1244            (builtin_identifier) @_builtin
1245            (#eq? @_builtin "@import"))) @import
1246    "#;
1247
1248    Query::new(&tree_sitter_zig::LANGUAGE.into(), query_string)
1249        .map_err(|e| ParserError::QueryError(e.to_string()))
1250}
1251
1252// ==========================================================================
1253// Dart
1254// ==========================================================================
1255
1256pub fn dart_query() -> Result<Query, ParserError> {
1257    let query_string = r#"
1258        (function_signature
1259          name: (identifier) @name) @function
1260
1261        (class_definition
1262          name: (identifier) @name) @class
1263
1264        (method_signature
1265          (function_signature
1266            name: (identifier) @name)) @method
1267
1268        (enum_declaration
1269          name: (identifier) @name) @enum
1270
1271        (mixin_declaration
1272          (identifier) @name) @class
1273    "#;
1274
1275    Query::new(&tree_sitter_dart_orchard::LANGUAGE.into(), query_string)
1276        .map_err(|e| ParserError::QueryError(e.to_string()))
1277}
1278
1279pub fn dart_super_query() -> Result<Query, ParserError> {
1280    let query_string = r#"
1281        ; Functions
1282        (function_signature
1283          name: (identifier) @name) @function
1284
1285        ; Classes
1286        (class_definition
1287          name: (identifier) @name) @class
1288
1289        ; Methods
1290        (method_signature
1291          (function_signature
1292            name: (identifier) @name)) @method
1293
1294        ; Enums
1295        (enum_declaration
1296          name: (identifier) @name) @enum
1297
1298        ; Mixins
1299        (mixin_declaration
1300          (identifier) @name) @class
1301
1302        ; Imports
1303        (import_or_export) @import
1304    "#;
1305
1306    Query::new(&tree_sitter_dart_orchard::LANGUAGE.into(), query_string)
1307        .map_err(|e| ParserError::QueryError(e.to_string()))
1308}
1309
1310#[cfg(test)]
1311mod tests {
1312    use super::*;
1313
1314    #[test]
1315    fn test_python_queries() {
1316        assert!(python_query().is_ok());
1317        assert!(python_super_query().is_ok());
1318    }
1319
1320    #[test]
1321    fn test_javascript_queries() {
1322        assert!(javascript_query().is_ok());
1323        assert!(javascript_super_query().is_ok());
1324    }
1325
1326    #[test]
1327    fn test_typescript_queries() {
1328        assert!(typescript_query().is_ok());
1329        assert!(typescript_super_query().is_ok());
1330    }
1331
1332    #[test]
1333    fn test_rust_queries() {
1334        assert!(rust_query().is_ok());
1335        assert!(rust_super_query().is_ok());
1336    }
1337
1338    #[test]
1339    fn test_go_queries() {
1340        assert!(go_query().is_ok());
1341        assert!(go_super_query().is_ok());
1342    }
1343
1344    #[test]
1345    fn test_java_queries() {
1346        assert!(java_query().is_ok());
1347        assert!(java_super_query().is_ok());
1348    }
1349
1350    #[test]
1351    fn test_c_queries() {
1352        assert!(c_query().is_ok());
1353        assert!(c_super_query().is_ok());
1354    }
1355
1356    #[test]
1357    fn test_cpp_queries() {
1358        assert!(cpp_query().is_ok());
1359        assert!(cpp_super_query().is_ok());
1360    }
1361
1362    #[test]
1363    fn test_csharp_queries() {
1364        assert!(csharp_query().is_ok());
1365        assert!(csharp_super_query().is_ok());
1366    }
1367
1368    #[test]
1369    fn test_ruby_queries() {
1370        assert!(ruby_query().is_ok());
1371        assert!(ruby_super_query().is_ok());
1372    }
1373
1374    #[test]
1375    fn test_bash_queries() {
1376        assert!(bash_query().is_ok());
1377        assert!(bash_super_query().is_ok());
1378    }
1379
1380    #[test]
1381    fn test_php_queries() {
1382        assert!(php_query().is_ok());
1383        assert!(php_super_query().is_ok());
1384    }
1385
1386    #[test]
1387    fn test_kotlin_queries() {
1388        assert!(kotlin_query().is_ok());
1389        assert!(kotlin_super_query().is_ok());
1390    }
1391
1392    #[test]
1393    fn test_swift_queries() {
1394        assert!(swift_query().is_ok());
1395        assert!(swift_super_query().is_ok());
1396    }
1397
1398    #[test]
1399    fn test_scala_queries() {
1400        assert!(scala_query().is_ok());
1401        assert!(scala_super_query().is_ok());
1402    }
1403
1404    #[test]
1405    fn test_haskell_queries() {
1406        assert!(haskell_query().is_ok());
1407        assert!(haskell_super_query().is_ok());
1408    }
1409
1410    #[test]
1411    fn test_elixir_queries() {
1412        assert!(elixir_query().is_ok());
1413        assert!(elixir_super_query().is_ok());
1414    }
1415
1416    #[test]
1417    fn test_clojure_queries() {
1418        // Clojure queries are expected to return errors since tree-sitter-clojure
1419        // is incompatible with tree-sitter 0.26
1420        assert!(clojure_query().is_err());
1421        assert!(clojure_super_query().is_err());
1422    }
1423
1424    #[test]
1425    fn test_ocaml_queries() {
1426        let result = ocaml_query();
1427        if let Err(ref e) = result {
1428            eprintln!("OCaml query error: {:?}", e);
1429        }
1430        assert!(result.is_ok(), "ocaml_query failed: {:?}", result.err());
1431
1432        let super_result = ocaml_super_query();
1433        if let Err(ref e) = super_result {
1434            eprintln!("OCaml super query error: {:?}", e);
1435        }
1436        assert!(super_result.is_ok(), "ocaml_super_query failed: {:?}", super_result.err());
1437    }
1438
1439    #[test]
1440    fn test_lua_queries() {
1441        assert!(lua_query().is_ok());
1442        assert!(lua_super_query().is_ok());
1443    }
1444
1445    #[test]
1446    fn test_r_queries() {
1447        assert!(r_query().is_ok());
1448        assert!(r_super_query().is_ok());
1449    }
1450
1451    #[test]
1452    fn test_hcl_queries() {
1453        assert!(hcl_query().is_ok());
1454        assert!(hcl_super_query().is_ok());
1455    }
1456
1457    #[test]
1458    fn test_zig_queries() {
1459        assert!(zig_query().is_ok());
1460        assert!(zig_super_query().is_ok());
1461    }
1462
1463    #[test]
1464    fn test_dart_queries() {
1465        assert!(dart_query().is_ok());
1466        assert!(dart_super_query().is_ok());
1467    }
1468}