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