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        ; Classes
93        (class_declaration
94          name: (identifier) @name) @class
95
96        ; Methods
97        (method_definition
98          name: (property_identifier) @name) @method
99
100        ; Arrow functions (named via variable)
101        (lexical_declaration
102          (variable_declarator
103            name: (identifier) @name
104            value: (arrow_function))) @function
105
106        ; Imports
107        (import_statement) @import
108    "#;
109
110    Query::new(&tree_sitter_javascript::LANGUAGE.into(), query_string)
111        .map_err(|e| ParserError::QueryError(e.to_string()))
112}
113
114// ==========================================================================
115// TypeScript
116// ==========================================================================
117
118pub fn typescript_query() -> Result<Query, ParserError> {
119    let query_string = r#"
120        (function_declaration
121          name: (identifier) @name) @function
122
123        (class_declaration
124          name: (type_identifier) @name) @class
125
126        (interface_declaration
127          name: (type_identifier) @name) @interface
128
129        (method_definition
130          name: (property_identifier) @name) @method
131
132        (enum_declaration
133          name: (identifier) @name) @enum
134
135        ; Arrow functions (named via variable) - Bug #1 fix
136        (lexical_declaration
137          (variable_declarator
138            name: (identifier) @name
139            value: (arrow_function))) @function
140    "#;
141
142    Query::new(&tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(), query_string)
143        .map_err(|e| ParserError::QueryError(e.to_string()))
144}
145
146pub fn typescript_super_query() -> Result<Query, ParserError> {
147    let query_string = r#"
148        ; Functions
149        (function_declaration
150          name: (identifier) @name) @function
151
152        ; Classes
153        (class_declaration
154          name: (type_identifier) @name) @class
155
156        ; Interfaces
157        (interface_declaration
158          name: (type_identifier) @name) @interface
159
160        ; Methods
161        (method_definition
162          name: (property_identifier) @name) @method
163
164        ; Enums
165        (enum_declaration
166          name: (identifier) @name) @enum
167
168        ; Arrow functions (named via variable) - Bug #1 fix
169        (lexical_declaration
170          (variable_declarator
171            name: (identifier) @name
172            value: (arrow_function))) @function
173
174        ; Arrow functions (exported)
175        (export_statement
176          declaration: (lexical_declaration
177            (variable_declarator
178              name: (identifier) @name
179              value: (arrow_function)))) @function
180
181        ; Type aliases
182        (type_alias_declaration
183          name: (type_identifier) @name) @struct
184
185        ; Imports
186        (import_statement) @import
187
188        ; Exports (re-exports)
189        (export_statement) @export
190    "#;
191
192    Query::new(&tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(), query_string)
193        .map_err(|e| ParserError::QueryError(e.to_string()))
194}
195
196// ==========================================================================
197// Rust
198// ==========================================================================
199
200pub fn rust_query() -> Result<Query, ParserError> {
201    let query_string = r#"
202        (function_item
203          name: (identifier) @name) @function
204
205        (struct_item
206          name: (type_identifier) @name) @struct
207
208        (enum_item
209          name: (type_identifier) @name) @enum
210
211        (trait_item
212          name: (type_identifier) @name) @trait
213    "#;
214
215    Query::new(&tree_sitter_rust::LANGUAGE.into(), query_string)
216        .map_err(|e| ParserError::QueryError(e.to_string()))
217}
218
219pub fn rust_super_query() -> Result<Query, ParserError> {
220    let query_string = r#"
221        ; Functions
222        (function_item
223          name: (identifier) @name) @function
224
225        ; Structs
226        (struct_item
227          name: (type_identifier) @name) @struct
228
229        ; Enums
230        (enum_item
231          name: (type_identifier) @name) @enum
232
233        ; Traits
234        (trait_item
235          name: (type_identifier) @name) @trait
236
237        ; Use statements (imports)
238        (use_declaration) @import
239    "#;
240
241    Query::new(&tree_sitter_rust::LANGUAGE.into(), query_string)
242        .map_err(|e| ParserError::QueryError(e.to_string()))
243}
244
245// ==========================================================================
246// Go
247// ==========================================================================
248
249pub fn go_query() -> Result<Query, ParserError> {
250    let query_string = r#"
251        (function_declaration
252          name: (identifier) @name) @function
253
254        (method_declaration
255          name: (field_identifier) @name) @method
256
257        (type_declaration
258          (type_spec
259            name: (type_identifier) @name
260            type: (struct_type))) @struct
261
262        (type_declaration
263          (type_spec
264            name: (type_identifier) @name
265            type: (interface_type))) @interface
266    "#;
267
268    Query::new(&tree_sitter_go::LANGUAGE.into(), query_string)
269        .map_err(|e| ParserError::QueryError(e.to_string()))
270}
271
272pub fn go_super_query() -> Result<Query, ParserError> {
273    let query_string = r#"
274        ; Functions
275        (function_declaration
276          name: (identifier) @name) @function
277
278        ; Methods
279        (method_declaration
280          name: (field_identifier) @name) @method
281
282        ; Structs
283        (type_declaration
284          (type_spec
285            name: (type_identifier) @name
286            type: (struct_type))) @struct
287
288        ; Interfaces
289        (type_declaration
290          (type_spec
291            name: (type_identifier) @name
292            type: (interface_type))) @interface
293
294        ; Imports
295        (import_declaration) @import
296    "#;
297
298    Query::new(&tree_sitter_go::LANGUAGE.into(), query_string)
299        .map_err(|e| ParserError::QueryError(e.to_string()))
300}
301
302// ==========================================================================
303// Java
304// ==========================================================================
305
306pub fn java_query() -> Result<Query, ParserError> {
307    let query_string = r#"
308        (method_declaration
309          name: (identifier) @name) @method
310
311        (class_declaration
312          name: (identifier) @name) @class
313
314        (interface_declaration
315          name: (identifier) @name) @interface
316
317        (enum_declaration
318          name: (identifier) @name) @enum
319    "#;
320
321    Query::new(&tree_sitter_java::LANGUAGE.into(), query_string)
322        .map_err(|e| ParserError::QueryError(e.to_string()))
323}
324
325pub fn java_super_query() -> Result<Query, ParserError> {
326    let query_string = r#"
327        ; Methods
328        (method_declaration
329          name: (identifier) @name) @method
330
331        ; Classes
332        (class_declaration
333          name: (identifier) @name) @class
334
335        ; Interfaces
336        (interface_declaration
337          name: (identifier) @name) @interface
338
339        ; Enums
340        (enum_declaration
341          name: (identifier) @name) @enum
342
343        ; Imports
344        (import_declaration) @import
345    "#;
346
347    Query::new(&tree_sitter_java::LANGUAGE.into(), query_string)
348        .map_err(|e| ParserError::QueryError(e.to_string()))
349}
350
351// ==========================================================================
352// C
353// ==========================================================================
354
355pub fn c_query() -> Result<Query, ParserError> {
356    let query_string = r#"
357        (function_definition
358          declarator: (function_declarator
359            declarator: (identifier) @name)) @function
360
361        (struct_specifier
362          name: (type_identifier) @name) @struct
363
364        (enum_specifier
365          name: (type_identifier) @name) @enum
366    "#;
367
368    Query::new(&tree_sitter_c::LANGUAGE.into(), query_string)
369        .map_err(|e| ParserError::QueryError(e.to_string()))
370}
371
372pub fn c_super_query() -> Result<Query, ParserError> {
373    let query_string = r#"
374        ; Functions
375        (function_definition
376          declarator: (function_declarator
377            declarator: (identifier) @name)) @function
378
379        ; Structs
380        (struct_specifier
381          name: (type_identifier) @name) @struct
382
383        ; Enums
384        (enum_specifier
385          name: (type_identifier) @name) @enum
386
387        ; Includes (imports)
388        (preproc_include) @import
389    "#;
390
391    Query::new(&tree_sitter_c::LANGUAGE.into(), query_string)
392        .map_err(|e| ParserError::QueryError(e.to_string()))
393}
394
395// ==========================================================================
396// C++
397// ==========================================================================
398
399pub fn cpp_query() -> Result<Query, ParserError> {
400    let query_string = r#"
401        (function_definition
402          declarator: (function_declarator
403            declarator: (identifier) @name)) @function
404
405        (class_specifier
406          name: (type_identifier) @name) @class
407
408        (struct_specifier
409          name: (type_identifier) @name) @struct
410
411        (enum_specifier
412          name: (type_identifier) @name) @enum
413    "#;
414
415    Query::new(&tree_sitter_cpp::LANGUAGE.into(), query_string)
416        .map_err(|e| ParserError::QueryError(e.to_string()))
417}
418
419pub fn cpp_super_query() -> Result<Query, ParserError> {
420    let query_string = r#"
421        ; Functions
422        (function_definition
423          declarator: (function_declarator
424            declarator: (identifier) @name)) @function
425
426        ; Classes
427        (class_specifier
428          name: (type_identifier) @name) @class
429
430        ; Structs
431        (struct_specifier
432          name: (type_identifier) @name) @struct
433
434        ; Enums
435        (enum_specifier
436          name: (type_identifier) @name) @enum
437
438        ; Includes (imports)
439        (preproc_include) @import
440    "#;
441
442    Query::new(&tree_sitter_cpp::LANGUAGE.into(), query_string)
443        .map_err(|e| ParserError::QueryError(e.to_string()))
444}
445
446// ==========================================================================
447// C#
448// ==========================================================================
449
450pub fn csharp_query() -> Result<Query, ParserError> {
451    let query_string = r#"
452        (method_declaration
453          name: (identifier) @name) @method
454
455        (class_declaration
456          name: (identifier) @name) @class
457
458        (interface_declaration
459          name: (identifier) @name) @interface
460
461        (struct_declaration
462          name: (identifier) @name) @struct
463
464        (enum_declaration
465          name: (identifier) @name) @enum
466    "#;
467
468    Query::new(&tree_sitter_c_sharp::LANGUAGE.into(), query_string)
469        .map_err(|e| ParserError::QueryError(e.to_string()))
470}
471
472pub fn csharp_super_query() -> Result<Query, ParserError> {
473    let query_string = r#"
474        ; Methods
475        (method_declaration
476          name: (identifier) @name) @method
477
478        ; Classes
479        (class_declaration
480          name: (identifier) @name) @class
481
482        ; Interfaces
483        (interface_declaration
484          name: (identifier) @name) @interface
485
486        ; Structs
487        (struct_declaration
488          name: (identifier) @name) @struct
489
490        ; Enums
491        (enum_declaration
492          name: (identifier) @name) @enum
493
494        ; Imports (using directives)
495        (using_directive) @import
496    "#;
497
498    Query::new(&tree_sitter_c_sharp::LANGUAGE.into(), query_string)
499        .map_err(|e| ParserError::QueryError(e.to_string()))
500}
501
502// ==========================================================================
503// Ruby
504// ==========================================================================
505
506pub fn ruby_query() -> Result<Query, ParserError> {
507    let query_string = r#"
508        (method
509          name: (identifier) @name) @function
510
511        (class
512          name: (constant) @name) @class
513
514        (module
515          name: (constant) @name) @class
516    "#;
517
518    Query::new(&tree_sitter_ruby::LANGUAGE.into(), query_string)
519        .map_err(|e| ParserError::QueryError(e.to_string()))
520}
521
522pub fn ruby_super_query() -> Result<Query, ParserError> {
523    let query_string = r#"
524        ; Methods
525        (method
526          name: (identifier) @name) @function
527
528        ; Classes
529        (class
530          name: (constant) @name) @class
531
532        ; Modules
533        (module
534          name: (constant) @name) @class
535
536        ; Requires (imports)
537        (call
538          method: (identifier) @_method
539          (#match? @_method "^require")
540          arguments: (argument_list)) @import
541    "#;
542
543    Query::new(&tree_sitter_ruby::LANGUAGE.into(), query_string)
544        .map_err(|e| ParserError::QueryError(e.to_string()))
545}
546
547// ==========================================================================
548// Bash
549// ==========================================================================
550
551pub fn bash_query() -> Result<Query, ParserError> {
552    let query_string = r#"
553        (function_definition
554          name: (word) @name) @function
555    "#;
556
557    Query::new(&tree_sitter_bash::LANGUAGE.into(), query_string)
558        .map_err(|e| ParserError::QueryError(e.to_string()))
559}
560
561pub fn bash_super_query() -> Result<Query, ParserError> {
562    let query_string = r#"
563        ; Functions
564        (function_definition
565          name: (word) @name) @function
566
567        ; Source commands (imports)
568        (command
569          name: (command_name) @_cmd
570          (#match? @_cmd "^(source|\\.)$")
571          argument: (word)) @import
572    "#;
573
574    Query::new(&tree_sitter_bash::LANGUAGE.into(), query_string)
575        .map_err(|e| ParserError::QueryError(e.to_string()))
576}
577
578// ==========================================================================
579// PHP
580// ==========================================================================
581
582pub fn php_query() -> Result<Query, ParserError> {
583    let query_string = r#"
584        (function_definition
585          name: (name) @name) @function
586
587        (method_declaration
588          name: (name) @name) @method
589
590        (class_declaration
591          name: (name) @name) @class
592
593        (interface_declaration
594          name: (name) @name) @interface
595
596        (trait_declaration
597          name: (name) @name) @trait
598    "#;
599
600    Query::new(&tree_sitter_php::LANGUAGE_PHP.into(), query_string)
601        .map_err(|e| ParserError::QueryError(e.to_string()))
602}
603
604pub fn php_super_query() -> Result<Query, ParserError> {
605    let query_string = r#"
606        ; Functions
607        (function_definition
608          name: (name) @name) @function
609
610        ; Methods
611        (method_declaration
612          name: (name) @name) @method
613
614        ; Classes
615        (class_declaration
616          name: (name) @name) @class
617
618        ; Interfaces
619        (interface_declaration
620          name: (name) @name) @interface
621
622        ; Traits
623        (trait_declaration
624          name: (name) @name) @trait
625
626        ; Use statements (imports)
627        (namespace_use_declaration) @import
628    "#;
629
630    Query::new(&tree_sitter_php::LANGUAGE_PHP.into(), query_string)
631        .map_err(|e| ParserError::QueryError(e.to_string()))
632}
633
634// ==========================================================================
635// Kotlin
636// ==========================================================================
637
638pub fn kotlin_query() -> Result<Query, ParserError> {
639    let query_string = r#"
640        (function_declaration
641          name: (_) @name) @function
642
643        (class_declaration
644          name: (_) @name) @class
645
646        (object_declaration
647          name: (_) @name) @class
648    "#;
649
650    Query::new(&tree_sitter_kotlin_ng::LANGUAGE.into(), query_string)
651        .map_err(|e| ParserError::QueryError(e.to_string()))
652}
653
654pub fn kotlin_super_query() -> Result<Query, ParserError> {
655    let query_string = r#"
656        ; Functions
657        (function_declaration
658          name: (_) @name) @function
659
660        ; Classes
661        (class_declaration
662          name: (_) @name) @class
663
664        ; Objects
665        (object_declaration
666          name: (_) @name) @class
667
668        ; Imports
669        (import) @import
670    "#;
671
672    Query::new(&tree_sitter_kotlin_ng::LANGUAGE.into(), query_string)
673        .map_err(|e| ParserError::QueryError(e.to_string()))
674}
675
676// ==========================================================================
677// Swift
678// ==========================================================================
679
680pub fn swift_query() -> Result<Query, ParserError> {
681    let query_string = r#"
682        (function_declaration
683          name: (simple_identifier) @name) @function
684
685        (class_declaration
686          declaration_kind: "class"
687          name: (type_identifier) @name) @class
688
689        (protocol_declaration
690          name: (type_identifier) @name) @interface
691
692        (class_declaration
693          declaration_kind: "struct"
694          name: (type_identifier) @name) @struct
695
696        (class_declaration
697          declaration_kind: "enum"
698          name: (type_identifier) @name) @enum
699    "#;
700
701    Query::new(&tree_sitter_swift::LANGUAGE.into(), query_string)
702        .map_err(|e| ParserError::QueryError(e.to_string()))
703}
704
705pub fn swift_super_query() -> Result<Query, ParserError> {
706    let query_string = r#"
707        ; Functions
708        (function_declaration
709          name: (simple_identifier) @name) @function
710
711        ; Classes
712        (class_declaration
713          declaration_kind: "class"
714          name: (type_identifier) @name) @class
715
716        ; Protocols (interfaces)
717        (protocol_declaration
718          name: (type_identifier) @name) @interface
719
720        ; Structs
721        (class_declaration
722          declaration_kind: "struct"
723          name: (type_identifier) @name) @struct
724
725        ; Enums
726        (class_declaration
727          declaration_kind: "enum"
728          name: (type_identifier) @name) @enum
729
730        ; Imports
731        (import_declaration) @import
732    "#;
733
734    Query::new(&tree_sitter_swift::LANGUAGE.into(), query_string)
735        .map_err(|e| ParserError::QueryError(e.to_string()))
736}
737
738// ==========================================================================
739// Scala
740// ==========================================================================
741
742pub fn scala_query() -> Result<Query, ParserError> {
743    let query_string = r#"
744        (function_definition
745          name: (identifier) @name) @function
746
747        (class_definition
748          name: (identifier) @name) @class
749
750        (object_definition
751          name: (identifier) @name) @class
752
753        (trait_definition
754          name: (identifier) @name) @trait
755    "#;
756
757    Query::new(&tree_sitter_scala::LANGUAGE.into(), query_string)
758        .map_err(|e| ParserError::QueryError(e.to_string()))
759}
760
761pub fn scala_super_query() -> Result<Query, ParserError> {
762    let query_string = r#"
763        ; Functions
764        (function_definition
765          name: (identifier) @name) @function
766
767        ; Classes
768        (class_definition
769          name: (identifier) @name) @class
770
771        ; Objects
772        (object_definition
773          name: (identifier) @name) @class
774
775        ; Traits
776        (trait_definition
777          name: (identifier) @name) @trait
778
779        ; Imports
780        (import_declaration) @import
781    "#;
782
783    Query::new(&tree_sitter_scala::LANGUAGE.into(), query_string)
784        .map_err(|e| ParserError::QueryError(e.to_string()))
785}
786
787// ==========================================================================
788// Haskell
789// ==========================================================================
790
791pub fn haskell_query() -> Result<Query, ParserError> {
792    let query_string = r#"
793        (function
794          name: (variable) @name) @function
795
796        (signature
797          name: (variable) @name) @function
798
799        (function
800          name: (prefix_id) @name) @function
801
802        (signature
803          name: (prefix_id) @name) @function
804
805        (newtype
806          name: (name) @name) @struct
807
808        (type_synomym
809          name: (name) @name) @struct
810
811        (data_type
812          name: (name) @name) @enum
813    "#;
814
815    Query::new(&tree_sitter_haskell::LANGUAGE.into(), query_string)
816        .map_err(|e| ParserError::QueryError(e.to_string()))
817}
818
819pub fn haskell_super_query() -> Result<Query, ParserError> {
820    let query_string = r#"
821        ; Functions
822        (function
823          name: (variable) @name) @function
824
825        ; Type signatures
826        (signature
827          name: (variable) @name) @function
828
829        ; Type aliases
830        (function
831          name: (prefix_id) @name) @function
832
833        (signature
834          name: (prefix_id) @name) @function
835
836        ; Newtypes
837        (newtype
838          name: (name) @name) @struct
839
840        ; ADTs (data declarations)
841        (type_synomym
842          name: (name) @name) @struct
843
844        (data_type
845          name: (name) @name) @enum
846
847        ; Imports
848        (import) @import
849    "#;
850
851    Query::new(&tree_sitter_haskell::LANGUAGE.into(), query_string)
852        .map_err(|e| ParserError::QueryError(e.to_string()))
853}
854
855// ==========================================================================
856// Elixir
857// ==========================================================================
858
859pub fn elixir_query() -> Result<Query, ParserError> {
860    let query_string = r#"
861        (call
862          target: (identifier) @_type
863          (#match? @_type "^(def|defp|defmacro|defmacrop)$")
864          (arguments
865            (call
866              target: (identifier) @name))) @function
867
868        (call
869          target: (identifier) @_type
870          (#match? @_type "^defmodule$")
871          (arguments
872            (alias) @name)) @class
873    "#;
874
875    Query::new(&tree_sitter_elixir::LANGUAGE.into(), query_string)
876        .map_err(|e| ParserError::QueryError(e.to_string()))
877}
878
879pub fn elixir_super_query() -> Result<Query, ParserError> {
880    let query_string = r#"
881        ; Functions (def, defp, defmacro)
882        (call
883          target: (identifier) @_type
884          (#match? @_type "^(def|defp|defmacro|defmacrop)$")
885          (arguments
886            (call
887              target: (identifier) @name))) @function
888
889        ; Modules
890        (call
891          target: (identifier) @_type
892          (#match? @_type "^defmodule$")
893          (arguments
894            (alias) @name)) @class
895
896        ; Imports (alias, import, use, require)
897        (call
898          target: (identifier) @_type
899          (#match? @_type "^(alias|import|use|require)$")) @import
900    "#;
901
902    Query::new(&tree_sitter_elixir::LANGUAGE.into(), query_string)
903        .map_err(|e| ParserError::QueryError(e.to_string()))
904}
905
906// ==========================================================================
907// Clojure
908// ==========================================================================
909
910pub fn clojure_query() -> Result<Query, ParserError> {
911    let query_string = r#"
912        (list_lit
913          (sym_lit) @_type
914          (#match? @_type "^(defn|defn-|defmacro)$")
915          (sym_lit) @name) @function
916
917        (list_lit
918          (sym_lit) @_type
919          (#match? @_type "^(defrecord|deftype|defprotocol)$")
920          (sym_lit) @name) @class
921    "#;
922
923    Query::new(&tree_sitter_clojure::LANGUAGE.into(), query_string)
924        .map_err(|e| ParserError::QueryError(e.to_string()))
925}
926
927pub fn clojure_super_query() -> Result<Query, ParserError> {
928    let query_string = r#"
929        ; Functions
930        (list_lit
931          (sym_lit) @_type
932          (#match? @_type "^(defn|defn-|defmacro)$")
933          (sym_lit) @name) @function
934
935        ; Records/Types/Protocols
936        (list_lit
937          (sym_lit) @_type
938          (#match? @_type "^(defrecord|deftype|defprotocol)$")
939          (sym_lit) @name) @class
940
941        ; Namespace (imports)
942        (list_lit
943          (sym_lit) @_type
944          (#match? @_type "^(ns|require|use|import)$")) @import
945    "#;
946
947    Query::new(&tree_sitter_clojure::LANGUAGE.into(), query_string)
948        .map_err(|e| ParserError::QueryError(e.to_string()))
949}
950
951// ==========================================================================
952// OCaml
953// ==========================================================================
954
955pub fn ocaml_query() -> Result<Query, ParserError> {
956    let query_string = r#"
957        (value_definition
958          (let_binding
959            pattern: (value_name) @name)) @function
960
961        (type_definition
962          (type_binding
963            name: (type_constructor) @name)) @struct
964
965        (module_definition
966          (module_binding
967            name: (module_name) @name)) @class
968    "#;
969
970    Query::new(&tree_sitter_ocaml::LANGUAGE_OCAML.into(), query_string)
971        .map_err(|e| ParserError::QueryError(e.to_string()))
972}
973
974pub fn ocaml_super_query() -> Result<Query, ParserError> {
975    let query_string = r#"
976        ; Functions (let bindings)
977        (value_definition
978          (let_binding
979            pattern: (value_name) @name)) @function
980
981        ; Types
982        (type_definition
983          (type_binding
984            name: (type_constructor) @name)) @struct
985
986        ; Modules
987        (module_definition
988          (module_binding
989            name: (module_name) @name)) @class
990
991        ; Opens (imports)
992        (open_module) @import
993    "#;
994
995    Query::new(&tree_sitter_ocaml::LANGUAGE_OCAML.into(), query_string)
996        .map_err(|e| ParserError::QueryError(e.to_string()))
997}
998
999// ==========================================================================
1000// Lua
1001// ==========================================================================
1002
1003pub fn lua_query() -> Result<Query, ParserError> {
1004    let query_string = r#"
1005        (function_declaration
1006          name: (identifier) @name) @function
1007
1008        (function_declaration
1009          name: (dot_index_expression) @name) @method
1010
1011        (function_declaration
1012          name: (method_index_expression) @name) @method
1013    "#;
1014
1015    Query::new(&tree_sitter_lua::LANGUAGE.into(), query_string)
1016        .map_err(|e| ParserError::QueryError(e.to_string()))
1017}
1018
1019pub fn lua_super_query() -> Result<Query, ParserError> {
1020    let query_string = r#"
1021        ; Global functions
1022        (function_declaration
1023          name: (identifier) @name) @function
1024
1025        ; Method-like functions
1026        (function_declaration
1027          name: (dot_index_expression) @name) @method
1028
1029        (function_declaration
1030          name: (method_index_expression) @name) @method
1031
1032        ; Requires (imports)
1033        (function_call
1034          name: (variable
1035            (identifier) @_func)
1036          (#eq? @_func "require")
1037          arguments: (arguments)) @import
1038    "#;
1039
1040    Query::new(&tree_sitter_lua::LANGUAGE.into(), query_string)
1041        .map_err(|e| ParserError::QueryError(e.to_string()))
1042}
1043
1044// ==========================================================================
1045// R
1046// ==========================================================================
1047
1048pub fn r_query() -> Result<Query, ParserError> {
1049    let query_string = r#"
1050        (binary_operator
1051          lhs: (identifier) @name
1052          operator: "<-"
1053          rhs: (function_definition)) @function
1054
1055        (binary_operator
1056          lhs: (identifier) @name
1057          operator: "="
1058          rhs: (function_definition)) @function
1059    "#;
1060
1061    Query::new(&tree_sitter_r::LANGUAGE.into(), query_string)
1062        .map_err(|e| ParserError::QueryError(e.to_string()))
1063}
1064
1065pub fn r_super_query() -> Result<Query, ParserError> {
1066    let query_string = r#"
1067        ; Functions (left assignment)
1068        (binary_operator
1069          lhs: (identifier) @name
1070          operator: "<-"
1071          rhs: (function_definition)) @function
1072
1073        ; Functions (equals assignment)
1074        (binary_operator
1075          lhs: (identifier) @name
1076          operator: "="
1077          rhs: (function_definition)) @function
1078
1079        ; Library/require calls (imports)
1080        (call
1081          function: (identifier) @_func
1082          (#match? @_func "^(library|require|source)$")) @import
1083    "#;
1084
1085    Query::new(&tree_sitter_r::LANGUAGE.into(), query_string)
1086        .map_err(|e| ParserError::QueryError(e.to_string()))
1087}
1088
1089#[cfg(test)]
1090mod tests {
1091    use super::*;
1092
1093    #[test]
1094    fn test_python_queries() {
1095        assert!(python_query().is_ok());
1096        assert!(python_super_query().is_ok());
1097    }
1098
1099    #[test]
1100    fn test_javascript_queries() {
1101        assert!(javascript_query().is_ok());
1102        assert!(javascript_super_query().is_ok());
1103    }
1104
1105    #[test]
1106    fn test_typescript_queries() {
1107        assert!(typescript_query().is_ok());
1108        assert!(typescript_super_query().is_ok());
1109    }
1110
1111    #[test]
1112    fn test_rust_queries() {
1113        assert!(rust_query().is_ok());
1114        assert!(rust_super_query().is_ok());
1115    }
1116
1117    #[test]
1118    fn test_go_queries() {
1119        assert!(go_query().is_ok());
1120        assert!(go_super_query().is_ok());
1121    }
1122
1123    #[test]
1124    fn test_java_queries() {
1125        assert!(java_query().is_ok());
1126        assert!(java_super_query().is_ok());
1127    }
1128
1129    #[test]
1130    fn test_c_queries() {
1131        assert!(c_query().is_ok());
1132        assert!(c_super_query().is_ok());
1133    }
1134
1135    #[test]
1136    fn test_cpp_queries() {
1137        assert!(cpp_query().is_ok());
1138        assert!(cpp_super_query().is_ok());
1139    }
1140
1141    #[test]
1142    fn test_csharp_queries() {
1143        assert!(csharp_query().is_ok());
1144        assert!(csharp_super_query().is_ok());
1145    }
1146
1147    #[test]
1148    fn test_ruby_queries() {
1149        assert!(ruby_query().is_ok());
1150        assert!(ruby_super_query().is_ok());
1151    }
1152
1153    #[test]
1154    fn test_bash_queries() {
1155        assert!(bash_query().is_ok());
1156        assert!(bash_super_query().is_ok());
1157    }
1158
1159    #[test]
1160    fn test_php_queries() {
1161        assert!(php_query().is_ok());
1162        assert!(php_super_query().is_ok());
1163    }
1164
1165    #[test]
1166    fn test_kotlin_queries() {
1167        assert!(kotlin_query().is_ok());
1168        assert!(kotlin_super_query().is_ok());
1169    }
1170
1171    #[test]
1172    fn test_swift_queries() {
1173        assert!(swift_query().is_ok());
1174        assert!(swift_super_query().is_ok());
1175    }
1176
1177    #[test]
1178    fn test_scala_queries() {
1179        assert!(scala_query().is_ok());
1180        assert!(scala_super_query().is_ok());
1181    }
1182
1183    #[test]
1184    fn test_haskell_queries() {
1185        assert!(haskell_query().is_ok());
1186        assert!(haskell_super_query().is_ok());
1187    }
1188
1189    #[test]
1190    fn test_elixir_queries() {
1191        assert!(elixir_query().is_ok());
1192        assert!(elixir_super_query().is_ok());
1193    }
1194
1195    #[test]
1196    fn test_clojure_queries() {
1197        assert!(clojure_query().is_ok());
1198        assert!(clojure_super_query().is_ok());
1199    }
1200
1201    #[test]
1202    fn test_ocaml_queries() {
1203        assert!(ocaml_query().is_ok());
1204        assert!(ocaml_super_query().is_ok());
1205    }
1206
1207    #[test]
1208    fn test_lua_queries() {
1209        assert!(lua_query().is_ok());
1210        assert!(lua_super_query().is_ok());
1211    }
1212
1213    #[test]
1214    fn test_r_queries() {
1215        assert!(r_query().is_ok());
1216        assert!(r_super_query().is_ok());
1217    }
1218}