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        "method_signature",
397        "property_signature",
398    ],
399    container_node_types: &["class_body", "interface_body", "enum_body", "statement_block"],
400    call_entity_identifiers: &[],
401    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
402    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
403    get_language: get_typescript,
404    scope_resolve: Some(&TS_SCOPE_CONFIG),
405};
406
407#[cfg(feature = "lang-typescript")]
408static TSX_CONFIG: LanguageConfig = LanguageConfig {
409    id: "tsx",
410    extensions: &[".tsx"],
411    entity_node_types: &[
412        "function_declaration",
413        "generator_function_declaration",
414        "class_declaration",
415        "interface_declaration",
416        "type_alias_declaration",
417        "enum_declaration",
418        "export_statement",
419        "lexical_declaration",
420        "variable_declaration",
421        "method_definition",
422        "public_field_definition",
423        "method_signature",
424        "property_signature",
425    ],
426    container_node_types: &["class_body", "interface_body", "enum_body", "statement_block"],
427    call_entity_identifiers: &[],
428    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
429    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
430    get_language: get_tsx,
431    scope_resolve: Some(&TS_SCOPE_CONFIG),
432};
433
434#[cfg(feature = "lang-javascript")]
435static JAVASCRIPT_CONFIG: LanguageConfig = LanguageConfig {
436    id: "javascript",
437    extensions: &[".js", ".jsx", ".mjs", ".cjs", ".es6"],
438    entity_node_types: &[
439        "function_declaration",
440        "generator_function_declaration",
441        "class_declaration",
442        "export_statement",
443        "lexical_declaration",
444        "variable_declaration",
445        "method_definition",
446        "field_definition",
447    ],
448    container_node_types: &["class_body", "statement_block"],
449    call_entity_identifiers: &[],
450    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
451    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
452    get_language: get_javascript,
453    scope_resolve: Some(&TS_SCOPE_CONFIG),
454};
455
456#[cfg(feature = "lang-python")]
457static PYTHON_CONFIG: LanguageConfig = LanguageConfig {
458    id: "python",
459    extensions: &[".py", ".pyi"],
460    entity_node_types: &[
461        "function_definition",
462        "class_definition",
463        "decorated_definition",
464    ],
465    container_node_types: &["block"],
466    call_entity_identifiers: &[],
467    suppressed_nested_entities: &[],
468    scope_boundary_types: &[],
469    get_language: get_python,
470    scope_resolve: Some(&PYTHON_SCOPE_CONFIG),
471};
472
473#[cfg(feature = "lang-go")]
474static GO_CONFIG: LanguageConfig = LanguageConfig {
475    id: "go",
476    extensions: &[".go"],
477    entity_node_types: &[
478        "function_declaration",
479        "method_declaration",
480        "type_declaration",
481        "var_declaration",
482        "const_declaration",
483    ],
484    container_node_types: &["block"],
485    call_entity_identifiers: &[],
486    suppressed_nested_entities: &[],
487    scope_boundary_types: &[],
488    get_language: get_go,
489    scope_resolve: Some(&GO_SCOPE_CONFIG),
490};
491
492#[cfg(feature = "lang-rust")]
493static RUST_CONFIG: LanguageConfig = LanguageConfig {
494    id: "rust",
495    extensions: &[".rs"],
496    entity_node_types: &[
497        "function_item",
498        "struct_item",
499        "enum_item",
500        "impl_item",
501        "trait_item",
502        "mod_item",
503        "const_item",
504        "static_item",
505        "type_item",
506        "macro_definition",
507    ],
508    container_node_types: &["declaration_list", "block"],
509    call_entity_identifiers: &[],
510    suppressed_nested_entities: &[],
511    scope_boundary_types: &[],
512    get_language: get_rust,
513    scope_resolve: Some(&RUST_SCOPE_CONFIG),
514};
515
516#[cfg(feature = "lang-java")]
517static JAVA_CONFIG: LanguageConfig = LanguageConfig {
518    id: "java",
519    extensions: &[".java"],
520    entity_node_types: &[
521        "class_declaration",
522        "method_declaration",
523        "interface_declaration",
524        "enum_declaration",
525        "record_declaration",
526        "field_declaration",
527        "constructor_declaration",
528        "annotation_type_declaration",
529    ],
530    container_node_types: &["class_body", "interface_body", "enum_body", "record_body", "block"],
531    call_entity_identifiers: &[],
532    suppressed_nested_entities: &[],
533    scope_boundary_types: &[],
534    get_language: get_java,
535    scope_resolve: Some(&JAVA_SCOPE_CONFIG),
536};
537
538#[cfg(feature = "lang-c")]
539static C_CONFIG: LanguageConfig = LanguageConfig {
540    id: "c",
541    extensions: &[".c", ".h"],
542    entity_node_types: &[
543        "function_definition",
544        "struct_specifier",
545        "enum_specifier",
546        "union_specifier",
547        "type_definition",
548        "declaration",
549    ],
550    container_node_types: &["compound_statement"],
551    call_entity_identifiers: &[],
552    suppressed_nested_entities: &[],
553    scope_boundary_types: &[],
554    get_language: get_c,
555    scope_resolve: None,
556};
557
558#[cfg(feature = "lang-cpp")]
559static CPP_CONFIG: LanguageConfig = LanguageConfig {
560    id: "cpp",
561    extensions: &[".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx"],
562    entity_node_types: &[
563        "function_definition",
564        "class_specifier",
565        "struct_specifier",
566        "enum_specifier",
567        "namespace_definition",
568        "template_declaration",
569        "declaration",
570        "type_definition",
571    ],
572    container_node_types: &["field_declaration_list", "declaration_list", "compound_statement"],
573    call_entity_identifiers: &[],
574    suppressed_nested_entities: &[],
575    scope_boundary_types: &[],
576    get_language: get_cpp,
577    scope_resolve: Some(&CPP_SCOPE_CONFIG),
578};
579
580#[cfg(feature = "lang-ruby")]
581static RUBY_CONFIG: LanguageConfig = LanguageConfig {
582    id: "ruby",
583    extensions: &[".rb"],
584    entity_node_types: &[
585        "method",
586        "singleton_method",
587        "class",
588        "module",
589    ],
590    container_node_types: &["body_statement"],
591    call_entity_identifiers: &[],
592    suppressed_nested_entities: &[],
593    scope_boundary_types: &[],
594    get_language: get_ruby,
595    scope_resolve: Some(&RUBY_SCOPE_CONFIG),
596};
597
598#[cfg(feature = "lang-csharp")]
599static CSHARP_CONFIG: LanguageConfig = LanguageConfig {
600    id: "csharp",
601    extensions: &[".cs"],
602    entity_node_types: &[
603        "method_declaration",
604        "class_declaration",
605        "interface_declaration",
606        "enum_declaration",
607        "struct_declaration",
608        "record_declaration",
609        "record_struct_declaration",
610        "namespace_declaration",
611        "property_declaration",
612        "constructor_declaration",
613        "field_declaration",
614    ],
615    container_node_types: &["declaration_list", "record_body", "block"],
616    call_entity_identifiers: &[],
617    suppressed_nested_entities: &[],
618    scope_boundary_types: &[],
619    get_language: get_csharp,
620    scope_resolve: Some(&CSHARP_SCOPE_CONFIG),
621};
622
623#[cfg(feature = "lang-php")]
624static PHP_CONFIG: LanguageConfig = LanguageConfig {
625    id: "php",
626    extensions: &[".php", ".inc", ".phtml", ".module"],
627    entity_node_types: &[
628        "function_definition",
629        "class_declaration",
630        "method_declaration",
631        "interface_declaration",
632        "trait_declaration",
633        "enum_declaration",
634        "namespace_definition",
635    ],
636    container_node_types: &["declaration_list", "enum_declaration_list", "compound_statement"],
637    call_entity_identifiers: &[],
638    suppressed_nested_entities: &[],
639    scope_boundary_types: &[],
640    get_language: get_php,
641    scope_resolve: Some(&PHP_SCOPE_CONFIG),
642};
643
644#[cfg(feature = "lang-fortran")]
645static FORTRAN_CONFIG: LanguageConfig = LanguageConfig {
646    id: "fortran",
647    extensions: &[".f90", ".f95", ".f03", ".f08", ".f", ".for"],
648    entity_node_types: &[
649        "function",
650        "subroutine",
651        "module",
652        "program",
653        "interface",
654        "type_declaration",
655    ],
656    container_node_types: &["module", "program", "internal_procedures"],
657    call_entity_identifiers: &[],
658    suppressed_nested_entities: &[],
659    scope_boundary_types: &[],
660    get_language: get_fortran,
661    scope_resolve: None,
662};
663
664#[cfg(feature = "lang-swift")]
665static SWIFT_CONFIG: LanguageConfig = LanguageConfig {
666    id: "swift",
667    extensions: &[".swift"],
668    entity_node_types: &[
669        "function_declaration",
670        "class_declaration",
671        "protocol_declaration",
672        "struct_declaration",
673        "enum_declaration",
674        "init_declaration",
675        "deinit_declaration",
676        "subscript_declaration",
677        "typealias_declaration",
678        "property_declaration",
679        "operator_declaration",
680        "associatedtype_declaration",
681    ],
682    container_node_types: &["class_body", "protocol_body", "enum_class_body", "struct_body", "function_body"],
683    call_entity_identifiers: &[],
684    suppressed_nested_entities: &[],
685    scope_boundary_types: &[],
686    get_language: get_swift,
687    scope_resolve: Some(&SWIFT_SCOPE_CONFIG),
688};
689
690#[cfg(feature = "lang-elixir")]
691static ELIXIR_CONFIG: LanguageConfig = LanguageConfig {
692    id: "elixir",
693    extensions: &[".ex", ".exs"],
694    entity_node_types: &[],
695    container_node_types: &["do_block"],
696    call_entity_identifiers: &[
697        "defmodule", "def", "defp", "defmacro", "defmacrop",
698        "defguard", "defguardp", "defprotocol", "defimpl",
699        "defstruct", "defexception", "defdelegate",
700    ],
701    suppressed_nested_entities: &[],
702    scope_boundary_types: &[],
703    get_language: get_elixir,
704    scope_resolve: None,
705};
706
707#[cfg(feature = "lang-bash")]
708static BASH_CONFIG: LanguageConfig = LanguageConfig {
709    id: "bash",
710    extensions: &[".sh"],
711    entity_node_types: &["function_definition"],
712    container_node_types: &["compound_statement"],
713    call_entity_identifiers: &[],
714    suppressed_nested_entities: &[],
715    scope_boundary_types: &[],
716    get_language: get_bash,
717    scope_resolve: Some(&BASH_SCOPE_CONFIG),
718};
719
720#[cfg(feature = "lang-hcl")]
721static HCL_CONFIG: LanguageConfig = LanguageConfig {
722    id: "hcl",
723    extensions: &[".hcl", ".tf", ".tfvars"],
724    entity_node_types: &["block", "attribute"],
725    container_node_types: &["body"],
726    call_entity_identifiers: &[],
727    suppressed_nested_entities: &[SuppressedNestedEntity {
728        parent_entity_node_type: "block",
729        child_entity_node_type: "attribute",
730    }],
731    scope_boundary_types: &[],
732    get_language: get_hcl,
733    scope_resolve: None,
734};
735
736#[cfg(feature = "lang-kotlin")]
737static KOTLIN_CONFIG: LanguageConfig = LanguageConfig {
738    id: "kotlin",
739    extensions: &[".kt", ".kts"],
740    entity_node_types: &[
741        "function_declaration",
742        "class_declaration",
743        "object_declaration",
744        "property_declaration",
745        "companion_object",
746        "secondary_constructor",
747        "type_alias",
748    ],
749    container_node_types: &["class_body", "enum_class_body"],
750    call_entity_identifiers: &[],
751    suppressed_nested_entities: &[],
752    scope_boundary_types: &[],
753    get_language: get_kotlin,
754    scope_resolve: Some(&KOTLIN_SCOPE_CONFIG),
755};
756
757#[cfg(feature = "lang-xml")]
758static XML_CONFIG: LanguageConfig = LanguageConfig {
759    id: "xml",
760    extensions: &[".xml", ".plist", ".svg", ".xhtml", ".csproj", ".fsproj", ".vbproj", ".props", ".targets", ".nuspec", ".resx", ".xaml", ".axml"],
761    entity_node_types: &["element"],
762    container_node_types: &["content"],
763    call_entity_identifiers: &[],
764    suppressed_nested_entities: &[],
765    scope_boundary_types: &[],
766    get_language: get_xml,
767    scope_resolve: None,
768};
769
770#[cfg(feature = "lang-dart")]
771static DART_CONFIG: LanguageConfig = LanguageConfig {
772    id: "dart",
773    extensions: &[".dart"],
774    entity_node_types: &[
775        "class_declaration",
776        "mixin_declaration",
777        "extension_declaration",
778        "extension_type_declaration",
779        "enum_declaration",
780        "type_alias",
781        "class_member",
782        "function_signature",
783        "getter_signature",
784        "setter_signature",
785    ],
786    container_node_types: &["class_body", "enum_body", "extension_body"],
787    call_entity_identifiers: &[],
788    suppressed_nested_entities: &[],
789    scope_boundary_types: &[],
790    get_language: get_dart,
791    scope_resolve: Some(&DART_SCOPE_CONFIG),
792};
793  
794#[cfg(feature = "lang-perl")]
795static PERL_CONFIG: LanguageConfig = LanguageConfig {
796    id: "perl",
797    extensions: &[".pl", ".pm", ".t"],
798    entity_node_types: &[
799        "subroutine_declaration_statement",
800        "package_statement",
801    ],
802    container_node_types: &["block"],
803    call_entity_identifiers: &[],
804    suppressed_nested_entities: &[],
805    scope_boundary_types: &[],
806    get_language: get_perl,
807    scope_resolve: None,
808};
809
810#[cfg(feature = "lang-ocaml")]
811static OCAML_CONFIG: LanguageConfig = LanguageConfig {
812    id: "ocaml",
813    extensions: &[".ml"],
814    entity_node_types: &[
815        "value_definition",
816        "module_definition",
817        "module_type_definition",
818        "type_definition",
819        "exception_definition",
820        "class_definition",
821        "class_type_definition",
822        "external",
823    ],
824    container_node_types: &["structure", "module_binding"],
825    call_entity_identifiers: &[],
826    suppressed_nested_entities: &[],
827    scope_boundary_types: &[],
828    get_language: get_ocaml,
829    scope_resolve: None,
830};
831
832#[cfg(feature = "lang-ocaml")]
833static OCAML_INTERFACE_CONFIG: LanguageConfig = LanguageConfig {
834    id: "ocaml_interface",
835    extensions: &[".mli"],
836    entity_node_types: &[
837        "value_specification",
838        "module_definition",
839        "module_type_definition",
840        "type_definition",
841        "exception_definition",
842        "class_definition",
843        "class_type_definition",
844        "external",
845    ],
846    container_node_types: &["signature", "module_binding"],
847    call_entity_identifiers: &[],
848    suppressed_nested_entities: &[],
849    scope_boundary_types: &[],
850    get_language: get_ocaml_interface,
851    scope_resolve: None,
852};
853
854#[cfg(feature = "lang-scala")]
855static SCALA_CONFIG: LanguageConfig = LanguageConfig {
856    id: "scala",
857    extensions: &[".scala", ".sc", ".sbt", ".kojo", ".mill"],
858    entity_node_types: &[
859        "class_definition",
860        "object_definition",
861        "trait_definition",
862        "enum_definition",
863        "function_definition",
864        "function_declaration",
865        "val_definition",
866        "given_definition",
867        "extension_definition",
868        "type_definition",
869        "package_object",
870    ],
871    container_node_types: &["template_body", "enum_body", "with_template_body"],
872    call_entity_identifiers: &[],
873    suppressed_nested_entities: &[],
874    scope_boundary_types: &[],
875    get_language: get_scala,
876    scope_resolve: Some(&SCALA_SCOPE_CONFIG),
877};
878
879#[cfg(feature = "lang-zig")]
880static ZIG_CONFIG: LanguageConfig = LanguageConfig {
881    id: "zig",
882    extensions: &[".zig"],
883    entity_node_types: &[
884        "function_declaration",
885        "test_declaration",
886        "variable_declaration",
887    ],
888    container_node_types: &["block"],
889    call_entity_identifiers: &[],
890    suppressed_nested_entities: &[
891        SuppressedNestedEntity {
892            parent_entity_node_type: "function_declaration",
893            child_entity_node_type: "variable_declaration",
894        },
895    ],
896    scope_boundary_types: &[],
897    get_language: get_zig,
898    scope_resolve: Some(&ZIG_SCOPE_CONFIG),
899};
900
901#[cfg(feature = "lang-nix")]
902static NIX_CONFIG: LanguageConfig = LanguageConfig {
903    id: "nix",
904    extensions: &[".nix"],
905    entity_node_types: &["binding", "inherit", "inherit_from"],
906    container_node_types: &["binding_set"],
907    call_entity_identifiers: &[],
908    suppressed_nested_entities: &[],
909    scope_boundary_types: &[],
910    get_language: get_nix,
911    scope_resolve: None,
912};
913
914// ─── Scope Resolve Configs for Supported Languages ────────────────────────────
915
916static PYTHON_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
917    class_scope_nodes: &["class_definition"],
918    impl_scope_nodes: &[],
919    function_scope_nodes: &["function_definition"],
920    class_name_field: ClassNameField::Simple("name"),
921
922    assignment_rules: &[
923        AssignmentRule { node_kind: "assignment", strategy: AssignmentStrategy::LeftRight },
924        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
925    ],
926    assignment_recurse_into: &["block"],
927
928    param_rules: &[
929        ParamRule { node_kind: "typed_parameter", name_field: ParamNameField::WithFallback("name"), type_field: "type", skip_names: &["self", "cls"] },
930        ParamRule { node_kind: "typed_default_parameter", name_field: ParamNameField::WithFallback("name"), type_field: "type", skip_names: &["self", "cls"] },
931    ],
932
933    return_type_field: None,
934
935    call_nodes: &["call"],
936    call_style: CallNodeStyle::FunctionField("function"),
937    new_expr_nodes: &[],
938    new_expr_type_field: "constructor",
939    composite_literal_nodes: &[],
940    member_access: &[MemberAccess { node_kind: "attribute", object_field: "object", property_field: "attribute" }],
941    scoped_call_nodes: &[],
942
943    self_keywords: &["self", "cls"],
944
945    init_strategy: InitStrategy::ConstructorBody {
946        class_nodes: &["class_definition"],
947        init_names: &["__init__"],
948        init_node_kind: "function_definition",
949        self_keyword: "self",
950        access_kind: "attribute",
951        obj_field: "object",
952        prop_field: "attribute",
953    },
954
955    import_extractor: None, // set via import_rules
956    external_method: false,
957
958    builtins: &[
959        "print", "len", "range", "str", "int", "float", "bool",
960        "list", "dict", "set", "tuple", "type", "super",
961        "isinstance", "issubclass", "getattr", "setattr",
962        "hasattr", "delattr", "open", "input", "map",
963        "filter", "zip", "enumerate", "sorted", "reversed",
964        "min", "max", "sum", "any", "all", "abs",
965        "round", "format", "repr", "id", "hash",
966        "ValueError", "TypeError", "KeyError", "RuntimeError",
967        "Exception", "StopIteration",
968    ],
969};
970
971static TS_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
972    class_scope_nodes: &["class_declaration"],
973    impl_scope_nodes: &[],
974    function_scope_nodes: &["function_declaration", "method_definition"],
975    class_name_field: ClassNameField::Simple("name"),
976
977    assignment_rules: &[
978        AssignmentRule { node_kind: "lexical_declaration", strategy: AssignmentStrategy::Declarators },
979        AssignmentRule { node_kind: "variable_declaration", strategy: AssignmentStrategy::Declarators },
980        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
981    ],
982    assignment_recurse_into: &["statement_block"],
983
984    param_rules: &[
985        ParamRule { node_kind: "required_parameter", name_field: ParamNameField::WithFallback("pattern"), type_field: "type", skip_names: &["this"] },
986        ParamRule { node_kind: "optional_parameter", name_field: ParamNameField::WithFallback("pattern"), type_field: "type", skip_names: &["this"] },
987    ],
988
989    return_type_field: Some("return_type"),
990
991    call_nodes: &["call_expression"],
992    call_style: CallNodeStyle::FunctionField("function"),
993    new_expr_nodes: &["new_expression"],
994    new_expr_type_field: "constructor",
995    composite_literal_nodes: &[],
996    member_access: &[MemberAccess { node_kind: "member_expression", object_field: "object", property_field: "property" }],
997    scoped_call_nodes: &[],
998
999    self_keywords: &["this"],
1000
1001    init_strategy: InitStrategy::ConstructorBody {
1002        class_nodes: &["class_declaration"],
1003        init_names: &["constructor"],
1004        init_node_kind: "method_definition",
1005        self_keyword: "this",
1006        access_kind: "member_expression",
1007        obj_field: "object",
1008        prop_field: "property",
1009    },
1010
1011    import_extractor: None,
1012    external_method: false,
1013
1014    builtins: &[
1015        "console", "parseInt", "parseFloat", "isNaN", "isFinite",
1016        "setTimeout", "setInterval", "clearTimeout", "clearInterval",
1017        "Promise", "Array", "Object", "Map", "Set", "WeakMap", "WeakSet",
1018        "JSON", "Math", "Date", "RegExp", "Error", "TypeError",
1019        "RangeError", "Symbol", "Proxy", "Reflect",
1020        "String", "Number", "Boolean", "BigInt",
1021        "require", "module", "exports", "process",
1022        "Buffer", "global", "window", "document",
1023        "fetch", "Response", "Request", "Headers", "URL",
1024    ],
1025};
1026
1027static RUST_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1028    class_scope_nodes: &["struct_item"],
1029    impl_scope_nodes: &["impl_item"],
1030    function_scope_nodes: &["function_item"],
1031    class_name_field: ClassNameField::Simple("name"),
1032
1033    assignment_rules: &[
1034        AssignmentRule { node_kind: "let_declaration", strategy: AssignmentStrategy::PatternBased },
1035    ],
1036    assignment_recurse_into: &["block", "expression_statement"],
1037
1038    param_rules: &[
1039        ParamRule { node_kind: "parameter", name_field: ParamNameField::RustPattern, type_field: "type", skip_names: &["self"] },
1040    ],
1041
1042    return_type_field: Some("return_type"),
1043
1044    call_nodes: &["call_expression"],
1045    call_style: CallNodeStyle::FunctionField("function"),
1046    new_expr_nodes: &[],
1047    new_expr_type_field: "constructor",
1048    composite_literal_nodes: &[],
1049    member_access: &[MemberAccess { node_kind: "field_expression", object_field: "value", property_field: "field" }],
1050    scoped_call_nodes: &["scoped_identifier"],
1051
1052    self_keywords: &["self"],
1053
1054    init_strategy: InitStrategy::StructFields {
1055        struct_nodes: &["struct_item"],
1056    },
1057
1058    import_extractor: None,
1059    external_method: false,
1060
1061    builtins: &[
1062        "println", "eprintln", "print", "eprint", "dbg",
1063        "format", "write", "writeln",
1064        "vec", "panic", "todo", "unimplemented", "unreachable",
1065        "assert", "assert_eq", "assert_ne", "debug_assert",
1066        "Some", "None", "Ok", "Err",
1067        "Box", "Vec", "String", "HashMap", "HashSet",
1068        "Arc", "Rc", "Mutex", "RwLock", "Cell", "RefCell",
1069        "Option", "Result", "Iterator", "IntoIterator",
1070        "Clone", "Copy", "Debug", "Display", "Default",
1071        "From", "Into", "TryFrom", "TryInto",
1072        "Send", "Sync", "Sized", "Unpin",
1073        "cfg", "derive", "include", "env",
1074    ],
1075};
1076
1077static GO_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1078    class_scope_nodes: &["type_declaration"],
1079    impl_scope_nodes: &[],
1080    function_scope_nodes: &["function_declaration", "method_declaration"],
1081    class_name_field: ClassNameField::TypeSpec { spec_kind: "type_spec", field: "name" },
1082
1083    assignment_rules: &[
1084        AssignmentRule { node_kind: "short_var_declaration", strategy: AssignmentStrategy::ShortVar },
1085        AssignmentRule { node_kind: "var_declaration", strategy: AssignmentStrategy::VarSpec },
1086    ],
1087    assignment_recurse_into: &["block"],
1088
1089    param_rules: &[
1090        ParamRule { node_kind: "parameter_declaration", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1091    ],
1092
1093    return_type_field: Some("result"),
1094
1095    call_nodes: &["call_expression"],
1096    call_style: CallNodeStyle::FunctionField("function"),
1097    new_expr_nodes: &[],
1098    new_expr_type_field: "constructor",
1099    composite_literal_nodes: &["composite_literal"],
1100    member_access: &[MemberAccess { node_kind: "selector_expression", object_field: "operand", property_field: "field" }],
1101    scoped_call_nodes: &[],
1102
1103    self_keywords: &[],
1104
1105    init_strategy: InitStrategy::StructFields {
1106        struct_nodes: &["type_declaration"],
1107    },
1108
1109    import_extractor: None,
1110    external_method: true,
1111
1112    builtins: &[
1113        "fmt", "log", "os", "io", "strings", "strconv", "bytes",
1114        "make", "len", "cap", "append", "copy", "delete", "close",
1115        "panic", "recover", "new", "print", "println",
1116        "error", "string", "int", "int8", "int16", "int32", "int64",
1117        "uint", "uint8", "uint16", "uint32", "uint64",
1118        "float32", "float64", "complex64", "complex128",
1119        "bool", "byte", "rune", "uintptr",
1120        "Println", "Printf", "Sprintf", "Fprintf", "Errorf",
1121    ],
1122};
1123
1124// ─── Tier 1 Scope Resolve Configs ─────────────────────────────────────────────
1125
1126static JAVA_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1127    class_scope_nodes: &["class_declaration", "interface_declaration", "enum_declaration"],
1128    impl_scope_nodes: &[],
1129    function_scope_nodes: &["method_declaration", "constructor_declaration"],
1130    class_name_field: ClassNameField::Simple("name"),
1131
1132    assignment_rules: &[
1133        AssignmentRule { node_kind: "local_variable_declaration", strategy: AssignmentStrategy::Declarators },
1134        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1135    ],
1136    assignment_recurse_into: &["block"],
1137
1138    param_rules: &[
1139        ParamRule { node_kind: "formal_parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1140    ],
1141
1142    return_type_field: Some("type"),
1143
1144    call_nodes: &["method_invocation"],
1145    call_style: CallNodeStyle::DirectMethod { object_field: "object", method_field: "name" },
1146    new_expr_nodes: &["object_creation_expression"],
1147    new_expr_type_field: "type",
1148    composite_literal_nodes: &[],
1149    member_access: &[MemberAccess { node_kind: "method_invocation", object_field: "object", property_field: "name" }],
1150    scoped_call_nodes: &[],
1151
1152    self_keywords: &["this"],
1153
1154    init_strategy: InitStrategy::None,
1155    import_extractor: None,
1156    external_method: false,
1157
1158    builtins: &[
1159        "System", "String", "Integer", "Long", "Double", "Float", "Boolean",
1160        "Object", "Class", "Math", "Collections", "Arrays", "List", "Map", "Set",
1161        "ArrayList", "HashMap", "HashSet", "Optional", "Stream",
1162        "Exception", "RuntimeException", "NullPointerException",
1163        "println", "printf", "format",
1164    ],
1165};
1166
1167static CSHARP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1168    class_scope_nodes: &["class_declaration", "interface_declaration", "struct_declaration", "enum_declaration"],
1169    impl_scope_nodes: &[],
1170    function_scope_nodes: &["method_declaration", "constructor_declaration"],
1171    class_name_field: ClassNameField::Simple("name"),
1172
1173    assignment_rules: &[
1174        AssignmentRule { node_kind: "local_declaration_statement", strategy: AssignmentStrategy::Declarators },
1175        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1176    ],
1177    assignment_recurse_into: &["block"],
1178
1179    param_rules: &[
1180        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1181    ],
1182
1183    return_type_field: Some("type"),
1184
1185    call_nodes: &["invocation_expression"],
1186    call_style: CallNodeStyle::FunctionField("function"),
1187    new_expr_nodes: &["object_creation_expression"],
1188    new_expr_type_field: "type",
1189    composite_literal_nodes: &[],
1190    member_access: &[MemberAccess { node_kind: "member_access_expression", object_field: "expression", property_field: "name" }],
1191    scoped_call_nodes: &[],
1192
1193    self_keywords: &["this"],
1194
1195    init_strategy: InitStrategy::None,
1196    import_extractor: None,
1197    external_method: false,
1198
1199    builtins: &[
1200        "Console", "String", "Int32", "Int64", "Double", "Boolean",
1201        "Object", "Math", "List", "Dictionary", "HashSet",
1202        "Task", "Async", "Exception", "ArgumentException",
1203        "WriteLine", "ReadLine", "ToString", "Equals",
1204    ],
1205};
1206
1207static CPP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1208    class_scope_nodes: &["class_specifier", "struct_specifier"],
1209    impl_scope_nodes: &[],
1210    function_scope_nodes: &["function_definition"],
1211    class_name_field: ClassNameField::Simple("name"),
1212
1213    assignment_rules: &[
1214        AssignmentRule { node_kind: "declaration", strategy: AssignmentStrategy::Declarators },
1215        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1216    ],
1217    assignment_recurse_into: &["compound_statement"],
1218
1219    param_rules: &[
1220        ParamRule { node_kind: "parameter_declaration", name_field: ParamNameField::Simple("declarator"), type_field: "type", skip_names: &[] },
1221    ],
1222
1223    return_type_field: Some("type"),
1224
1225    call_nodes: &["call_expression"],
1226    call_style: CallNodeStyle::FunctionField("function"),
1227    new_expr_nodes: &["new_expression"],
1228    new_expr_type_field: "type",
1229    composite_literal_nodes: &[],
1230    member_access: &[
1231        MemberAccess { node_kind: "field_expression", object_field: "argument", property_field: "field" },
1232    ],
1233    scoped_call_nodes: &["qualified_identifier"],
1234
1235    self_keywords: &["this"],
1236
1237    init_strategy: InitStrategy::StructFields {
1238        struct_nodes: &["class_specifier", "struct_specifier"],
1239    },
1240    import_extractor: None,
1241    external_method: false,
1242
1243    builtins: &[
1244        "std", "cout", "cin", "endl", "printf", "scanf", "malloc", "free",
1245        "string", "vector", "map", "set", "pair", "make_pair",
1246        "shared_ptr", "unique_ptr", "make_shared", "make_unique",
1247        "nullptr", "size_t", "int", "char", "double", "float", "bool",
1248    ],
1249};
1250
1251static RUBY_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1252    class_scope_nodes: &["class", "module"],
1253    impl_scope_nodes: &[],
1254    function_scope_nodes: &["method", "singleton_method"],
1255    class_name_field: ClassNameField::Simple("name"),
1256
1257    assignment_rules: &[
1258        AssignmentRule { node_kind: "assignment", strategy: AssignmentStrategy::LeftRight },
1259    ],
1260    assignment_recurse_into: &["body_statement"],
1261
1262    param_rules: &[],
1263
1264    return_type_field: None,
1265
1266    call_nodes: &["call"],
1267    call_style: CallNodeStyle::DirectMethod { object_field: "receiver", method_field: "method" },
1268    new_expr_nodes: &[],
1269    new_expr_type_field: "constructor",
1270    composite_literal_nodes: &[],
1271    member_access: &[MemberAccess { node_kind: "call", object_field: "receiver", property_field: "method" }],
1272    scoped_call_nodes: &["scope_resolution"],
1273
1274    self_keywords: &["self"],
1275
1276    init_strategy: InitStrategy::None,
1277    import_extractor: None,
1278    external_method: false,
1279
1280    builtins: &[
1281        "puts", "print", "p", "require", "require_relative", "include", "extend",
1282        "attr_accessor", "attr_reader", "attr_writer",
1283        "raise", "rescue", "yield", "block_given?",
1284        "Array", "Hash", "String", "Integer", "Float", "Symbol",
1285        "nil", "true", "false",
1286    ],
1287};
1288
1289static KOTLIN_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1290    class_scope_nodes: &["class_declaration", "object_declaration"],
1291    impl_scope_nodes: &[],
1292    function_scope_nodes: &["function_declaration", "secondary_constructor"],
1293    class_name_field: ClassNameField::Simple("name"),
1294
1295    assignment_rules: &[
1296        AssignmentRule { node_kind: "property_declaration", strategy: AssignmentStrategy::Declarators },
1297    ],
1298    assignment_recurse_into: &["statements"],
1299
1300    param_rules: &[
1301        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1302    ],
1303
1304    return_type_field: Some("type"),
1305
1306    call_nodes: &["call_expression"],
1307    call_style: CallNodeStyle::FunctionField("function"),
1308    new_expr_nodes: &[],
1309    new_expr_type_field: "constructor",
1310    composite_literal_nodes: &[],
1311    member_access: &[MemberAccess { node_kind: "navigation_expression", object_field: "expression", property_field: "navigation_suffix" }],
1312    scoped_call_nodes: &[],
1313
1314    self_keywords: &["this"],
1315
1316    init_strategy: InitStrategy::None,
1317    import_extractor: None,
1318    external_method: false,
1319
1320    builtins: &[
1321        "println", "print", "listOf", "mapOf", "setOf", "arrayOf",
1322        "mutableListOf", "mutableMapOf", "mutableSetOf",
1323        "String", "Int", "Long", "Double", "Float", "Boolean",
1324        "Any", "Unit", "Nothing", "Pair", "Triple",
1325        "require", "check", "error", "TODO",
1326    ],
1327};
1328
1329static PHP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1330    class_scope_nodes: &["class_declaration", "interface_declaration", "trait_declaration"],
1331    impl_scope_nodes: &[],
1332    function_scope_nodes: &["function_definition", "method_declaration"],
1333    class_name_field: ClassNameField::Simple("name"),
1334
1335    assignment_rules: &[
1336        AssignmentRule { node_kind: "expression_statement", strategy: AssignmentStrategy::LeftRight },
1337    ],
1338    assignment_recurse_into: &["compound_statement"],
1339
1340    param_rules: &[
1341        ParamRule { node_kind: "simple_parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1342    ],
1343
1344    return_type_field: Some("return_type"),
1345
1346    call_nodes: &["function_call_expression", "member_call_expression"],
1347    call_style: CallNodeStyle::FunctionField("function"),
1348    new_expr_nodes: &["object_creation_expression"],
1349    new_expr_type_field: "type",
1350    composite_literal_nodes: &[],
1351    member_access: &[MemberAccess { node_kind: "member_call_expression", object_field: "object", property_field: "name" }],
1352    scoped_call_nodes: &["scoped_call_expression"],
1353
1354    self_keywords: &["$this"],
1355
1356    init_strategy: InitStrategy::None,
1357    import_extractor: None,
1358    external_method: false,
1359
1360    builtins: &[
1361        "echo", "print", "var_dump", "print_r", "isset", "unset", "empty",
1362        "array", "count", "strlen", "substr", "strpos",
1363        "is_null", "is_array", "is_string", "is_int",
1364        "Exception", "RuntimeException", "InvalidArgumentException",
1365    ],
1366};
1367
1368static SWIFT_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1369    class_scope_nodes: &["class_declaration", "protocol_declaration"],
1370    impl_scope_nodes: &[],
1371    function_scope_nodes: &["function_declaration", "init_declaration"],
1372    class_name_field: ClassNameField::Simple("name"),
1373
1374    assignment_rules: &[
1375        AssignmentRule { node_kind: "property_declaration", strategy: AssignmentStrategy::Declarators },
1376    ],
1377    assignment_recurse_into: &["function_body"],
1378
1379    param_rules: &[
1380        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1381    ],
1382
1383    return_type_field: Some("return_type"),
1384
1385    call_nodes: &["call_expression"],
1386    call_style: CallNodeStyle::FunctionField("function"),
1387    new_expr_nodes: &[],
1388    new_expr_type_field: "constructor",
1389    composite_literal_nodes: &[],
1390    member_access: &[MemberAccess { node_kind: "navigation_expression", object_field: "target", property_field: "suffix" }],
1391    scoped_call_nodes: &[],
1392
1393    self_keywords: &["self"],
1394
1395    init_strategy: InitStrategy::None,
1396    import_extractor: None,
1397    external_method: false,
1398
1399    builtins: &[
1400        "print", "debugPrint", "fatalError", "precondition", "assert",
1401        "String", "Int", "Double", "Float", "Bool", "Array", "Dictionary", "Set",
1402        "Optional", "Result", "Error", "NSError",
1403    ],
1404};
1405
1406static SCALA_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1407    class_scope_nodes: &["class_definition", "object_definition", "trait_definition"],
1408    impl_scope_nodes: &[],
1409    function_scope_nodes: &["function_definition", "function_declaration"],
1410    class_name_field: ClassNameField::Simple("name"),
1411
1412    assignment_rules: &[
1413        AssignmentRule { node_kind: "val_definition", strategy: AssignmentStrategy::Declarators },
1414    ],
1415    assignment_recurse_into: &["template_body"],
1416
1417    param_rules: &[
1418        ParamRule { node_kind: "parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1419    ],
1420
1421    return_type_field: Some("return_type"),
1422
1423    call_nodes: &["call_expression"],
1424    call_style: CallNodeStyle::FunctionField("function"),
1425    new_expr_nodes: &[],
1426    new_expr_type_field: "constructor",
1427    composite_literal_nodes: &[],
1428    member_access: &[MemberAccess { node_kind: "field_expression", object_field: "value", property_field: "field" }],
1429    scoped_call_nodes: &[],
1430
1431    self_keywords: &["this"],
1432
1433    init_strategy: InitStrategy::None,
1434    import_extractor: None,
1435    external_method: false,
1436
1437    builtins: &[
1438        "println", "print", "require", "assert",
1439        "String", "Int", "Long", "Double", "Float", "Boolean",
1440        "List", "Map", "Set", "Seq", "Vector", "Option", "Some", "None",
1441        "Future", "Try", "Either", "Left", "Right",
1442    ],
1443};
1444
1445// ─── Tier 2 Scope Resolve Configs (Minimal) ───────────────────────────────────
1446
1447static DART_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1448    class_scope_nodes: &["class_declaration", "mixin_declaration", "enum_declaration"],
1449    impl_scope_nodes: &[],
1450    function_scope_nodes: &["function_signature", "method_signature"],
1451    class_name_field: ClassNameField::Simple("name"),
1452
1453    assignment_rules: &[],
1454    assignment_recurse_into: &[],
1455
1456    param_rules: &[
1457        ParamRule { node_kind: "formal_parameter", name_field: ParamNameField::Simple("name"), type_field: "type", skip_names: &[] },
1458    ],
1459
1460    return_type_field: None,
1461
1462    call_nodes: &["function_expression_body"],
1463    call_style: CallNodeStyle::FunctionField("function"),
1464    new_expr_nodes: &[],
1465    new_expr_type_field: "constructor",
1466    composite_literal_nodes: &[],
1467    member_access: &[],
1468    scoped_call_nodes: &[],
1469
1470    self_keywords: &["this"],
1471
1472    init_strategy: InitStrategy::None,
1473    import_extractor: None,
1474    external_method: false,
1475
1476    builtins: &[
1477        "print", "debugPrint", "String", "int", "double", "bool",
1478        "List", "Map", "Set", "Future", "Stream",
1479    ],
1480};
1481
1482static ZIG_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1483    class_scope_nodes: &[],
1484    impl_scope_nodes: &[],
1485    function_scope_nodes: &["function_declaration", "test_declaration"],
1486    class_name_field: ClassNameField::Simple("name"),
1487
1488    assignment_rules: &[],
1489    assignment_recurse_into: &[],
1490
1491    param_rules: &[],
1492
1493    return_type_field: None,
1494
1495    call_nodes: &["call_expression"],
1496    call_style: CallNodeStyle::FunctionField("function"),
1497    new_expr_nodes: &[],
1498    new_expr_type_field: "constructor",
1499    composite_literal_nodes: &[],
1500    member_access: &[MemberAccess { node_kind: "field_expression", object_field: "object", property_field: "field" }],
1501    scoped_call_nodes: &[],
1502
1503    self_keywords: &[],
1504
1505    init_strategy: InitStrategy::None,
1506    import_extractor: None,
1507    external_method: false,
1508
1509    builtins: &[
1510        "std", "print", "debug", "assert", "expect",
1511        "allocator", "mem", "testing",
1512    ],
1513};
1514
1515static BASH_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1516    class_scope_nodes: &[],
1517    impl_scope_nodes: &[],
1518    function_scope_nodes: &["function_definition"],
1519    class_name_field: ClassNameField::Simple("name"),
1520
1521    assignment_rules: &[],
1522    assignment_recurse_into: &[],
1523
1524    param_rules: &[],
1525
1526    return_type_field: None,
1527
1528    call_nodes: &["command"],
1529    call_style: CallNodeStyle::FunctionField("name"),
1530    new_expr_nodes: &[],
1531    new_expr_type_field: "constructor",
1532    composite_literal_nodes: &[],
1533    member_access: &[],
1534    scoped_call_nodes: &[],
1535
1536    self_keywords: &[],
1537
1538    init_strategy: InitStrategy::None,
1539    import_extractor: None,
1540    external_method: false,
1541
1542    builtins: &[
1543        "echo", "printf", "cd", "ls", "cat", "grep", "sed", "awk",
1544        "if", "then", "else", "fi", "for", "while", "do", "done",
1545        "exit", "return", "export", "source", "eval",
1546    ],
1547};
1548
1549macro_rules! all_configs {
1550    () => {{
1551        &[
1552            #[cfg(feature = "lang-typescript")]
1553            &TYPESCRIPT_CONFIG,
1554            #[cfg(feature = "lang-typescript")]
1555            &TSX_CONFIG,
1556            #[cfg(feature = "lang-javascript")]
1557            &JAVASCRIPT_CONFIG,
1558            #[cfg(feature = "lang-python")]
1559            &PYTHON_CONFIG,
1560            #[cfg(feature = "lang-go")]
1561            &GO_CONFIG,
1562            #[cfg(feature = "lang-rust")]
1563            &RUST_CONFIG,
1564            #[cfg(feature = "lang-java")]
1565            &JAVA_CONFIG,
1566            #[cfg(feature = "lang-c")]
1567            &C_CONFIG,
1568            #[cfg(feature = "lang-cpp")]
1569            &CPP_CONFIG,
1570            #[cfg(feature = "lang-ruby")]
1571            &RUBY_CONFIG,
1572            #[cfg(feature = "lang-csharp")]
1573            &CSHARP_CONFIG,
1574            #[cfg(feature = "lang-php")]
1575            &PHP_CONFIG,
1576            #[cfg(feature = "lang-fortran")]
1577            &FORTRAN_CONFIG,
1578            #[cfg(feature = "lang-swift")]
1579            &SWIFT_CONFIG,
1580            #[cfg(feature = "lang-elixir")]
1581            &ELIXIR_CONFIG,
1582            #[cfg(feature = "lang-bash")]
1583            &BASH_CONFIG,
1584            #[cfg(feature = "lang-hcl")]
1585            &HCL_CONFIG,
1586            #[cfg(feature = "lang-kotlin")]
1587            &KOTLIN_CONFIG,
1588            #[cfg(feature = "lang-xml")]
1589            &XML_CONFIG,
1590            #[cfg(feature = "lang-dart")]
1591            &DART_CONFIG,
1592            #[cfg(feature = "lang-perl")]
1593            &PERL_CONFIG,
1594            #[cfg(feature = "lang-ocaml")]
1595            &OCAML_CONFIG,
1596            #[cfg(feature = "lang-ocaml")]
1597            &OCAML_INTERFACE_CONFIG,
1598            #[cfg(feature = "lang-scala")]
1599            &SCALA_CONFIG,
1600            #[cfg(feature = "lang-zig")]
1601            &ZIG_CONFIG,
1602            #[cfg(feature = "lang-nix")]
1603            &NIX_CONFIG,
1604        ]
1605    }};
1606}
1607
1608static ALL_CONFIGS: &[&LanguageConfig] = all_configs!();
1609
1610pub fn get_language_config(extension: &str) -> Option<&'static LanguageConfig> {
1611    ALL_CONFIGS
1612        .iter()
1613        .find(|c| c.extensions.contains(&extension))
1614        .copied()
1615}
1616
1617pub fn get_all_code_extensions() -> &'static [&'static str] {
1618    // Derived from ALL_CONFIGS to avoid duplication drift.
1619    // When you add an extension to a LanguageConfig, it's automatically included here.
1620    static EXTENSIONS: std::sync::LazyLock<Vec<&'static str>> = std::sync::LazyLock::new(|| {
1621        ALL_CONFIGS.iter().flat_map(|c| c.extensions.iter().copied()).collect()
1622    });
1623    &EXTENSIONS
1624}