Skip to main content

sem_core/parser/plugins/code/
languages.rs

1use std::collections::HashMap;
2
3use tree_sitter::Language;
4
5use crate::parser::graph::EntityInfo;
6
7pub struct SuppressedNestedEntity {
8    pub parent_entity_node_type: &'static str,
9    pub child_entity_node_type: &'static str,
10}
11
12#[allow(dead_code)]
13pub struct LanguageConfig {
14    pub id: &'static str,
15    pub extensions: &'static [&'static str],
16    pub entity_node_types: &'static [&'static str],
17    pub container_node_types: &'static [&'static str],
18    pub call_entity_identifiers: &'static [&'static str],
19    pub suppressed_nested_entities: &'static [SuppressedNestedEntity],
20    /// Node types that introduce a new scope. The general (non-container) recursion
21    /// in visit_node will not descend into these nodes, preventing local variables
22    /// inside function bodies from being extracted as top-level entities.
23    pub scope_boundary_types: &'static [&'static str],
24    pub get_language: fn() -> Option<Language>,
25    pub scope_resolve: Option<&'static ScopeResolveConfig>,
26}
27
28// ─── Scope Resolve Config Types ───────────────────────────────────────────────
29
30/// Configuration for scope-aware reference resolution.
31/// Captures the AST node names and strategies that differ per language.
32pub struct ScopeResolveConfig {
33    /// AST node types that create class/struct scopes
34    pub class_scope_nodes: &'static [&'static str],
35    /// AST node types that create impl scopes (Rust impl_item, Swift extension)
36    pub impl_scope_nodes: &'static [&'static str],
37    /// AST node types that create function/method scopes
38    pub function_scope_nodes: &'static [&'static str],
39    /// How to extract the class name from a class scope node
40    pub class_name_field: ClassNameField,
41
42    /// Rules for scanning variable assignments to track types
43    pub assignment_rules: &'static [AssignmentRule],
44    /// Node types to recurse into when scanning assignments
45    pub assignment_recurse_into: &'static [&'static str],
46
47    /// Rules for extracting typed parameters from function signatures
48    pub param_rules: &'static [ParamRule],
49
50    /// Field name for return type annotation on function nodes (None = body heuristic only)
51    pub return_type_field: Option<&'static str>,
52
53    /// AST node types that represent function/method calls
54    pub call_nodes: &'static [&'static str],
55    /// How call nodes expose the callee. FunctionField = node has a "function" field containing
56    /// an identifier or member_expression. DirectMethod = node has object+name fields directly.
57    pub call_style: CallNodeStyle,
58    /// AST node types for `new Foo()` expressions
59    pub new_expr_nodes: &'static [&'static str],
60    /// Field name on new-expression nodes that holds the type/constructor name.
61    pub new_expr_type_field: &'static str,
62    /// AST node types for struct/composite literals (Go `Foo{}`)
63    pub composite_literal_nodes: &'static [&'static str],
64    /// How member access / method calls are represented in the AST
65    pub member_access: &'static [MemberAccess],
66    /// Scoped identifier nodes (Rust `Type::method`)
67    pub scoped_call_nodes: &'static [&'static str],
68
69    /// Self/this keywords to recognize
70    pub self_keywords: &'static [&'static str],
71
72    /// Strategy for extracting instance attribute types
73    pub init_strategy: InitStrategy,
74
75    /// Import extraction function (the only truly per-language piece)
76    pub import_extractor: Option<ImportExtractorFn>,
77
78    /// Whether methods are declared externally with receiver types (Go-style)
79    pub external_method: bool,
80
81    /// Language builtins to skip during resolution
82    pub builtins: &'static [&'static str],
83}
84
85/// How call nodes expose the callee/function.
86pub enum CallNodeStyle {
87    /// The call node has a field (e.g. "function") containing either an identifier
88    /// (bare call) or a member_expression (method call). Python, TS, Rust, Go, C#, C++.
89    FunctionField(&'static str),
90    /// The call node directly has object (optional) + method name fields.
91    /// Java: method_invocation(object, name). Ruby: call(receiver, method).
92    DirectMethod { object_field: &'static str, method_field: &'static str },
93}
94
95/// How to extract the class/struct name from a scope node.
96pub enum ClassNameField {
97    /// Simple field lookup: `node.child_by_field_name(field)`
98    Simple(&'static str),
99    /// Go-style: look for a child of type `spec_kind`, then get field `field` from it
100    TypeSpec { spec_kind: &'static str, field: &'static str },
101    /// Rust impl: get name from `node.child_by_field_name(field)` (the "type" field)
102    ImplType(&'static str),
103}
104
105/// A rule for scanning assignment nodes to extract type bindings.
106pub struct AssignmentRule {
107    pub node_kind: &'static str,
108    pub strategy: AssignmentStrategy,
109}
110
111/// Strategy for extracting variable name and type from an assignment node.
112pub enum AssignmentStrategy {
113    /// Python/TS: `x = Foo()` - left/right fields on assignment node
114    LeftRight,
115    /// TS: `const x = new Foo()` - variable_declarator children
116    Declarators,
117    /// Rust: `let x: Type = value` - pattern + type + value fields
118    PatternBased,
119    /// Go: `x := Foo{}` - expression_list left/right
120    ShortVar,
121    /// Go: `var x Type = ...` - var_spec children
122    VarSpec,
123}
124
125/// A rule for extracting typed parameters from function signatures.
126pub struct ParamRule {
127    pub node_kind: &'static str,
128    pub name_field: ParamNameField,
129    pub type_field: &'static str,
130    pub skip_names: &'static [&'static str],
131}
132
133/// How to extract the parameter name.
134pub enum ParamNameField {
135    /// Simple field name: `child_by_field_name(field)`
136    Simple(&'static str),
137    /// Field with fallback to first named child if identifier
138    WithFallback(&'static str),
139    /// Rust pattern matching (identifier, mut_pattern, reference_pattern)
140    RustPattern,
141}
142
143/// How member access (obj.field / obj.method()) is represented in the AST.
144pub struct MemberAccess {
145    pub node_kind: &'static str,
146    pub object_field: &'static str,
147    pub property_field: &'static str,
148}
149
150/// Strategy for extracting instance attribute types from class definitions.
151pub enum InitStrategy {
152    /// Python/TS: scan constructor body for self.attr = param patterns
153    ConstructorBody {
154        class_nodes: &'static [&'static str],
155        init_names: &'static [&'static str],
156        init_node_kind: &'static str,
157        self_keyword: &'static str,
158        access_kind: &'static str,
159        obj_field: &'static str,
160        prop_field: &'static str,
161    },
162    /// Rust/Go: extract field types directly from struct declarations
163    StructFields {
164        struct_nodes: &'static [&'static str],
165    },
166    /// No instance attribute tracking
167    None,
168}
169
170/// Function pointer type for import extraction.
171pub type ImportExtractorFn = fn(
172    node: tree_sitter::Node,
173    file_path: &str,
174    source: &[u8],
175    symbol_table: &HashMap<String, Vec<String>>,
176    entity_map: &HashMap<String, EntityInfo>,
177    import_table: &mut HashMap<(String, String), String>,
178    scopes: &mut Vec<crate::parser::scope_resolve::Scope>,
179);
180
181/// Import node kind + extractor function pair
182pub struct ImportRule {
183    pub node_kind: &'static str,
184    pub extractor: ImportExtractorFn,
185}
186
187#[cfg(feature = "lang-typescript")]
188fn get_typescript() -> Option<Language> {
189    Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into())
190}
191
192#[cfg(feature = "lang-typescript")]
193fn get_tsx() -> Option<Language> {
194    Some(tree_sitter_typescript::LANGUAGE_TSX.into())
195}
196
197#[cfg(feature = "lang-javascript")]
198fn get_javascript() -> Option<Language> {
199    Some(tree_sitter_javascript::LANGUAGE.into())
200}
201
202#[cfg(feature = "lang-python")]
203fn get_python() -> Option<Language> {
204    Some(tree_sitter_python::LANGUAGE.into())
205}
206
207#[cfg(feature = "lang-go")]
208fn get_go() -> Option<Language> {
209    Some(tree_sitter_go::LANGUAGE.into())
210}
211
212#[cfg(feature = "lang-rust")]
213fn get_rust() -> Option<Language> {
214    Some(tree_sitter_rust::LANGUAGE.into())
215}
216
217#[cfg(feature = "lang-java")]
218fn get_java() -> Option<Language> {
219    Some(tree_sitter_java::LANGUAGE.into())
220}
221
222#[cfg(feature = "lang-c")]
223fn get_c() -> Option<Language> {
224    Some(tree_sitter_c::LANGUAGE.into())
225}
226
227#[cfg(feature = "lang-cpp")]
228fn get_cpp() -> Option<Language> {
229    Some(tree_sitter_cpp::LANGUAGE.into())
230}
231
232#[cfg(feature = "lang-ruby")]
233fn get_ruby() -> Option<Language> {
234    Some(tree_sitter_ruby::LANGUAGE.into())
235}
236
237#[cfg(feature = "lang-csharp")]
238fn get_csharp() -> Option<Language> {
239    Some(tree_sitter_c_sharp::LANGUAGE.into())
240}
241
242#[cfg(feature = "lang-php")]
243fn get_php() -> Option<Language> {
244    Some(tree_sitter_php::LANGUAGE_PHP.into())
245}
246
247#[cfg(feature = "lang-fortran")]
248fn get_fortran() -> Option<Language> {
249    Some(tree_sitter_fortran::LANGUAGE.into())
250}
251
252#[cfg(feature = "lang-swift")]
253fn get_swift() -> Option<Language> {
254    Some(tree_sitter_swift::LANGUAGE.into())
255}
256
257#[cfg(feature = "lang-elixir")]
258fn get_elixir() -> Option<Language> {
259    Some(tree_sitter_elixir::LANGUAGE.into())
260}
261
262#[cfg(feature = "lang-bash")]
263fn get_bash() -> Option<Language> {
264    Some(tree_sitter_bash::LANGUAGE.into())
265}
266
267#[cfg(feature = "lang-hcl")]
268fn get_hcl() -> Option<Language> {
269    Some(tree_sitter_hcl::LANGUAGE.into())
270}
271
272#[cfg(feature = "lang-kotlin")]
273fn get_kotlin() -> Option<Language> {
274    Some(tree_sitter_kotlin_ng::LANGUAGE.into())
275}
276
277#[cfg(feature = "lang-xml")]
278fn get_xml() -> Option<Language> {
279    Some(tree_sitter_xml::LANGUAGE_XML.into())
280}
281
282#[cfg(feature = "lang-dart")]
283fn get_dart() -> Option<Language> {
284    Some(tree_sitter_dart::LANGUAGE.into())
285}
286
287#[cfg(feature = "lang-perl")]
288fn get_perl() -> Option<Language> {
289    Some(tree_sitter_perl_next::LANGUAGE.into())
290}
291
292#[cfg(feature = "lang-ocaml")]
293fn get_ocaml() -> Option<Language> {
294    Some(tree_sitter_ocaml::LANGUAGE_OCAML.into())
295}
296
297#[cfg(feature = "lang-ocaml")]
298fn get_ocaml_interface() -> Option<Language> {
299    Some(tree_sitter_ocaml::LANGUAGE_OCAML_INTERFACE.into())
300}
301
302#[cfg(feature = "lang-scala")]
303fn get_scala() -> Option<Language> {
304    Some(tree_sitter_scala::LANGUAGE.into())
305}
306
307#[cfg(feature = "lang-zig")]
308fn get_zig() -> Option<Language> {
309    Some(tree_sitter_zig::LANGUAGE.into())
310}
311
312#[cfg(feature = "lang-nix")]
313fn get_nix() -> Option<Language> {
314    Some(tree_sitter_nix::LANGUAGE.into())
315}
316
317/// Inside JS/TS function bodies, suppress variable declarations so that local
318/// variables are not extracted as nested entities. Inner function/class
319/// declarations are still extracted for diff granularity.
320const JS_TS_SUPPRESSED_NESTED: &[SuppressedNestedEntity] = &[
321    SuppressedNestedEntity {
322        parent_entity_node_type: "function_declaration",
323        child_entity_node_type: "lexical_declaration",
324    },
325    SuppressedNestedEntity {
326        parent_entity_node_type: "function_declaration",
327        child_entity_node_type: "variable_declaration",
328    },
329    SuppressedNestedEntity {
330        parent_entity_node_type: "generator_function_declaration",
331        child_entity_node_type: "lexical_declaration",
332    },
333    SuppressedNestedEntity {
334        parent_entity_node_type: "generator_function_declaration",
335        child_entity_node_type: "variable_declaration",
336    },
337    SuppressedNestedEntity {
338        parent_entity_node_type: "method_definition",
339        child_entity_node_type: "lexical_declaration",
340    },
341    SuppressedNestedEntity {
342        parent_entity_node_type: "method_definition",
343        child_entity_node_type: "variable_declaration",
344    },
345    // Scope boundaries: suppress local variables inside arrow functions,
346    // function expressions, and generator functions, while still allowing
347    // inner class/function declarations to be extracted.
348    SuppressedNestedEntity {
349        parent_entity_node_type: "arrow_function",
350        child_entity_node_type: "lexical_declaration",
351    },
352    SuppressedNestedEntity {
353        parent_entity_node_type: "arrow_function",
354        child_entity_node_type: "variable_declaration",
355    },
356    SuppressedNestedEntity {
357        parent_entity_node_type: "function_expression",
358        child_entity_node_type: "lexical_declaration",
359    },
360    SuppressedNestedEntity {
361        parent_entity_node_type: "function_expression",
362        child_entity_node_type: "variable_declaration",
363    },
364    SuppressedNestedEntity {
365        parent_entity_node_type: "generator_function",
366        child_entity_node_type: "lexical_declaration",
367    },
368    SuppressedNestedEntity {
369        parent_entity_node_type: "generator_function",
370        child_entity_node_type: "variable_declaration",
371    },
372];
373
374const JS_TS_SCOPE_BOUNDARIES: &[&str] = &[
375    "arrow_function",
376    "function_expression",
377    "generator_function",
378];
379
380#[cfg(feature = "lang-typescript")]
381static TYPESCRIPT_CONFIG: LanguageConfig = LanguageConfig {
382    id: "typescript",
383    extensions: &[".ts", ".mts", ".cts"],
384    entity_node_types: &[
385        "function_declaration",
386        "generator_function_declaration",
387        "class_declaration",
388        "interface_declaration",
389        "type_alias_declaration",
390        "enum_declaration",
391        "export_statement",
392        "lexical_declaration",
393        "variable_declaration",
394        "method_definition",
395        "public_field_definition",
396    ],
397    container_node_types: &["class_body", "interface_body", "enum_body", "statement_block"],
398    call_entity_identifiers: &[],
399    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
400    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
401    get_language: get_typescript,
402    scope_resolve: Some(&TS_SCOPE_CONFIG),
403};
404
405#[cfg(feature = "lang-typescript")]
406static TSX_CONFIG: LanguageConfig = LanguageConfig {
407    id: "tsx",
408    extensions: &[".tsx"],
409    entity_node_types: &[
410        "function_declaration",
411        "generator_function_declaration",
412        "class_declaration",
413        "interface_declaration",
414        "type_alias_declaration",
415        "enum_declaration",
416        "export_statement",
417        "lexical_declaration",
418        "variable_declaration",
419        "method_definition",
420        "public_field_definition",
421    ],
422    container_node_types: &["class_body", "interface_body", "enum_body", "statement_block"],
423    call_entity_identifiers: &[],
424    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
425    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
426    get_language: get_tsx,
427    scope_resolve: Some(&TS_SCOPE_CONFIG),
428};
429
430#[cfg(feature = "lang-javascript")]
431static JAVASCRIPT_CONFIG: LanguageConfig = LanguageConfig {
432    id: "javascript",
433    extensions: &[".js", ".jsx", ".mjs", ".cjs", ".es6"],
434    entity_node_types: &[
435        "function_declaration",
436        "generator_function_declaration",
437        "class_declaration",
438        "export_statement",
439        "lexical_declaration",
440        "variable_declaration",
441        "method_definition",
442        "field_definition",
443    ],
444    container_node_types: &["class_body", "statement_block"],
445    call_entity_identifiers: &[],
446    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
447    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
448    get_language: get_javascript,
449    scope_resolve: Some(&TS_SCOPE_CONFIG),
450};
451
452#[cfg(feature = "lang-python")]
453static PYTHON_CONFIG: LanguageConfig = LanguageConfig {
454    id: "python",
455    extensions: &[".py", ".pyi"],
456    entity_node_types: &[
457        "function_definition",
458        "class_definition",
459        "decorated_definition",
460    ],
461    container_node_types: &["block"],
462    call_entity_identifiers: &[],
463    suppressed_nested_entities: &[],
464    scope_boundary_types: &[],
465    get_language: get_python,
466    scope_resolve: Some(&PYTHON_SCOPE_CONFIG),
467};
468
469#[cfg(feature = "lang-go")]
470static GO_CONFIG: LanguageConfig = LanguageConfig {
471    id: "go",
472    extensions: &[".go"],
473    entity_node_types: &[
474        "function_declaration",
475        "method_declaration",
476        "type_declaration",
477        "var_declaration",
478        "const_declaration",
479    ],
480    container_node_types: &["block"],
481    call_entity_identifiers: &[],
482    suppressed_nested_entities: &[],
483    scope_boundary_types: &[],
484    get_language: get_go,
485    scope_resolve: Some(&GO_SCOPE_CONFIG),
486};
487
488#[cfg(feature = "lang-rust")]
489static RUST_CONFIG: LanguageConfig = LanguageConfig {
490    id: "rust",
491    extensions: &[".rs"],
492    entity_node_types: &[
493        "function_item",
494        "struct_item",
495        "enum_item",
496        "impl_item",
497        "trait_item",
498        "mod_item",
499        "const_item",
500        "static_item",
501        "type_item",
502        "macro_definition",
503    ],
504    container_node_types: &["declaration_list", "block"],
505    call_entity_identifiers: &[],
506    suppressed_nested_entities: &[],
507    scope_boundary_types: &[],
508    get_language: get_rust,
509    scope_resolve: Some(&RUST_SCOPE_CONFIG),
510};
511
512#[cfg(feature = "lang-java")]
513static JAVA_CONFIG: LanguageConfig = LanguageConfig {
514    id: "java",
515    extensions: &[".java"],
516    entity_node_types: &[
517        "class_declaration",
518        "method_declaration",
519        "interface_declaration",
520        "enum_declaration",
521        "field_declaration",
522        "constructor_declaration",
523        "annotation_type_declaration",
524    ],
525    container_node_types: &["class_body", "interface_body", "enum_body", "block"],
526    call_entity_identifiers: &[],
527    suppressed_nested_entities: &[],
528    scope_boundary_types: &[],
529    get_language: get_java,
530    scope_resolve: Some(&JAVA_SCOPE_CONFIG),
531};
532
533#[cfg(feature = "lang-c")]
534static C_CONFIG: LanguageConfig = LanguageConfig {
535    id: "c",
536    extensions: &[".c", ".h"],
537    entity_node_types: &[
538        "function_definition",
539        "struct_specifier",
540        "enum_specifier",
541        "union_specifier",
542        "type_definition",
543        "declaration",
544    ],
545    container_node_types: &["compound_statement"],
546    call_entity_identifiers: &[],
547    suppressed_nested_entities: &[],
548    scope_boundary_types: &[],
549    get_language: get_c,
550    scope_resolve: None,
551};
552
553#[cfg(feature = "lang-cpp")]
554static CPP_CONFIG: LanguageConfig = LanguageConfig {
555    id: "cpp",
556    extensions: &[".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx"],
557    entity_node_types: &[
558        "function_definition",
559        "class_specifier",
560        "struct_specifier",
561        "enum_specifier",
562        "namespace_definition",
563        "template_declaration",
564        "declaration",
565        "type_definition",
566    ],
567    container_node_types: &["field_declaration_list", "declaration_list", "compound_statement"],
568    call_entity_identifiers: &[],
569    suppressed_nested_entities: &[],
570    scope_boundary_types: &[],
571    get_language: get_cpp,
572    scope_resolve: Some(&CPP_SCOPE_CONFIG),
573};
574
575#[cfg(feature = "lang-ruby")]
576static RUBY_CONFIG: LanguageConfig = LanguageConfig {
577    id: "ruby",
578    extensions: &[".rb"],
579    entity_node_types: &[
580        "method",
581        "singleton_method",
582        "class",
583        "module",
584    ],
585    container_node_types: &["body_statement"],
586    call_entity_identifiers: &[],
587    suppressed_nested_entities: &[],
588    scope_boundary_types: &[],
589    get_language: get_ruby,
590    scope_resolve: Some(&RUBY_SCOPE_CONFIG),
591};
592
593#[cfg(feature = "lang-csharp")]
594static CSHARP_CONFIG: LanguageConfig = LanguageConfig {
595    id: "csharp",
596    extensions: &[".cs"],
597    entity_node_types: &[
598        "method_declaration",
599        "class_declaration",
600        "interface_declaration",
601        "enum_declaration",
602        "struct_declaration",
603        "namespace_declaration",
604        "property_declaration",
605        "constructor_declaration",
606        "field_declaration",
607    ],
608    container_node_types: &["declaration_list", "block"],
609    call_entity_identifiers: &[],
610    suppressed_nested_entities: &[],
611    scope_boundary_types: &[],
612    get_language: get_csharp,
613    scope_resolve: Some(&CSHARP_SCOPE_CONFIG),
614};
615
616#[cfg(feature = "lang-php")]
617static PHP_CONFIG: LanguageConfig = LanguageConfig {
618    id: "php",
619    extensions: &[".php", ".inc", ".phtml", ".module"],
620    entity_node_types: &[
621        "function_definition",
622        "class_declaration",
623        "method_declaration",
624        "interface_declaration",
625        "trait_declaration",
626        "enum_declaration",
627        "namespace_definition",
628    ],
629    container_node_types: &["declaration_list", "enum_declaration_list", "compound_statement"],
630    call_entity_identifiers: &[],
631    suppressed_nested_entities: &[],
632    scope_boundary_types: &[],
633    get_language: get_php,
634    scope_resolve: Some(&PHP_SCOPE_CONFIG),
635};
636
637#[cfg(feature = "lang-fortran")]
638static FORTRAN_CONFIG: LanguageConfig = LanguageConfig {
639    id: "fortran",
640    extensions: &[".f90", ".f95", ".f03", ".f08", ".f", ".for"],
641    entity_node_types: &[
642        "function",
643        "subroutine",
644        "module",
645        "program",
646        "interface",
647        "type_declaration",
648    ],
649    container_node_types: &["module", "program", "internal_procedures"],
650    call_entity_identifiers: &[],
651    suppressed_nested_entities: &[],
652    scope_boundary_types: &[],
653    get_language: get_fortran,
654    scope_resolve: None,
655};
656
657#[cfg(feature = "lang-swift")]
658static SWIFT_CONFIG: LanguageConfig = LanguageConfig {
659    id: "swift",
660    extensions: &[".swift"],
661    entity_node_types: &[
662        "function_declaration",
663        "class_declaration",
664        "protocol_declaration",
665        "init_declaration",
666        "deinit_declaration",
667        "subscript_declaration",
668        "typealias_declaration",
669        "property_declaration",
670        "operator_declaration",
671        "associatedtype_declaration",
672    ],
673    container_node_types: &["class_body", "protocol_body", "enum_class_body", "function_body"],
674    call_entity_identifiers: &[],
675    suppressed_nested_entities: &[],
676    scope_boundary_types: &[],
677    get_language: get_swift,
678    scope_resolve: Some(&SWIFT_SCOPE_CONFIG),
679};
680
681#[cfg(feature = "lang-elixir")]
682static ELIXIR_CONFIG: LanguageConfig = LanguageConfig {
683    id: "elixir",
684    extensions: &[".ex", ".exs"],
685    entity_node_types: &[],
686    container_node_types: &["do_block"],
687    call_entity_identifiers: &[
688        "defmodule", "def", "defp", "defmacro", "defmacrop",
689        "defguard", "defguardp", "defprotocol", "defimpl",
690        "defstruct", "defexception", "defdelegate",
691    ],
692    suppressed_nested_entities: &[],
693    scope_boundary_types: &[],
694    get_language: get_elixir,
695    scope_resolve: None,
696};
697
698#[cfg(feature = "lang-bash")]
699static BASH_CONFIG: LanguageConfig = LanguageConfig {
700    id: "bash",
701    extensions: &[".sh"],
702    entity_node_types: &["function_definition"],
703    container_node_types: &["compound_statement"],
704    call_entity_identifiers: &[],
705    suppressed_nested_entities: &[],
706    scope_boundary_types: &[],
707    get_language: get_bash,
708    scope_resolve: Some(&BASH_SCOPE_CONFIG),
709};
710
711#[cfg(feature = "lang-hcl")]
712static HCL_CONFIG: LanguageConfig = LanguageConfig {
713    id: "hcl",
714    extensions: &[".hcl", ".tf", ".tfvars"],
715    entity_node_types: &["block", "attribute"],
716    container_node_types: &["body"],
717    call_entity_identifiers: &[],
718    suppressed_nested_entities: &[SuppressedNestedEntity {
719        parent_entity_node_type: "block",
720        child_entity_node_type: "attribute",
721    }],
722    scope_boundary_types: &[],
723    get_language: get_hcl,
724    scope_resolve: None,
725};
726
727#[cfg(feature = "lang-kotlin")]
728static KOTLIN_CONFIG: LanguageConfig = LanguageConfig {
729    id: "kotlin",
730    extensions: &[".kt", ".kts"],
731    entity_node_types: &[
732        "function_declaration",
733        "class_declaration",
734        "object_declaration",
735        "property_declaration",
736        "companion_object",
737        "secondary_constructor",
738        "type_alias",
739    ],
740    container_node_types: &["class_body", "enum_class_body"],
741    call_entity_identifiers: &[],
742    suppressed_nested_entities: &[],
743    scope_boundary_types: &[],
744    get_language: get_kotlin,
745    scope_resolve: Some(&KOTLIN_SCOPE_CONFIG),
746};
747
748#[cfg(feature = "lang-xml")]
749static XML_CONFIG: LanguageConfig = LanguageConfig {
750    id: "xml",
751    extensions: &[".xml", ".plist", ".svg", ".xhtml", ".csproj", ".fsproj", ".vbproj", ".props", ".targets", ".nuspec", ".resx", ".xaml", ".axml"],
752    entity_node_types: &["element"],
753    container_node_types: &["content"],
754    call_entity_identifiers: &[],
755    suppressed_nested_entities: &[],
756    scope_boundary_types: &[],
757    get_language: get_xml,
758    scope_resolve: None,
759};
760
761#[cfg(feature = "lang-dart")]
762static DART_CONFIG: LanguageConfig = LanguageConfig {
763    id: "dart",
764    extensions: &[".dart"],
765    entity_node_types: &[
766        "class_declaration",
767        "mixin_declaration",
768        "extension_declaration",
769        "extension_type_declaration",
770        "enum_declaration",
771        "type_alias",
772        "class_member",
773        "function_signature",
774        "getter_signature",
775        "setter_signature",
776    ],
777    container_node_types: &["class_body", "enum_body", "extension_body"],
778    call_entity_identifiers: &[],
779    suppressed_nested_entities: &[],
780    scope_boundary_types: &[],
781    get_language: get_dart,
782    scope_resolve: Some(&DART_SCOPE_CONFIG),
783};
784  
785#[cfg(feature = "lang-perl")]
786static PERL_CONFIG: LanguageConfig = LanguageConfig {
787    id: "perl",
788    extensions: &[".pl", ".pm", ".t"],
789    entity_node_types: &[
790        "subroutine_declaration_statement",
791        "package_statement",
792    ],
793    container_node_types: &["block"],
794    call_entity_identifiers: &[],
795    suppressed_nested_entities: &[],
796    scope_boundary_types: &[],
797    get_language: get_perl,
798    scope_resolve: None,
799};
800
801#[cfg(feature = "lang-ocaml")]
802static OCAML_CONFIG: LanguageConfig = LanguageConfig {
803    id: "ocaml",
804    extensions: &[".ml"],
805    entity_node_types: &[
806        "value_definition",
807        "module_definition",
808        "module_type_definition",
809        "type_definition",
810        "exception_definition",
811        "class_definition",
812        "class_type_definition",
813        "external",
814    ],
815    container_node_types: &["structure", "module_binding"],
816    call_entity_identifiers: &[],
817    suppressed_nested_entities: &[],
818    scope_boundary_types: &[],
819    get_language: get_ocaml,
820    scope_resolve: None,
821};
822
823#[cfg(feature = "lang-ocaml")]
824static OCAML_INTERFACE_CONFIG: LanguageConfig = LanguageConfig {
825    id: "ocaml_interface",
826    extensions: &[".mli"],
827    entity_node_types: &[
828        "value_specification",
829        "module_definition",
830        "module_type_definition",
831        "type_definition",
832        "exception_definition",
833        "class_definition",
834        "class_type_definition",
835        "external",
836    ],
837    container_node_types: &["signature", "module_binding"],
838    call_entity_identifiers: &[],
839    suppressed_nested_entities: &[],
840    scope_boundary_types: &[],
841    get_language: get_ocaml_interface,
842    scope_resolve: None,
843};
844
845#[cfg(feature = "lang-scala")]
846static SCALA_CONFIG: LanguageConfig = LanguageConfig {
847    id: "scala",
848    extensions: &[".scala", ".sc", ".sbt", ".kojo", ".mill"],
849    entity_node_types: &[
850        "class_definition",
851        "object_definition",
852        "trait_definition",
853        "enum_definition",
854        "function_definition",
855        "function_declaration",
856        "val_definition",
857        "given_definition",
858        "extension_definition",
859        "type_definition",
860        "package_object",
861    ],
862    container_node_types: &["template_body", "enum_body", "with_template_body"],
863    call_entity_identifiers: &[],
864    suppressed_nested_entities: &[],
865    scope_boundary_types: &[],
866    get_language: get_scala,
867    scope_resolve: Some(&SCALA_SCOPE_CONFIG),
868};
869
870#[cfg(feature = "lang-zig")]
871static ZIG_CONFIG: LanguageConfig = LanguageConfig {
872    id: "zig",
873    extensions: &[".zig"],
874    entity_node_types: &[
875        "function_declaration",
876        "test_declaration",
877        "variable_declaration",
878    ],
879    container_node_types: &["block"],
880    call_entity_identifiers: &[],
881    suppressed_nested_entities: &[
882        SuppressedNestedEntity {
883            parent_entity_node_type: "function_declaration",
884            child_entity_node_type: "variable_declaration",
885        },
886    ],
887    scope_boundary_types: &[],
888    get_language: get_zig,
889    scope_resolve: Some(&ZIG_SCOPE_CONFIG),
890};
891
892#[cfg(feature = "lang-nix")]
893static NIX_CONFIG: LanguageConfig = LanguageConfig {
894    id: "nix",
895    extensions: &[".nix"],
896    entity_node_types: &["binding", "inherit", "inherit_from"],
897    container_node_types: &["binding_set"],
898    call_entity_identifiers: &[],
899    suppressed_nested_entities: &[],
900    scope_boundary_types: &[],
901    get_language: get_nix,
902    scope_resolve: None,
903};
904
905// ─── Scope Resolve Configs for Supported Languages ────────────────────────────
906
907static PYTHON_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
908    class_scope_nodes: &["class_definition"],
909    impl_scope_nodes: &[],
910    function_scope_nodes: &["function_definition"],
911    class_name_field: ClassNameField::Simple("name"),
912
913    assignment_rules: &[
914        AssignmentRule { node_kind: "assignment", strategy: AssignmentStrategy::LeftRight },
915        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
916    ],
917    assignment_recurse_into: &["block"],
918
919    param_rules: &[
920        ParamRule { node_kind: "typed_parameter", name_field: ParamNameField::WithFallback("name"), type_field: "type", skip_names: &["self", "cls"] },
921        ParamRule { node_kind: "typed_default_parameter", name_field: ParamNameField::WithFallback("name"), type_field: "type", skip_names: &["self", "cls"] },
922    ],
923
924    return_type_field: None,
925
926    call_nodes: &["call"],
927    call_style: CallNodeStyle::FunctionField("function"),
928    new_expr_nodes: &[],
929    new_expr_type_field: "constructor",
930    composite_literal_nodes: &[],
931    member_access: &[MemberAccess { node_kind: "attribute", object_field: "object", property_field: "attribute" }],
932    scoped_call_nodes: &[],
933
934    self_keywords: &["self", "cls"],
935
936    init_strategy: InitStrategy::ConstructorBody {
937        class_nodes: &["class_definition"],
938        init_names: &["__init__"],
939        init_node_kind: "function_definition",
940        self_keyword: "self",
941        access_kind: "attribute",
942        obj_field: "object",
943        prop_field: "attribute",
944    },
945
946    import_extractor: None, // set via import_rules
947    external_method: false,
948
949    builtins: &[
950        "print", "len", "range", "str", "int", "float", "bool",
951        "list", "dict", "set", "tuple", "type", "super",
952        "isinstance", "issubclass", "getattr", "setattr",
953        "hasattr", "delattr", "open", "input", "map",
954        "filter", "zip", "enumerate", "sorted", "reversed",
955        "min", "max", "sum", "any", "all", "abs",
956        "round", "format", "repr", "id", "hash",
957        "ValueError", "TypeError", "KeyError", "RuntimeError",
958        "Exception", "StopIteration",
959    ],
960};
961
962static TS_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
963    class_scope_nodes: &["class_declaration"],
964    impl_scope_nodes: &[],
965    function_scope_nodes: &["function_declaration", "method_definition"],
966    class_name_field: ClassNameField::Simple("name"),
967
968    assignment_rules: &[
969        AssignmentRule { node_kind: "lexical_declaration", strategy: AssignmentStrategy::Declarators },
970        AssignmentRule { node_kind: "variable_declaration", strategy: AssignmentStrategy::Declarators },
971        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
972    ],
973    assignment_recurse_into: &["statement_block"],
974
975    param_rules: &[
976        ParamRule { node_kind: "required_parameter", name_field: ParamNameField::WithFallback("pattern"), type_field: "type", skip_names: &["this"] },
977        ParamRule { node_kind: "optional_parameter", name_field: ParamNameField::WithFallback("pattern"), type_field: "type", skip_names: &["this"] },
978    ],
979
980    return_type_field: Some("return_type"),
981
982    call_nodes: &["call_expression"],
983    call_style: CallNodeStyle::FunctionField("function"),
984    new_expr_nodes: &["new_expression"],
985    new_expr_type_field: "constructor",
986    composite_literal_nodes: &[],
987    member_access: &[MemberAccess { node_kind: "member_expression", object_field: "object", property_field: "property" }],
988    scoped_call_nodes: &[],
989
990    self_keywords: &["this"],
991
992    init_strategy: InitStrategy::ConstructorBody {
993        class_nodes: &["class_declaration"],
994        init_names: &["constructor"],
995        init_node_kind: "method_definition",
996        self_keyword: "this",
997        access_kind: "member_expression",
998        obj_field: "object",
999        prop_field: "property",
1000    },
1001
1002    import_extractor: None,
1003    external_method: false,
1004
1005    builtins: &[
1006        "console", "parseInt", "parseFloat", "isNaN", "isFinite",
1007        "setTimeout", "setInterval", "clearTimeout", "clearInterval",
1008        "Promise", "Array", "Object", "Map", "Set", "WeakMap", "WeakSet",
1009        "JSON", "Math", "Date", "RegExp", "Error", "TypeError",
1010        "RangeError", "Symbol", "Proxy", "Reflect",
1011        "String", "Number", "Boolean", "BigInt",
1012        "require", "module", "exports", "process",
1013        "Buffer", "global", "window", "document",
1014        "fetch", "Response", "Request", "Headers", "URL",
1015    ],
1016};
1017
1018static RUST_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1019    class_scope_nodes: &["struct_item"],
1020    impl_scope_nodes: &["impl_item"],
1021    function_scope_nodes: &["function_item"],
1022    class_name_field: ClassNameField::Simple("name"),
1023
1024    assignment_rules: &[
1025        AssignmentRule { node_kind: "let_declaration", strategy: AssignmentStrategy::PatternBased },
1026    ],
1027    assignment_recurse_into: &["block", "expression_statement"],
1028
1029    param_rules: &[
1030        ParamRule { node_kind: "parameter", name_field: ParamNameField::RustPattern, type_field: "type", skip_names: &["self"] },
1031    ],
1032
1033    return_type_field: Some("return_type"),
1034
1035    call_nodes: &["call_expression"],
1036    call_style: CallNodeStyle::FunctionField("function"),
1037    new_expr_nodes: &[],
1038    new_expr_type_field: "constructor",
1039    composite_literal_nodes: &[],
1040    member_access: &[MemberAccess { node_kind: "field_expression", object_field: "value", property_field: "field" }],
1041    scoped_call_nodes: &["scoped_identifier"],
1042
1043    self_keywords: &["self"],
1044
1045    init_strategy: InitStrategy::StructFields {
1046        struct_nodes: &["struct_item"],
1047    },
1048
1049    import_extractor: None,
1050    external_method: false,
1051
1052    builtins: &[
1053        "println", "eprintln", "print", "eprint", "dbg",
1054        "format", "write", "writeln",
1055        "vec", "panic", "todo", "unimplemented", "unreachable",
1056        "assert", "assert_eq", "assert_ne", "debug_assert",
1057        "Some", "None", "Ok", "Err",
1058        "Box", "Vec", "String", "HashMap", "HashSet",
1059        "Arc", "Rc", "Mutex", "RwLock", "Cell", "RefCell",
1060        "Option", "Result", "Iterator", "IntoIterator",
1061        "Clone", "Copy", "Debug", "Display", "Default",
1062        "From", "Into", "TryFrom", "TryInto",
1063        "Send", "Sync", "Sized", "Unpin",
1064        "cfg", "derive", "include", "env",
1065    ],
1066};
1067
1068static GO_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1069    class_scope_nodes: &["type_declaration"],
1070    impl_scope_nodes: &[],
1071    function_scope_nodes: &["function_declaration", "method_declaration"],
1072    class_name_field: ClassNameField::TypeSpec { spec_kind: "type_spec", field: "name" },
1073
1074    assignment_rules: &[
1075        AssignmentRule { node_kind: "short_var_declaration", strategy: AssignmentStrategy::ShortVar },
1076        AssignmentRule { node_kind: "var_declaration", strategy: AssignmentStrategy::VarSpec },
1077    ],
1078    assignment_recurse_into: &["block"],
1079
1080    param_rules: &[
1081        ParamRule { node_kind: "parameter_declaration", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1082    ],
1083
1084    return_type_field: Some("result"),
1085
1086    call_nodes: &["call_expression"],
1087    call_style: CallNodeStyle::FunctionField("function"),
1088    new_expr_nodes: &[],
1089    new_expr_type_field: "constructor",
1090    composite_literal_nodes: &["composite_literal"],
1091    member_access: &[MemberAccess { node_kind: "selector_expression", object_field: "operand", property_field: "field" }],
1092    scoped_call_nodes: &[],
1093
1094    self_keywords: &[],
1095
1096    init_strategy: InitStrategy::StructFields {
1097        struct_nodes: &["type_declaration"],
1098    },
1099
1100    import_extractor: None,
1101    external_method: true,
1102
1103    builtins: &[
1104        "fmt", "log", "os", "io", "strings", "strconv", "bytes",
1105        "make", "len", "cap", "append", "copy", "delete", "close",
1106        "panic", "recover", "new", "print", "println",
1107        "error", "string", "int", "int8", "int16", "int32", "int64",
1108        "uint", "uint8", "uint16", "uint32", "uint64",
1109        "float32", "float64", "complex64", "complex128",
1110        "bool", "byte", "rune", "uintptr",
1111        "Println", "Printf", "Sprintf", "Fprintf", "Errorf",
1112    ],
1113};
1114
1115// ─── Tier 1 Scope Resolve Configs ─────────────────────────────────────────────
1116
1117static JAVA_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1118    class_scope_nodes: &["class_declaration", "interface_declaration", "enum_declaration"],
1119    impl_scope_nodes: &[],
1120    function_scope_nodes: &["method_declaration", "constructor_declaration"],
1121    class_name_field: ClassNameField::Simple("name"),
1122
1123    assignment_rules: &[
1124        AssignmentRule { node_kind: "local_variable_declaration", strategy: AssignmentStrategy::Declarators },
1125        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1126    ],
1127    assignment_recurse_into: &["block"],
1128
1129    param_rules: &[
1130        ParamRule { node_kind: "formal_parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1131    ],
1132
1133    return_type_field: Some("type"),
1134
1135    call_nodes: &["method_invocation"],
1136    call_style: CallNodeStyle::DirectMethod { object_field: "object", method_field: "name" },
1137    new_expr_nodes: &["object_creation_expression"],
1138    new_expr_type_field: "type",
1139    composite_literal_nodes: &[],
1140    member_access: &[MemberAccess { node_kind: "method_invocation", object_field: "object", property_field: "name" }],
1141    scoped_call_nodes: &[],
1142
1143    self_keywords: &["this"],
1144
1145    init_strategy: InitStrategy::None,
1146    import_extractor: None,
1147    external_method: false,
1148
1149    builtins: &[
1150        "System", "String", "Integer", "Long", "Double", "Float", "Boolean",
1151        "Object", "Class", "Math", "Collections", "Arrays", "List", "Map", "Set",
1152        "ArrayList", "HashMap", "HashSet", "Optional", "Stream",
1153        "Exception", "RuntimeException", "NullPointerException",
1154        "println", "printf", "format",
1155    ],
1156};
1157
1158static CSHARP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1159    class_scope_nodes: &["class_declaration", "interface_declaration", "struct_declaration", "enum_declaration"],
1160    impl_scope_nodes: &[],
1161    function_scope_nodes: &["method_declaration", "constructor_declaration"],
1162    class_name_field: ClassNameField::Simple("name"),
1163
1164    assignment_rules: &[
1165        AssignmentRule { node_kind: "local_declaration_statement", strategy: AssignmentStrategy::Declarators },
1166        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1167    ],
1168    assignment_recurse_into: &["block"],
1169
1170    param_rules: &[
1171        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1172    ],
1173
1174    return_type_field: Some("type"),
1175
1176    call_nodes: &["invocation_expression"],
1177    call_style: CallNodeStyle::FunctionField("function"),
1178    new_expr_nodes: &["object_creation_expression"],
1179    new_expr_type_field: "type",
1180    composite_literal_nodes: &[],
1181    member_access: &[MemberAccess { node_kind: "member_access_expression", object_field: "expression", property_field: "name" }],
1182    scoped_call_nodes: &[],
1183
1184    self_keywords: &["this"],
1185
1186    init_strategy: InitStrategy::None,
1187    import_extractor: None,
1188    external_method: false,
1189
1190    builtins: &[
1191        "Console", "String", "Int32", "Int64", "Double", "Boolean",
1192        "Object", "Math", "List", "Dictionary", "HashSet",
1193        "Task", "Async", "Exception", "ArgumentException",
1194        "WriteLine", "ReadLine", "ToString", "Equals",
1195    ],
1196};
1197
1198static CPP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1199    class_scope_nodes: &["class_specifier", "struct_specifier"],
1200    impl_scope_nodes: &[],
1201    function_scope_nodes: &["function_definition"],
1202    class_name_field: ClassNameField::Simple("name"),
1203
1204    assignment_rules: &[
1205        AssignmentRule { node_kind: "declaration", strategy: AssignmentStrategy::Declarators },
1206        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1207    ],
1208    assignment_recurse_into: &["compound_statement"],
1209
1210    param_rules: &[
1211        ParamRule { node_kind: "parameter_declaration", name_field: ParamNameField::Simple("declarator"), type_field: "type", skip_names: &[] },
1212    ],
1213
1214    return_type_field: Some("type"),
1215
1216    call_nodes: &["call_expression"],
1217    call_style: CallNodeStyle::FunctionField("function"),
1218    new_expr_nodes: &["new_expression"],
1219    new_expr_type_field: "type",
1220    composite_literal_nodes: &[],
1221    member_access: &[
1222        MemberAccess { node_kind: "field_expression", object_field: "argument", property_field: "field" },
1223    ],
1224    scoped_call_nodes: &["qualified_identifier"],
1225
1226    self_keywords: &["this"],
1227
1228    init_strategy: InitStrategy::StructFields {
1229        struct_nodes: &["class_specifier", "struct_specifier"],
1230    },
1231    import_extractor: None,
1232    external_method: false,
1233
1234    builtins: &[
1235        "std", "cout", "cin", "endl", "printf", "scanf", "malloc", "free",
1236        "string", "vector", "map", "set", "pair", "make_pair",
1237        "shared_ptr", "unique_ptr", "make_shared", "make_unique",
1238        "nullptr", "size_t", "int", "char", "double", "float", "bool",
1239    ],
1240};
1241
1242static RUBY_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1243    class_scope_nodes: &["class", "module"],
1244    impl_scope_nodes: &[],
1245    function_scope_nodes: &["method", "singleton_method"],
1246    class_name_field: ClassNameField::Simple("name"),
1247
1248    assignment_rules: &[
1249        AssignmentRule { node_kind: "assignment", strategy: AssignmentStrategy::LeftRight },
1250    ],
1251    assignment_recurse_into: &["body_statement"],
1252
1253    param_rules: &[],
1254
1255    return_type_field: None,
1256
1257    call_nodes: &["call"],
1258    call_style: CallNodeStyle::DirectMethod { object_field: "receiver", method_field: "method" },
1259    new_expr_nodes: &[],
1260    new_expr_type_field: "constructor",
1261    composite_literal_nodes: &[],
1262    member_access: &[MemberAccess { node_kind: "call", object_field: "receiver", property_field: "method" }],
1263    scoped_call_nodes: &["scope_resolution"],
1264
1265    self_keywords: &["self"],
1266
1267    init_strategy: InitStrategy::None,
1268    import_extractor: None,
1269    external_method: false,
1270
1271    builtins: &[
1272        "puts", "print", "p", "require", "require_relative", "include", "extend",
1273        "attr_accessor", "attr_reader", "attr_writer",
1274        "raise", "rescue", "yield", "block_given?",
1275        "Array", "Hash", "String", "Integer", "Float", "Symbol",
1276        "nil", "true", "false",
1277    ],
1278};
1279
1280static KOTLIN_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1281    class_scope_nodes: &["class_declaration", "object_declaration"],
1282    impl_scope_nodes: &[],
1283    function_scope_nodes: &["function_declaration", "secondary_constructor"],
1284    class_name_field: ClassNameField::Simple("name"),
1285
1286    assignment_rules: &[
1287        AssignmentRule { node_kind: "property_declaration", strategy: AssignmentStrategy::Declarators },
1288    ],
1289    assignment_recurse_into: &["statements"],
1290
1291    param_rules: &[
1292        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1293    ],
1294
1295    return_type_field: Some("type"),
1296
1297    call_nodes: &["call_expression"],
1298    call_style: CallNodeStyle::FunctionField("function"),
1299    new_expr_nodes: &[],
1300    new_expr_type_field: "constructor",
1301    composite_literal_nodes: &[],
1302    member_access: &[MemberAccess { node_kind: "navigation_expression", object_field: "expression", property_field: "navigation_suffix" }],
1303    scoped_call_nodes: &[],
1304
1305    self_keywords: &["this"],
1306
1307    init_strategy: InitStrategy::None,
1308    import_extractor: None,
1309    external_method: false,
1310
1311    builtins: &[
1312        "println", "print", "listOf", "mapOf", "setOf", "arrayOf",
1313        "mutableListOf", "mutableMapOf", "mutableSetOf",
1314        "String", "Int", "Long", "Double", "Float", "Boolean",
1315        "Any", "Unit", "Nothing", "Pair", "Triple",
1316        "require", "check", "error", "TODO",
1317    ],
1318};
1319
1320static PHP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1321    class_scope_nodes: &["class_declaration", "interface_declaration", "trait_declaration"],
1322    impl_scope_nodes: &[],
1323    function_scope_nodes: &["function_definition", "method_declaration"],
1324    class_name_field: ClassNameField::Simple("name"),
1325
1326    assignment_rules: &[
1327        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1328    ],
1329    assignment_recurse_into: &["compound_statement"],
1330
1331    param_rules: &[
1332        ParamRule { node_kind: "simple_parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1333    ],
1334
1335    return_type_field: Some("return_type"),
1336
1337    call_nodes: &["function_call_expression", "member_call_expression"],
1338    call_style: CallNodeStyle::FunctionField("function"),
1339    new_expr_nodes: &["object_creation_expression"],
1340    new_expr_type_field: "type",
1341    composite_literal_nodes: &[],
1342    member_access: &[MemberAccess { node_kind: "member_call_expression", object_field: "object", property_field: "name" }],
1343    scoped_call_nodes: &["scoped_call_expression"],
1344
1345    self_keywords: &["$this"],
1346
1347    init_strategy: InitStrategy::None,
1348    import_extractor: None,
1349    external_method: false,
1350
1351    builtins: &[
1352        "echo", "print", "var_dump", "print_r", "isset", "unset", "empty",
1353        "array", "count", "strlen", "substr", "strpos",
1354        "is_null", "is_array", "is_string", "is_int",
1355        "Exception", "RuntimeException", "InvalidArgumentException",
1356    ],
1357};
1358
1359static SWIFT_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1360    class_scope_nodes: &["class_declaration", "protocol_declaration"],
1361    impl_scope_nodes: &[],
1362    function_scope_nodes: &["function_declaration", "init_declaration"],
1363    class_name_field: ClassNameField::Simple("name"),
1364
1365    assignment_rules: &[
1366        AssignmentRule { node_kind: "property_declaration", strategy: AssignmentStrategy::Declarators },
1367    ],
1368    assignment_recurse_into: &["function_body"],
1369
1370    param_rules: &[
1371        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1372    ],
1373
1374    return_type_field: Some("return_type"),
1375
1376    call_nodes: &["call_expression"],
1377    call_style: CallNodeStyle::FunctionField("function"),
1378    new_expr_nodes: &[],
1379    new_expr_type_field: "constructor",
1380    composite_literal_nodes: &[],
1381    member_access: &[MemberAccess { node_kind: "navigation_expression", object_field: "target", property_field: "suffix" }],
1382    scoped_call_nodes: &[],
1383
1384    self_keywords: &["self"],
1385
1386    init_strategy: InitStrategy::None,
1387    import_extractor: None,
1388    external_method: false,
1389
1390    builtins: &[
1391        "print", "debugPrint", "fatalError", "precondition", "assert",
1392        "String", "Int", "Double", "Float", "Bool", "Array", "Dictionary", "Set",
1393        "Optional", "Result", "Error", "NSError",
1394    ],
1395};
1396
1397static SCALA_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1398    class_scope_nodes: &["class_definition", "object_definition", "trait_definition"],
1399    impl_scope_nodes: &[],
1400    function_scope_nodes: &["function_definition", "function_declaration"],
1401    class_name_field: ClassNameField::Simple("name"),
1402
1403    assignment_rules: &[
1404        AssignmentRule { node_kind: "val_definition", strategy: AssignmentStrategy::Declarators },
1405    ],
1406    assignment_recurse_into: &["template_body"],
1407
1408    param_rules: &[
1409        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1410    ],
1411
1412    return_type_field: Some("return_type"),
1413
1414    call_nodes: &["call_expression"],
1415    call_style: CallNodeStyle::FunctionField("function"),
1416    new_expr_nodes: &[],
1417    new_expr_type_field: "constructor",
1418    composite_literal_nodes: &[],
1419    member_access: &[MemberAccess { node_kind: "field_expression", object_field: "value", property_field: "field" }],
1420    scoped_call_nodes: &[],
1421
1422    self_keywords: &["this"],
1423
1424    init_strategy: InitStrategy::None,
1425    import_extractor: None,
1426    external_method: false,
1427
1428    builtins: &[
1429        "println", "print", "require", "assert",
1430        "String", "Int", "Long", "Double", "Float", "Boolean",
1431        "List", "Map", "Set", "Seq", "Vector", "Option", "Some", "None",
1432        "Future", "Try", "Either", "Left", "Right",
1433    ],
1434};
1435
1436// ─── Tier 2 Scope Resolve Configs (Minimal) ───────────────────────────────────
1437
1438static DART_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1439    class_scope_nodes: &["class_declaration", "mixin_declaration", "enum_declaration"],
1440    impl_scope_nodes: &[],
1441    function_scope_nodes: &["function_signature", "method_signature"],
1442    class_name_field: ClassNameField::Simple("name"),
1443
1444    assignment_rules: &[],
1445    assignment_recurse_into: &[],
1446
1447    param_rules: &[
1448        ParamRule { node_kind: "formal_parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1449    ],
1450
1451    return_type_field: None,
1452
1453    call_nodes: &["function_expression_body"],
1454    call_style: CallNodeStyle::FunctionField("function"),
1455    new_expr_nodes: &[],
1456    new_expr_type_field: "constructor",
1457    composite_literal_nodes: &[],
1458    member_access: &[],
1459    scoped_call_nodes: &[],
1460
1461    self_keywords: &["this"],
1462
1463    init_strategy: InitStrategy::None,
1464    import_extractor: None,
1465    external_method: false,
1466
1467    builtins: &[
1468        "print", "debugPrint", "String", "int", "double", "bool",
1469        "List", "Map", "Set", "Future", "Stream",
1470    ],
1471};
1472
1473static ZIG_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1474    class_scope_nodes: &[],
1475    impl_scope_nodes: &[],
1476    function_scope_nodes: &["function_declaration", "test_declaration"],
1477    class_name_field: ClassNameField::Simple("name"),
1478
1479    assignment_rules: &[],
1480    assignment_recurse_into: &[],
1481
1482    param_rules: &[],
1483
1484    return_type_field: None,
1485
1486    call_nodes: &["call_expression"],
1487    call_style: CallNodeStyle::FunctionField("function"),
1488    new_expr_nodes: &[],
1489    new_expr_type_field: "constructor",
1490    composite_literal_nodes: &[],
1491    member_access: &[MemberAccess { node_kind: "field_expression", object_field: "object", property_field: "field" }],
1492    scoped_call_nodes: &[],
1493
1494    self_keywords: &[],
1495
1496    init_strategy: InitStrategy::None,
1497    import_extractor: None,
1498    external_method: false,
1499
1500    builtins: &[
1501        "std", "print", "debug", "assert", "expect",
1502        "allocator", "mem", "testing",
1503    ],
1504};
1505
1506static BASH_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1507    class_scope_nodes: &[],
1508    impl_scope_nodes: &[],
1509    function_scope_nodes: &["function_definition"],
1510    class_name_field: ClassNameField::Simple("name"),
1511
1512    assignment_rules: &[],
1513    assignment_recurse_into: &[],
1514
1515    param_rules: &[],
1516
1517    return_type_field: None,
1518
1519    call_nodes: &["command"],
1520    call_style: CallNodeStyle::FunctionField("name"),
1521    new_expr_nodes: &[],
1522    new_expr_type_field: "constructor",
1523    composite_literal_nodes: &[],
1524    member_access: &[],
1525    scoped_call_nodes: &[],
1526
1527    self_keywords: &[],
1528
1529    init_strategy: InitStrategy::None,
1530    import_extractor: None,
1531    external_method: false,
1532
1533    builtins: &[
1534        "echo", "printf", "cd", "ls", "cat", "grep", "sed", "awk",
1535        "if", "then", "else", "fi", "for", "while", "do", "done",
1536        "exit", "return", "export", "source", "eval",
1537    ],
1538};
1539
1540macro_rules! all_configs {
1541    () => {{
1542        &[
1543            #[cfg(feature = "lang-typescript")]
1544            &TYPESCRIPT_CONFIG,
1545            #[cfg(feature = "lang-typescript")]
1546            &TSX_CONFIG,
1547            #[cfg(feature = "lang-javascript")]
1548            &JAVASCRIPT_CONFIG,
1549            #[cfg(feature = "lang-python")]
1550            &PYTHON_CONFIG,
1551            #[cfg(feature = "lang-go")]
1552            &GO_CONFIG,
1553            #[cfg(feature = "lang-rust")]
1554            &RUST_CONFIG,
1555            #[cfg(feature = "lang-java")]
1556            &JAVA_CONFIG,
1557            #[cfg(feature = "lang-c")]
1558            &C_CONFIG,
1559            #[cfg(feature = "lang-cpp")]
1560            &CPP_CONFIG,
1561            #[cfg(feature = "lang-ruby")]
1562            &RUBY_CONFIG,
1563            #[cfg(feature = "lang-csharp")]
1564            &CSHARP_CONFIG,
1565            #[cfg(feature = "lang-php")]
1566            &PHP_CONFIG,
1567            #[cfg(feature = "lang-fortran")]
1568            &FORTRAN_CONFIG,
1569            #[cfg(feature = "lang-swift")]
1570            &SWIFT_CONFIG,
1571            #[cfg(feature = "lang-elixir")]
1572            &ELIXIR_CONFIG,
1573            #[cfg(feature = "lang-bash")]
1574            &BASH_CONFIG,
1575            #[cfg(feature = "lang-hcl")]
1576            &HCL_CONFIG,
1577            #[cfg(feature = "lang-kotlin")]
1578            &KOTLIN_CONFIG,
1579            #[cfg(feature = "lang-xml")]
1580            &XML_CONFIG,
1581            #[cfg(feature = "lang-dart")]
1582            &DART_CONFIG,
1583            #[cfg(feature = "lang-perl")]
1584            &PERL_CONFIG,
1585            #[cfg(feature = "lang-ocaml")]
1586            &OCAML_CONFIG,
1587            #[cfg(feature = "lang-ocaml")]
1588            &OCAML_INTERFACE_CONFIG,
1589            #[cfg(feature = "lang-scala")]
1590            &SCALA_CONFIG,
1591            #[cfg(feature = "lang-zig")]
1592            &ZIG_CONFIG,
1593            #[cfg(feature = "lang-nix")]
1594            &NIX_CONFIG,
1595        ]
1596    }};
1597}
1598
1599static ALL_CONFIGS: &[&LanguageConfig] = all_configs!();
1600
1601pub fn get_language_config(extension: &str) -> Option<&'static LanguageConfig> {
1602    ALL_CONFIGS
1603        .iter()
1604        .find(|c| c.extensions.contains(&extension))
1605        .copied()
1606}
1607
1608pub fn get_all_code_extensions() -> &'static [&'static str] {
1609    // Derived from ALL_CONFIGS to avoid duplication drift.
1610    // When you add an extension to a LanguageConfig, it's automatically included here.
1611    static EXTENSIONS: std::sync::LazyLock<Vec<&'static str>> = std::sync::LazyLock::new(|| {
1612        ALL_CONFIGS.iter().flat_map(|c| c.extensions.iter().copied()).collect()
1613    });
1614    &EXTENSIONS
1615}