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/// Strategy for stripping comments and string literals from source content.
13/// Controls which stripping function `strip_for_language` dispatches to in graph.rs.
14/// Add a new variant here when a language requires custom comment handling.
15#[derive(Copy, Clone, Debug, PartialEq)]
16pub enum StripStrategy {
17    /// Standard stripper: handles `//`, `/* */`, and `#` line comments, plus string literals.
18    Generic,
19    /// Clojure: blank double-quoted strings only (preserves `#` for gensyms and reader macros),
20    /// then strip `;` line comments in a second pass.
21    Clojure,
22}
23
24#[allow(dead_code)]
25pub struct LanguageConfig {
26    pub id: &'static str,
27    pub extensions: &'static [&'static str],
28    pub entity_node_types: &'static [&'static str],
29    pub container_node_types: &'static [&'static str],
30    pub call_entity_identifiers: &'static [&'static str],
31    /// Extra characters (beyond alphanumeric and `_`) that are valid identifier
32    /// constituents for this language. Used by the tokenizer and reference scanner.
33    /// E.g. Clojure uses `['-', '?', '!', '*', '=']` for kebab-case, predicates,
34    /// bang functions, dynamic vars, and equality operators.
35    pub extra_ident_chars: &'static [char],
36    /// How to strip comments and string literals from content for this language.
37    pub strip_strategy: StripStrategy,
38    /// Whether this language uses `alias/name` qualified references (e.g. Clojure).
39    /// When true, `resolve_entity_references` runs a post-processing pass to resolve
40    /// these qualified calls via the import table.
41    pub has_slash_qualified_refs: bool,
42    /// When true, a top-level `map_lit` node is broken into individual named entities,
43    /// one per keyword key–value pair. Used for EDN data files (deps.edn, etc.) where
44    /// the meaningful units are top-level map entries, not code definition forms.
45    pub extract_map_entries: bool,
46    pub suppressed_nested_entities: &'static [SuppressedNestedEntity],
47    /// Node types that introduce a new scope. The general (non-container) recursion
48    /// in visit_node will not descend into these nodes, preventing local variables
49    /// inside function bodies from being extracted as top-level entities.
50    pub scope_boundary_types: &'static [&'static str],
51    pub get_language: fn() -> Option<Language>,
52    pub scope_resolve: Option<&'static ScopeResolveConfig>,
53}
54
55// ─── Scope Resolve Config Types ───────────────────────────────────────────────
56
57/// Configuration for scope-aware reference resolution.
58/// Captures the AST node names and strategies that differ per language.
59pub struct ScopeResolveConfig {
60    /// AST node types that create class/struct scopes
61    pub class_scope_nodes: &'static [&'static str],
62    /// AST node types that create impl scopes (Rust impl_item, Swift extension)
63    pub impl_scope_nodes: &'static [&'static str],
64    /// AST node types that create function/method scopes
65    pub function_scope_nodes: &'static [&'static str],
66    /// How to extract the class name from a class scope node
67    pub class_name_field: ClassNameField,
68
69    /// Rules for scanning variable assignments to track types
70    pub assignment_rules: &'static [AssignmentRule],
71    /// Node types to recurse into when scanning assignments
72    pub assignment_recurse_into: &'static [&'static str],
73
74    /// Rules for extracting typed parameters from function signatures
75    pub param_rules: &'static [ParamRule],
76
77    /// Field name for return type annotation on function nodes (None = body heuristic only)
78    pub return_type_field: Option<&'static str>,
79
80    /// AST node types that represent function/method calls
81    pub call_nodes: &'static [&'static str],
82    /// How call nodes expose the callee. FunctionField = node has a "function" field containing
83    /// an identifier or member_expression. DirectMethod = node has object+name fields directly.
84    pub call_style: CallNodeStyle,
85    /// AST node types for `new Foo()` expressions
86    pub new_expr_nodes: &'static [&'static str],
87    /// Field name on new-expression nodes that holds the type/constructor name.
88    pub new_expr_type_field: &'static str,
89    /// AST node types for struct/composite literals (Go `Foo{}`)
90    pub composite_literal_nodes: &'static [&'static str],
91    /// How member access / method calls are represented in the AST
92    pub member_access: &'static [MemberAccess],
93    /// Scoped identifier nodes (Rust `Type::method`)
94    pub scoped_call_nodes: &'static [&'static str],
95
96    /// Self/this keywords to recognize
97    pub self_keywords: &'static [&'static str],
98
99    /// Strategy for extracting instance attribute types
100    pub init_strategy: InitStrategy,
101
102    /// Import extraction function (the only truly per-language piece)
103    pub import_extractor: Option<ImportExtractorFn>,
104
105    /// Whether methods are declared externally with receiver types (Go-style)
106    pub external_method: bool,
107
108    /// Language builtins to skip during resolution
109    pub builtins: &'static [&'static str],
110}
111
112/// How call nodes expose the callee/function.
113pub enum CallNodeStyle {
114    /// The call node has a field (e.g. "function") containing either an identifier
115    /// (bare call) or a member_expression (method call). Python, TS, Rust, Go, C#, C++.
116    FunctionField(&'static str),
117    /// The call node directly has object (optional) + method name fields.
118    /// Java: method_invocation(object, name). Ruby: call(receiver, method).
119    DirectMethod {
120        object_field: &'static str,
121        method_field: &'static str,
122    },
123    /// The callee is the first named child of the call node (no field name).
124    /// Swift: call_expression(simple_identifier|navigation_expression, call_suffix)
125    /// Kotlin: call_expression(identifier|navigation_expression, value_arguments)
126    FirstChild,
127}
128
129/// How to extract the class/struct name from a scope node.
130pub enum ClassNameField {
131    /// Simple field lookup: `node.child_by_field_name(field)`
132    Simple(&'static str),
133    /// Go-style: look for a child of type `spec_kind`, then get field `field` from it
134    TypeSpec {
135        spec_kind: &'static str,
136        field: &'static str,
137    },
138    /// Rust impl: get name from `node.child_by_field_name(field)` (the "type" field)
139    ImplType(&'static str),
140}
141
142/// A rule for scanning assignment nodes to extract type bindings.
143pub struct AssignmentRule {
144    pub node_kind: &'static str,
145    pub strategy: AssignmentStrategy,
146}
147
148/// Strategy for extracting variable name and type from an assignment node.
149pub enum AssignmentStrategy {
150    /// Python/TS: `x = Foo()` - left/right fields on assignment node
151    LeftRight,
152    /// TS: `const x = new Foo()` - variable_declarator children
153    Declarators,
154    /// Rust: `let x: Type = value` - pattern + type + value fields
155    PatternBased,
156    /// Go: `x := Foo{}` - expression_list left/right
157    ShortVar,
158    /// Go: `var x Type = ...` - var_spec children
159    VarSpec,
160}
161
162/// A rule for extracting typed parameters from function signatures.
163pub struct ParamRule {
164    pub node_kind: &'static str,
165    pub name_field: ParamNameField,
166    pub type_field: &'static str,
167    pub skip_names: &'static [&'static str],
168}
169
170/// How to extract the parameter name.
171pub enum ParamNameField {
172    /// Simple field name: `child_by_field_name(field)`
173    Simple(&'static str),
174    /// Field with fallback to first named child if identifier
175    WithFallback(&'static str),
176    /// Rust pattern matching (identifier, mut_pattern, reference_pattern)
177    RustPattern,
178}
179
180/// How member access (obj.field / obj.method()) is represented in the AST.
181pub struct MemberAccess {
182    pub node_kind: &'static str,
183    pub object_field: &'static str,
184    pub property_field: &'static str,
185}
186
187/// Strategy for extracting instance attribute types from class definitions.
188pub enum InitStrategy {
189    /// Python/TS: scan constructor body for self.attr = param patterns
190    ConstructorBody {
191        class_nodes: &'static [&'static str],
192        init_names: &'static [&'static str],
193        init_node_kind: &'static str,
194        self_keyword: &'static str,
195        access_kind: &'static str,
196        obj_field: &'static str,
197        prop_field: &'static str,
198    },
199    /// Rust/Go: extract field types directly from struct declarations
200    StructFields {
201        struct_nodes: &'static [&'static str],
202    },
203    /// No instance attribute tracking
204    None,
205}
206
207/// Function pointer type for import extraction.
208pub type ImportExtractorFn = fn(
209    node: tree_sitter::Node,
210    file_path: &str,
211    source: &[u8],
212    symbol_table: &HashMap<String, Vec<String>>,
213    entity_map: &HashMap<String, EntityInfo>,
214    import_table: &mut HashMap<(String, String), String>,
215    scopes: &mut Vec<crate::parser::scope_resolve::Scope>,
216);
217
218/// Import node kind + extractor function pair
219pub struct ImportRule {
220    pub node_kind: &'static str,
221    pub extractor: ImportExtractorFn,
222}
223
224#[cfg(feature = "lang-typescript")]
225fn get_typescript() -> Option<Language> {
226    Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into())
227}
228
229#[cfg(feature = "lang-typescript")]
230fn get_tsx() -> Option<Language> {
231    Some(tree_sitter_typescript::LANGUAGE_TSX.into())
232}
233
234#[cfg(feature = "lang-javascript")]
235fn get_javascript() -> Option<Language> {
236    Some(tree_sitter_javascript::LANGUAGE.into())
237}
238
239#[cfg(feature = "lang-python")]
240fn get_python() -> Option<Language> {
241    Some(tree_sitter_python::LANGUAGE.into())
242}
243
244#[cfg(feature = "lang-go")]
245fn get_go() -> Option<Language> {
246    Some(tree_sitter_go::LANGUAGE.into())
247}
248
249#[cfg(feature = "lang-rust")]
250fn get_rust() -> Option<Language> {
251    Some(tree_sitter_rust::LANGUAGE.into())
252}
253
254#[cfg(feature = "lang-java")]
255fn get_java() -> Option<Language> {
256    Some(tree_sitter_java::LANGUAGE.into())
257}
258
259#[cfg(feature = "lang-c")]
260fn get_c() -> Option<Language> {
261    Some(tree_sitter_c::LANGUAGE.into())
262}
263
264#[cfg(feature = "lang-cpp")]
265fn get_cpp() -> Option<Language> {
266    Some(tree_sitter_cpp::LANGUAGE.into())
267}
268
269#[cfg(feature = "lang-ruby")]
270fn get_ruby() -> Option<Language> {
271    Some(tree_sitter_ruby::LANGUAGE.into())
272}
273
274#[cfg(feature = "lang-csharp")]
275fn get_csharp() -> Option<Language> {
276    Some(tree_sitter_c_sharp::LANGUAGE.into())
277}
278
279#[cfg(feature = "lang-php")]
280fn get_php() -> Option<Language> {
281    Some(tree_sitter_php::LANGUAGE_PHP.into())
282}
283
284#[cfg(feature = "lang-fortran")]
285fn get_fortran() -> Option<Language> {
286    Some(tree_sitter_fortran::LANGUAGE.into())
287}
288
289#[cfg(feature = "lang-swift")]
290fn get_swift() -> Option<Language> {
291    Some(tree_sitter_swift::LANGUAGE.into())
292}
293
294#[cfg(feature = "lang-elixir")]
295fn get_elixir() -> Option<Language> {
296    Some(tree_sitter_elixir::LANGUAGE.into())
297}
298
299#[cfg(feature = "lang-bash")]
300fn get_bash() -> Option<Language> {
301    Some(tree_sitter_bash::LANGUAGE.into())
302}
303
304#[cfg(feature = "lang-hcl")]
305fn get_hcl() -> Option<Language> {
306    Some(tree_sitter_hcl::LANGUAGE.into())
307}
308
309#[cfg(feature = "lang-kotlin")]
310fn get_kotlin() -> Option<Language> {
311    Some(tree_sitter_kotlin_ng::LANGUAGE.into())
312}
313
314#[cfg(feature = "lang-xml")]
315fn get_xml() -> Option<Language> {
316    Some(tree_sitter_xml::LANGUAGE_XML.into())
317}
318
319#[cfg(feature = "lang-dart")]
320fn get_dart() -> Option<Language> {
321    Some(tree_sitter_dart::LANGUAGE.into())
322}
323
324#[cfg(feature = "lang-perl")]
325fn get_perl() -> Option<Language> {
326    Some(tree_sitter_perl_next::LANGUAGE.into())
327}
328
329#[cfg(feature = "lang-ocaml")]
330fn get_ocaml() -> Option<Language> {
331    Some(tree_sitter_ocaml::LANGUAGE_OCAML.into())
332}
333
334#[cfg(feature = "lang-ocaml")]
335fn get_ocaml_interface() -> Option<Language> {
336    Some(tree_sitter_ocaml::LANGUAGE_OCAML_INTERFACE.into())
337}
338
339#[cfg(feature = "lang-scala")]
340fn get_scala() -> Option<Language> {
341    Some(tree_sitter_scala::LANGUAGE.into())
342}
343
344#[cfg(feature = "lang-zig")]
345fn get_zig() -> Option<Language> {
346    Some(tree_sitter_zig::LANGUAGE.into())
347}
348
349#[cfg(feature = "lang-nix")]
350fn get_nix() -> Option<Language> {
351    Some(tree_sitter_nix::LANGUAGE.into())
352}
353
354#[cfg(feature = "lang-haskell")]
355fn get_haskell() -> Option<Language> {
356    Some(tree_sitter_haskell::LANGUAGE.into())
357}
358
359#[cfg(feature = "lang-elm")]
360fn get_elm() -> Option<Language> {
361    Some(tree_sitter_elm::LANGUAGE.into())
362}
363
364#[cfg(any(feature = "lang-clojure", feature = "lang-edn"))]
365fn get_clojure() -> Option<Language> {
366    Some(tree_sitter_clojure_orchard::LANGUAGE.into())
367}
368
369#[cfg(feature = "lang-d")]
370fn get_d() -> Option<Language> {
371    Some(tree_sitter_d::LANGUAGE.into())
372}
373
374/// Inside JS/TS function bodies, suppress variable declarations so that local
375/// variables are not extracted as nested entities. Inner function/class
376/// declarations are still extracted for diff granularity.
377const JS_TS_SUPPRESSED_NESTED: &[SuppressedNestedEntity] = &[
378    SuppressedNestedEntity {
379        parent_entity_node_type: "function_declaration",
380        child_entity_node_type: "lexical_declaration",
381    },
382    SuppressedNestedEntity {
383        parent_entity_node_type: "function_declaration",
384        child_entity_node_type: "variable_declaration",
385    },
386    SuppressedNestedEntity {
387        parent_entity_node_type: "generator_function_declaration",
388        child_entity_node_type: "lexical_declaration",
389    },
390    SuppressedNestedEntity {
391        parent_entity_node_type: "generator_function_declaration",
392        child_entity_node_type: "variable_declaration",
393    },
394    SuppressedNestedEntity {
395        parent_entity_node_type: "method_definition",
396        child_entity_node_type: "lexical_declaration",
397    },
398    SuppressedNestedEntity {
399        parent_entity_node_type: "method_definition",
400        child_entity_node_type: "variable_declaration",
401    },
402    // Scope boundaries: suppress local variables inside arrow functions,
403    // function expressions, and generator functions, while still allowing
404    // inner class/function declarations to be extracted.
405    SuppressedNestedEntity {
406        parent_entity_node_type: "arrow_function",
407        child_entity_node_type: "lexical_declaration",
408    },
409    SuppressedNestedEntity {
410        parent_entity_node_type: "arrow_function",
411        child_entity_node_type: "variable_declaration",
412    },
413    SuppressedNestedEntity {
414        parent_entity_node_type: "function_expression",
415        child_entity_node_type: "lexical_declaration",
416    },
417    SuppressedNestedEntity {
418        parent_entity_node_type: "function_expression",
419        child_entity_node_type: "variable_declaration",
420    },
421    SuppressedNestedEntity {
422        parent_entity_node_type: "generator_function",
423        child_entity_node_type: "lexical_declaration",
424    },
425    SuppressedNestedEntity {
426        parent_entity_node_type: "generator_function",
427        child_entity_node_type: "variable_declaration",
428    },
429];
430
431const JS_TS_SCOPE_BOUNDARIES: &[&str] = &[
432    "arrow_function",
433    "function_expression",
434    "generator_function",
435];
436
437/// Inside C function bodies, suppress `declaration` nodes so that block-local
438/// variables are not extracted as nested entities. Inner type declarations are
439/// still reached by traversal after the wrapper is skipped.
440const C_SUPPRESSED_NESTED: &[SuppressedNestedEntity] = &[SuppressedNestedEntity {
441    parent_entity_node_type: "function_definition",
442    child_entity_node_type: "declaration",
443}];
444
445/// Inside C++ function-like bodies, suppress `declaration` nodes so that
446/// block-local variables are not extracted as nested entities. Inner type
447/// declarations are still reached by traversal after the wrapper is skipped.
448const CPP_SUPPRESSED_NESTED: &[SuppressedNestedEntity] = &[
449    SuppressedNestedEntity {
450        parent_entity_node_type: "function_definition",
451        child_entity_node_type: "declaration",
452    },
453    SuppressedNestedEntity {
454        parent_entity_node_type: "lambda_expression",
455        child_entity_node_type: "declaration",
456    },
457];
458
459const CPP_SCOPE_BOUNDARIES: &[&str] = &["lambda_expression"];
460
461const SWIFT_SUPPRESSED_NESTED: &[SuppressedNestedEntity] = &[
462    SuppressedNestedEntity {
463        parent_entity_node_type: "function_declaration",
464        child_entity_node_type: "property_declaration",
465    },
466    SuppressedNestedEntity {
467        parent_entity_node_type: "init_declaration",
468        child_entity_node_type: "property_declaration",
469    },
470    SuppressedNestedEntity {
471        parent_entity_node_type: "deinit_declaration",
472        child_entity_node_type: "property_declaration",
473    },
474    SuppressedNestedEntity {
475        parent_entity_node_type: "subscript_declaration",
476        child_entity_node_type: "property_declaration",
477    },
478    SuppressedNestedEntity {
479        parent_entity_node_type: "property_declaration",
480        child_entity_node_type: "property_declaration",
481    },
482];
483
484#[cfg(feature = "lang-typescript")]
485static TYPESCRIPT_CONFIG: LanguageConfig = LanguageConfig {
486    id: "typescript",
487    extensions: &[".ts", ".mts", ".cts"],
488    entity_node_types: &[
489        "function_declaration",
490        "generator_function_declaration",
491        "function_signature",
492        "class_declaration",
493        "abstract_class_declaration",
494        "interface_declaration",
495        "type_alias_declaration",
496        "enum_declaration",
497        "internal_module",
498        "module",
499        "export_statement",
500        "lexical_declaration",
501        "variable_declaration",
502        "method_definition",
503        "abstract_method_signature",
504        "public_field_definition",
505        "function_signature",
506        "method_signature",
507        "property_signature",
508    ],
509    container_node_types: &[
510        "class_body",
511        "interface_body",
512        "enum_body",
513        "statement_block",
514    ],
515    call_entity_identifiers: &[],
516    extra_ident_chars: &[],
517    strip_strategy: StripStrategy::Generic,
518    has_slash_qualified_refs: false,
519    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
520    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
521    get_language: get_typescript,
522    extract_map_entries: false,
523    scope_resolve: Some(&TS_SCOPE_CONFIG),
524};
525
526#[cfg(feature = "lang-typescript")]
527static TSX_CONFIG: LanguageConfig = LanguageConfig {
528    id: "tsx",
529    extensions: &[".tsx"],
530    entity_node_types: &[
531        "function_declaration",
532        "generator_function_declaration",
533        "function_signature",
534        "class_declaration",
535        "abstract_class_declaration",
536        "interface_declaration",
537        "type_alias_declaration",
538        "enum_declaration",
539        "internal_module",
540        "module",
541        "export_statement",
542        "lexical_declaration",
543        "variable_declaration",
544        "method_definition",
545        "abstract_method_signature",
546        "public_field_definition",
547        "function_signature",
548        "method_signature",
549        "property_signature",
550    ],
551    container_node_types: &[
552        "class_body",
553        "interface_body",
554        "enum_body",
555        "statement_block",
556    ],
557    call_entity_identifiers: &[],
558    extra_ident_chars: &[],
559    strip_strategy: StripStrategy::Generic,
560    has_slash_qualified_refs: false,
561    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
562    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
563    get_language: get_tsx,
564    extract_map_entries: false,
565    scope_resolve: Some(&TS_SCOPE_CONFIG),
566};
567
568#[cfg(feature = "lang-javascript")]
569static JAVASCRIPT_CONFIG: LanguageConfig = LanguageConfig {
570    id: "javascript",
571    extensions: &[".js", ".jsx", ".mjs", ".cjs", ".es6"],
572    entity_node_types: &[
573        "function_declaration",
574        "generator_function_declaration",
575        "class_declaration",
576        "export_statement",
577        "lexical_declaration",
578        "variable_declaration",
579        "method_definition",
580        "field_definition",
581    ],
582    container_node_types: &["class_body", "statement_block"],
583    call_entity_identifiers: &[],
584    extra_ident_chars: &[],
585    strip_strategy: StripStrategy::Generic,
586    has_slash_qualified_refs: false,
587    suppressed_nested_entities: JS_TS_SUPPRESSED_NESTED,
588    scope_boundary_types: JS_TS_SCOPE_BOUNDARIES,
589    get_language: get_javascript,
590    extract_map_entries: false,
591    scope_resolve: Some(&TS_SCOPE_CONFIG),
592};
593
594#[cfg(feature = "lang-python")]
595static PYTHON_CONFIG: LanguageConfig = LanguageConfig {
596    id: "python",
597    extensions: &[".py", ".pyi"],
598    entity_node_types: &[
599        "function_definition",
600        "class_definition",
601        "decorated_definition",
602    ],
603    container_node_types: &["block"],
604    call_entity_identifiers: &[],
605    extra_ident_chars: &[],
606    strip_strategy: StripStrategy::Generic,
607    has_slash_qualified_refs: false,
608    suppressed_nested_entities: &[],
609    scope_boundary_types: &[],
610    get_language: get_python,
611    extract_map_entries: false,
612    scope_resolve: Some(&PYTHON_SCOPE_CONFIG),
613};
614
615#[cfg(feature = "lang-go")]
616static GO_CONFIG: LanguageConfig = LanguageConfig {
617    id: "go",
618    extensions: &[".go"],
619    entity_node_types: &[
620        "function_declaration",
621        "method_declaration",
622        "type_declaration",
623        "var_declaration",
624        "const_declaration",
625    ],
626    container_node_types: &["block"],
627    call_entity_identifiers: &[],
628    extra_ident_chars: &[],
629    strip_strategy: StripStrategy::Generic,
630    has_slash_qualified_refs: false,
631    suppressed_nested_entities: &[],
632    scope_boundary_types: &[],
633    get_language: get_go,
634    extract_map_entries: false,
635    scope_resolve: Some(&GO_SCOPE_CONFIG),
636};
637
638#[cfg(feature = "lang-rust")]
639static RUST_CONFIG: LanguageConfig = LanguageConfig {
640    id: "rust",
641    extensions: &[".rs"],
642    entity_node_types: &[
643        "function_item",
644        "struct_item",
645        "enum_item",
646        "impl_item",
647        "trait_item",
648        "mod_item",
649        "const_item",
650        "static_item",
651        "type_item",
652        "macro_definition",
653    ],
654    container_node_types: &["declaration_list", "block"],
655    call_entity_identifiers: &[],
656    extra_ident_chars: &[],
657    strip_strategy: StripStrategy::Generic,
658    has_slash_qualified_refs: false,
659    suppressed_nested_entities: &[],
660    scope_boundary_types: &[],
661    get_language: get_rust,
662    extract_map_entries: false,
663    scope_resolve: Some(&RUST_SCOPE_CONFIG),
664};
665
666#[cfg(feature = "lang-java")]
667static JAVA_CONFIG: LanguageConfig = LanguageConfig {
668    id: "java",
669    extensions: &[".java"],
670    entity_node_types: &[
671        "class_declaration",
672        "method_declaration",
673        "interface_declaration",
674        "enum_declaration",
675        "record_declaration",
676        "field_declaration",
677        "constructor_declaration",
678        "annotation_type_declaration",
679    ],
680    container_node_types: &[
681        "class_body",
682        "interface_body",
683        "enum_body",
684        "record_body",
685        "block",
686    ],
687    call_entity_identifiers: &[],
688    extra_ident_chars: &[],
689    strip_strategy: StripStrategy::Generic,
690    has_slash_qualified_refs: false,
691    suppressed_nested_entities: &[],
692    scope_boundary_types: &[],
693    get_language: get_java,
694    extract_map_entries: false,
695    scope_resolve: Some(&JAVA_SCOPE_CONFIG),
696};
697
698#[cfg(feature = "lang-c")]
699static C_CONFIG: LanguageConfig = LanguageConfig {
700    id: "c",
701    extensions: &[".c", ".h"],
702    entity_node_types: &[
703        "function_definition",
704        "struct_specifier",
705        "enum_specifier",
706        "union_specifier",
707        "type_definition",
708        "declaration",
709    ],
710    container_node_types: &["compound_statement"],
711    call_entity_identifiers: &[],
712    extra_ident_chars: &[],
713    strip_strategy: StripStrategy::Generic,
714    has_slash_qualified_refs: false,
715    suppressed_nested_entities: C_SUPPRESSED_NESTED,
716    scope_boundary_types: &[],
717    get_language: get_c,
718    extract_map_entries: false,
719    scope_resolve: None,
720};
721
722#[cfg(feature = "lang-cpp")]
723static CPP_CONFIG: LanguageConfig = LanguageConfig {
724    id: "cpp",
725    extensions: &[".cpp", ".cc", ".cxx", ".hpp", ".hh", ".hxx"],
726    entity_node_types: &[
727        "function_definition",
728        "class_specifier",
729        "struct_specifier",
730        "enum_specifier",
731        "namespace_definition",
732        "template_declaration",
733        "declaration",
734        "type_definition",
735    ],
736    container_node_types: &[
737        "field_declaration_list",
738        "declaration_list",
739        "compound_statement",
740    ],
741    call_entity_identifiers: &[],
742    extra_ident_chars: &[],
743    strip_strategy: StripStrategy::Generic,
744    has_slash_qualified_refs: false,
745    suppressed_nested_entities: CPP_SUPPRESSED_NESTED,
746    scope_boundary_types: CPP_SCOPE_BOUNDARIES,
747    get_language: get_cpp,
748    extract_map_entries: false,
749    scope_resolve: Some(&CPP_SCOPE_CONFIG),
750};
751
752#[cfg(feature = "lang-ruby")]
753static RUBY_CONFIG: LanguageConfig = LanguageConfig {
754    id: "ruby",
755    extensions: &[".rb"],
756    entity_node_types: &["method", "singleton_method", "class", "module"],
757    container_node_types: &["body_statement"],
758    call_entity_identifiers: &[],
759    extra_ident_chars: &[],
760    strip_strategy: StripStrategy::Generic,
761    has_slash_qualified_refs: false,
762    suppressed_nested_entities: &[],
763    scope_boundary_types: &[],
764    get_language: get_ruby,
765    extract_map_entries: false,
766    scope_resolve: Some(&RUBY_SCOPE_CONFIG),
767};
768
769#[cfg(feature = "lang-csharp")]
770static CSHARP_CONFIG: LanguageConfig = LanguageConfig {
771    id: "csharp",
772    extensions: &[".cs"],
773    entity_node_types: &[
774        "method_declaration",
775        "class_declaration",
776        "interface_declaration",
777        "enum_declaration",
778        "struct_declaration",
779        "record_declaration",
780        "record_struct_declaration",
781        "namespace_declaration",
782        "property_declaration",
783        "constructor_declaration",
784        "field_declaration",
785    ],
786    container_node_types: &["declaration_list", "record_body", "block"],
787    call_entity_identifiers: &[],
788    extra_ident_chars: &[],
789    strip_strategy: StripStrategy::Generic,
790    has_slash_qualified_refs: false,
791    suppressed_nested_entities: &[],
792    scope_boundary_types: &[],
793    get_language: get_csharp,
794    extract_map_entries: false,
795    scope_resolve: Some(&CSHARP_SCOPE_CONFIG),
796};
797
798#[cfg(feature = "lang-php")]
799static PHP_CONFIG: LanguageConfig = LanguageConfig {
800    id: "php",
801    extensions: &[".php", ".inc", ".phtml", ".module"],
802    entity_node_types: &[
803        "function_definition",
804        "class_declaration",
805        "method_declaration",
806        "interface_declaration",
807        "trait_declaration",
808        "enum_declaration",
809        "namespace_definition",
810    ],
811    container_node_types: &[
812        "declaration_list",
813        "enum_declaration_list",
814        "compound_statement",
815    ],
816    call_entity_identifiers: &[],
817    extra_ident_chars: &[],
818    strip_strategy: StripStrategy::Generic,
819    has_slash_qualified_refs: false,
820    suppressed_nested_entities: &[],
821    scope_boundary_types: &[],
822    get_language: get_php,
823    extract_map_entries: false,
824    scope_resolve: Some(&PHP_SCOPE_CONFIG),
825};
826
827#[cfg(feature = "lang-fortran")]
828static FORTRAN_CONFIG: LanguageConfig = LanguageConfig {
829    id: "fortran",
830    extensions: &[".f90", ".f95", ".f03", ".f08", ".f", ".for"],
831    entity_node_types: &[
832        "function",
833        "subroutine",
834        "module",
835        "program",
836        "interface",
837        "type_declaration",
838    ],
839    container_node_types: &["module", "program", "internal_procedures"],
840    call_entity_identifiers: &[],
841    extra_ident_chars: &[],
842    strip_strategy: StripStrategy::Generic,
843    has_slash_qualified_refs: false,
844    suppressed_nested_entities: &[],
845    scope_boundary_types: &[],
846    get_language: get_fortran,
847    extract_map_entries: false,
848    scope_resolve: None,
849};
850
851#[cfg(feature = "lang-swift")]
852static SWIFT_CONFIG: LanguageConfig = LanguageConfig {
853    id: "swift",
854    extensions: &[".swift"],
855    entity_node_types: &[
856        "function_declaration",
857        "class_declaration",
858        "protocol_declaration",
859        "struct_declaration",
860        "enum_declaration",
861        "init_declaration",
862        "deinit_declaration",
863        "subscript_declaration",
864        "typealias_declaration",
865        "property_declaration",
866        "operator_declaration",
867        "associatedtype_declaration",
868    ],
869    container_node_types: &[
870        "class_body",
871        "protocol_body",
872        "enum_class_body",
873        "struct_body",
874        "function_body",
875        "computed_property",
876    ],
877    call_entity_identifiers: &[],
878    extra_ident_chars: &[],
879    strip_strategy: StripStrategy::Generic,
880    has_slash_qualified_refs: false,
881    suppressed_nested_entities: SWIFT_SUPPRESSED_NESTED,
882    scope_boundary_types: &[],
883    get_language: get_swift,
884    extract_map_entries: false,
885    scope_resolve: Some(&SWIFT_SCOPE_CONFIG),
886};
887
888#[cfg(feature = "lang-elixir")]
889static ELIXIR_CONFIG: LanguageConfig = LanguageConfig {
890    id: "elixir",
891    extensions: &[".ex", ".exs"],
892    entity_node_types: &[],
893    container_node_types: &["do_block"],
894    call_entity_identifiers: &[
895        "defmodule",
896        "def",
897        "defp",
898        "defmacro",
899        "defmacrop",
900        "defguard",
901        "defguardp",
902        "defprotocol",
903        "defimpl",
904        "defstruct",
905        "defexception",
906        "defdelegate",
907    ],
908    extra_ident_chars: &[],
909    strip_strategy: StripStrategy::Generic,
910    has_slash_qualified_refs: false,
911    suppressed_nested_entities: &[],
912    scope_boundary_types: &[],
913    get_language: get_elixir,
914    extract_map_entries: false,
915    scope_resolve: None,
916};
917
918#[cfg(feature = "lang-bash")]
919static BASH_CONFIG: LanguageConfig = LanguageConfig {
920    id: "bash",
921    extensions: &[".sh"],
922    entity_node_types: &["function_definition"],
923    container_node_types: &["compound_statement"],
924    call_entity_identifiers: &[],
925    extra_ident_chars: &[],
926    strip_strategy: StripStrategy::Generic,
927    has_slash_qualified_refs: false,
928    suppressed_nested_entities: &[],
929    scope_boundary_types: &[],
930    get_language: get_bash,
931    extract_map_entries: false,
932    scope_resolve: Some(&BASH_SCOPE_CONFIG),
933};
934
935#[cfg(feature = "lang-hcl")]
936static HCL_CONFIG: LanguageConfig = LanguageConfig {
937    id: "hcl",
938    extensions: &[".hcl", ".tf", ".tfvars"],
939    entity_node_types: &["block", "attribute"],
940    container_node_types: &["body"],
941    call_entity_identifiers: &[],
942    extra_ident_chars: &[],
943    strip_strategy: StripStrategy::Generic,
944    has_slash_qualified_refs: false,
945    suppressed_nested_entities: &[SuppressedNestedEntity {
946        parent_entity_node_type: "block",
947        child_entity_node_type: "attribute",
948    }],
949    scope_boundary_types: &[],
950    get_language: get_hcl,
951    extract_map_entries: false,
952    scope_resolve: None,
953};
954
955#[cfg(feature = "lang-kotlin")]
956static KOTLIN_CONFIG: LanguageConfig = LanguageConfig {
957    id: "kotlin",
958    extensions: &[".kt", ".kts"],
959    entity_node_types: &[
960        "function_declaration",
961        "class_declaration",
962        "object_declaration",
963        "property_declaration",
964        "companion_object",
965        "secondary_constructor",
966        "type_alias",
967    ],
968    container_node_types: &["class_body", "enum_class_body"],
969    call_entity_identifiers: &[],
970    extra_ident_chars: &[],
971    strip_strategy: StripStrategy::Generic,
972    has_slash_qualified_refs: false,
973    suppressed_nested_entities: &[],
974    scope_boundary_types: &[],
975    get_language: get_kotlin,
976    extract_map_entries: false,
977    scope_resolve: Some(&KOTLIN_SCOPE_CONFIG),
978};
979
980#[cfg(feature = "lang-xml")]
981static XML_CONFIG: LanguageConfig = LanguageConfig {
982    id: "xml",
983    extensions: &[
984        ".xml", ".plist", ".svg", ".xhtml", ".csproj", ".fsproj", ".vbproj", ".props", ".targets",
985        ".nuspec", ".resx", ".xaml", ".axml",
986    ],
987    entity_node_types: &["element"],
988    container_node_types: &["content"],
989    call_entity_identifiers: &[],
990    extra_ident_chars: &[],
991    strip_strategy: StripStrategy::Generic,
992    has_slash_qualified_refs: false,
993    suppressed_nested_entities: &[],
994    scope_boundary_types: &[],
995    get_language: get_xml,
996    extract_map_entries: false,
997    scope_resolve: None,
998};
999
1000#[cfg(feature = "lang-dart")]
1001static DART_CONFIG: LanguageConfig = LanguageConfig {
1002    id: "dart",
1003    extensions: &[".dart"],
1004    entity_node_types: &[
1005        "class_declaration",
1006        "mixin_declaration",
1007        "extension_declaration",
1008        "extension_type_declaration",
1009        "enum_declaration",
1010        "type_alias",
1011        "class_member",
1012        "function_signature",
1013        "getter_signature",
1014        "setter_signature",
1015    ],
1016    container_node_types: &["class_body", "enum_body", "extension_body"],
1017    call_entity_identifiers: &[],
1018    extra_ident_chars: &[],
1019    strip_strategy: StripStrategy::Generic,
1020    has_slash_qualified_refs: false,
1021    suppressed_nested_entities: &[],
1022    scope_boundary_types: &[],
1023    get_language: get_dart,
1024    extract_map_entries: false,
1025    scope_resolve: Some(&DART_SCOPE_CONFIG),
1026};
1027
1028#[cfg(feature = "lang-perl")]
1029static PERL_CONFIG: LanguageConfig = LanguageConfig {
1030    id: "perl",
1031    extensions: &[".pl", ".pm", ".t"],
1032    entity_node_types: &["subroutine_declaration_statement", "package_statement"],
1033    container_node_types: &["block"],
1034    call_entity_identifiers: &[],
1035    extra_ident_chars: &[],
1036    strip_strategy: StripStrategy::Generic,
1037    has_slash_qualified_refs: false,
1038    suppressed_nested_entities: &[],
1039    scope_boundary_types: &[],
1040    get_language: get_perl,
1041    extract_map_entries: false,
1042    scope_resolve: None,
1043};
1044
1045#[cfg(feature = "lang-ocaml")]
1046static OCAML_CONFIG: LanguageConfig = LanguageConfig {
1047    id: "ocaml",
1048    extensions: &[".ml"],
1049    entity_node_types: &[
1050        "value_definition",
1051        "module_definition",
1052        "module_type_definition",
1053        "type_definition",
1054        "exception_definition",
1055        "class_definition",
1056        "class_type_definition",
1057        "external",
1058    ],
1059    container_node_types: &["structure", "module_binding"],
1060    call_entity_identifiers: &[],
1061    extra_ident_chars: &[],
1062    strip_strategy: StripStrategy::Generic,
1063    has_slash_qualified_refs: false,
1064    suppressed_nested_entities: &[],
1065    scope_boundary_types: &[],
1066    get_language: get_ocaml,
1067    extract_map_entries: false,
1068    scope_resolve: None,
1069};
1070
1071#[cfg(feature = "lang-ocaml")]
1072static OCAML_INTERFACE_CONFIG: LanguageConfig = LanguageConfig {
1073    id: "ocaml_interface",
1074    extensions: &[".mli"],
1075    entity_node_types: &[
1076        "value_specification",
1077        "module_definition",
1078        "module_type_definition",
1079        "type_definition",
1080        "exception_definition",
1081        "class_definition",
1082        "class_type_definition",
1083        "external",
1084    ],
1085    container_node_types: &["signature", "module_binding"],
1086    call_entity_identifiers: &[],
1087    extra_ident_chars: &[],
1088    strip_strategy: StripStrategy::Generic,
1089    has_slash_qualified_refs: false,
1090    suppressed_nested_entities: &[],
1091    scope_boundary_types: &[],
1092    get_language: get_ocaml_interface,
1093    extract_map_entries: false,
1094    scope_resolve: None,
1095};
1096
1097#[cfg(feature = "lang-scala")]
1098static SCALA_CONFIG: LanguageConfig = LanguageConfig {
1099    id: "scala",
1100    extensions: &[".scala", ".sc", ".sbt", ".kojo", ".mill"],
1101    entity_node_types: &[
1102        "class_definition",
1103        "object_definition",
1104        "trait_definition",
1105        "enum_definition",
1106        "function_definition",
1107        "function_declaration",
1108        "val_definition",
1109        "given_definition",
1110        "extension_definition",
1111        "type_definition",
1112        "package_object",
1113    ],
1114    container_node_types: &["template_body", "enum_body", "with_template_body"],
1115    call_entity_identifiers: &[],
1116    extra_ident_chars: &[],
1117    strip_strategy: StripStrategy::Generic,
1118    has_slash_qualified_refs: false,
1119    suppressed_nested_entities: &[],
1120    scope_boundary_types: &[],
1121    get_language: get_scala,
1122    extract_map_entries: false,
1123    scope_resolve: Some(&SCALA_SCOPE_CONFIG),
1124};
1125
1126#[cfg(feature = "lang-zig")]
1127static ZIG_CONFIG: LanguageConfig = LanguageConfig {
1128    id: "zig",
1129    extensions: &[".zig"],
1130    entity_node_types: &[
1131        "function_declaration",
1132        "test_declaration",
1133        "variable_declaration",
1134    ],
1135    container_node_types: &["block"],
1136    call_entity_identifiers: &[],
1137    extra_ident_chars: &[],
1138    strip_strategy: StripStrategy::Generic,
1139    has_slash_qualified_refs: false,
1140    suppressed_nested_entities: &[SuppressedNestedEntity {
1141        parent_entity_node_type: "function_declaration",
1142        child_entity_node_type: "variable_declaration",
1143    }],
1144    scope_boundary_types: &[],
1145    get_language: get_zig,
1146    extract_map_entries: false,
1147    scope_resolve: Some(&ZIG_SCOPE_CONFIG),
1148};
1149
1150#[cfg(feature = "lang-nix")]
1151static NIX_CONFIG: LanguageConfig = LanguageConfig {
1152    id: "nix",
1153    extensions: &[".nix"],
1154    entity_node_types: &["binding", "inherit", "inherit_from"],
1155    container_node_types: &["binding_set"],
1156    call_entity_identifiers: &[],
1157    extra_ident_chars: &[],
1158    strip_strategy: StripStrategy::Generic,
1159    has_slash_qualified_refs: false,
1160    suppressed_nested_entities: &[],
1161    scope_boundary_types: &[],
1162    get_language: get_nix,
1163    extract_map_entries: false,
1164    scope_resolve: None,
1165};
1166
1167#[cfg(feature = "lang-haskell")]
1168static HASKELL_CONFIG: LanguageConfig = LanguageConfig {
1169    id: "haskell",
1170    extensions: &[".hs"],
1171    entity_node_types: &[
1172        "function",        // top-level function definitions
1173        "signature",       // type signatures (e.g. foo :: Int -> Int)
1174        "data_type",       // data declarations
1175        "newtype",         // newtype declarations
1176        "class",           // type class declarations
1177        "instance",        // instance declarations
1178        "type_synomym",    // type aliases (note: typo in grammar)
1179        "foreign_import",  // FFI imports
1180        "foreign_export",  // FFI exports
1181        "pattern_synonym", // pattern synonyms
1182        "type_family",     // type families
1183        "data_family",     // data families
1184        "fixity",          // fixity declarations
1185    ],
1186    container_node_types: &["declarations", "class_body", "instance_body"],
1187    call_entity_identifiers: &[],
1188    extra_ident_chars: &[],
1189    strip_strategy: StripStrategy::Generic,
1190    has_slash_qualified_refs: false,
1191    suppressed_nested_entities: &[],
1192    scope_boundary_types: &["function"],
1193    get_language: get_haskell,
1194    extract_map_entries: false,
1195    scope_resolve: None,
1196};
1197
1198#[cfg(feature = "lang-elm")]
1199static ELM_CONFIG: LanguageConfig = LanguageConfig {
1200    id: "elm",
1201    extensions: &[".elm"],
1202    entity_node_types: &[
1203        "value_declaration",
1204        "type_alias_declaration",
1205        "type_declaration",
1206        "port_annotation",
1207        "infix_declaration",
1208    ],
1209    container_node_types: &[],
1210    call_entity_identifiers: &[],
1211    extra_ident_chars: &[],
1212    strip_strategy: StripStrategy::Generic,
1213    has_slash_qualified_refs: false,
1214    suppressed_nested_entities: &[],
1215    scope_boundary_types: &["value_declaration"],
1216    get_language: get_elm,
1217    extract_map_entries: false,
1218    scope_resolve: None,
1219};
1220
1221// EDN (Extensible Data Notation) shares Clojure's syntax and grammar.
1222// Entities are top-level map entries (keyword key → value), extracted via the
1223// map_lit branch in visit_node when extract_map_entries is true.
1224// Non-map top-level forms (bare vecs, sets, lists) have no nameable identity
1225// and are not extracted.
1226#[cfg(feature = "lang-edn")]
1227static EDN_CONFIG: LanguageConfig = LanguageConfig {
1228    id: "edn",
1229    extensions: &[".edn"],
1230    entity_node_types: &[],
1231    container_node_types: &[],
1232    call_entity_identifiers: &[],
1233    extra_ident_chars: &['-', '?', '!', '*', '='],
1234    strip_strategy: StripStrategy::Clojure,
1235    has_slash_qualified_refs: false,
1236    suppressed_nested_entities: &[],
1237    scope_boundary_types: &[],
1238    get_language: get_clojure,
1239    extract_map_entries: true,
1240    scope_resolve: None,
1241};
1242
1243// Clojure is a Lisp: all definition forms are `list_lit` nodes whose first named
1244// child is a `sym_lit` identifying the macro (defn, ns, defrecord, etc.).
1245// The entity extractor handles these via the list_lit branch in visit_node.
1246#[cfg(feature = "lang-clojure")]
1247static CLOJURE_CONFIG: LanguageConfig = LanguageConfig {
1248    id: "clojure",
1249    extensions: &[".clj", ".cljs", ".cljc"],
1250    entity_node_types: &[],
1251    container_node_types: &[],
1252    call_entity_identifiers: &[
1253        "def",
1254        "defonce",
1255        "defn",
1256        "defn-",
1257        "defmacro",
1258        "defmulti",
1259        "defmethod",
1260        "defprotocol",
1261        "defrecord",
1262        "deftype",
1263        "definterface",
1264        "defstruct",
1265    ],
1266    extra_ident_chars: &['-', '?', '!', '*', '='],
1267    strip_strategy: StripStrategy::Clojure,
1268    has_slash_qualified_refs: true,
1269    suppressed_nested_entities: &[],
1270    scope_boundary_types: &[],
1271    get_language: get_clojure,
1272    extract_map_entries: false,
1273    scope_resolve: None,
1274};
1275
1276#[cfg(feature = "lang-d")]
1277static D_CONFIG: LanguageConfig = LanguageConfig {
1278    id: "d",
1279    extensions: &[".d", ".di"],
1280    entity_node_types: &[
1281        "module_declaration",
1282        "function_declaration",
1283        "class_declaration",
1284        "struct_declaration",
1285        "interface_declaration",
1286        "union_declaration",
1287        "enum_declaration",
1288        "anonymous_enum_declaration",
1289        "template_declaration",
1290        "mixin_template_declaration",
1291        "constructor",
1292        "destructor",
1293        "postblit",
1294        "alias_declaration",
1295        "unittest_declaration",
1296        "variable_declaration",
1297        "manifest_constant",
1298        "auto_declaration",
1299    ],
1300    container_node_types: &["aggregate_body"],
1301    call_entity_identifiers: &[],
1302    extra_ident_chars: &[],
1303    strip_strategy: StripStrategy::Generic,
1304    has_slash_qualified_refs: false,
1305    suppressed_nested_entities: &[
1306        SuppressedNestedEntity {
1307            parent_entity_node_type: "function_declaration",
1308            child_entity_node_type: "variable_declaration",
1309        },
1310        SuppressedNestedEntity {
1311            parent_entity_node_type: "function_declaration",
1312            child_entity_node_type: "auto_declaration",
1313        },
1314        SuppressedNestedEntity {
1315            parent_entity_node_type: "constructor",
1316            child_entity_node_type: "variable_declaration",
1317        },
1318        SuppressedNestedEntity {
1319            parent_entity_node_type: "destructor",
1320            child_entity_node_type: "variable_declaration",
1321        },
1322        SuppressedNestedEntity {
1323            parent_entity_node_type: "unittest_declaration",
1324            child_entity_node_type: "variable_declaration",
1325        },
1326        SuppressedNestedEntity {
1327            parent_entity_node_type: "unittest_declaration",
1328            child_entity_node_type: "auto_declaration",
1329        },
1330    ],
1331    scope_boundary_types: &["function_body", "block_statement"],
1332    get_language: get_d,
1333    extract_map_entries: false,
1334    scope_resolve: None,
1335};
1336
1337// ─── Scope Resolve Configs for Supported Languages ────────────────────────────
1338
1339static PYTHON_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1340    class_scope_nodes: &["class_definition"],
1341    impl_scope_nodes: &[],
1342    function_scope_nodes: &["function_definition"],
1343    class_name_field: ClassNameField::Simple("name"),
1344
1345    assignment_rules: &[
1346        AssignmentRule {
1347            node_kind: "assignment",
1348            strategy: AssignmentStrategy::LeftRight,
1349        },
1350        AssignmentRule {
1351            node_kind: "expression_statement",
1352            strategy: AssignmentStrategy::LeftRight,
1353        },
1354    ],
1355    assignment_recurse_into: &["block"],
1356
1357    param_rules: &[
1358        ParamRule {
1359            node_kind: "typed_parameter",
1360            name_field: ParamNameField::WithFallback("name"),
1361            type_field: "type",
1362            skip_names: &["self", "cls"],
1363        },
1364        ParamRule {
1365            node_kind: "typed_default_parameter",
1366            name_field: ParamNameField::WithFallback("name"),
1367            type_field: "type",
1368            skip_names: &["self", "cls"],
1369        },
1370    ],
1371
1372    return_type_field: None,
1373
1374    call_nodes: &["call"],
1375    call_style: CallNodeStyle::FunctionField("function"),
1376    new_expr_nodes: &[],
1377    new_expr_type_field: "constructor",
1378    composite_literal_nodes: &[],
1379    member_access: &[MemberAccess {
1380        node_kind: "attribute",
1381        object_field: "object",
1382        property_field: "attribute",
1383    }],
1384    scoped_call_nodes: &[],
1385
1386    self_keywords: &["self", "cls"],
1387
1388    init_strategy: InitStrategy::ConstructorBody {
1389        class_nodes: &["class_definition"],
1390        init_names: &["__init__"],
1391        init_node_kind: "function_definition",
1392        self_keyword: "self",
1393        access_kind: "attribute",
1394        obj_field: "object",
1395        prop_field: "attribute",
1396    },
1397
1398    import_extractor: None, // set via import_rules
1399    external_method: false,
1400
1401    builtins: &[
1402        "print",
1403        "len",
1404        "range",
1405        "str",
1406        "int",
1407        "float",
1408        "bool",
1409        "list",
1410        "dict",
1411        "set",
1412        "tuple",
1413        "type",
1414        "super",
1415        "isinstance",
1416        "issubclass",
1417        "getattr",
1418        "setattr",
1419        "hasattr",
1420        "delattr",
1421        "open",
1422        "input",
1423        "map",
1424        "filter",
1425        "zip",
1426        "enumerate",
1427        "sorted",
1428        "reversed",
1429        "min",
1430        "max",
1431        "sum",
1432        "any",
1433        "all",
1434        "abs",
1435        "round",
1436        "format",
1437        "repr",
1438        "id",
1439        "hash",
1440        "ValueError",
1441        "TypeError",
1442        "KeyError",
1443        "RuntimeError",
1444        "Exception",
1445        "StopIteration",
1446    ],
1447};
1448
1449static TS_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1450    class_scope_nodes: &["class_declaration", "abstract_class_declaration"],
1451    impl_scope_nodes: &[],
1452    function_scope_nodes: &[
1453        "function_declaration",
1454        "method_definition",
1455        "arrow_function",
1456    ],
1457    class_name_field: ClassNameField::Simple("name"),
1458
1459    assignment_rules: &[
1460        AssignmentRule {
1461            node_kind: "lexical_declaration",
1462            strategy: AssignmentStrategy::Declarators,
1463        },
1464        AssignmentRule {
1465            node_kind: "variable_declaration",
1466            strategy: AssignmentStrategy::Declarators,
1467        },
1468        AssignmentRule {
1469            node_kind: "expression_statement",
1470            strategy: AssignmentStrategy::LeftRight,
1471        },
1472    ],
1473    assignment_recurse_into: &["statement_block"],
1474
1475    param_rules: &[
1476        ParamRule {
1477            node_kind: "required_parameter",
1478            name_field: ParamNameField::WithFallback("pattern"),
1479            type_field: "type",
1480            skip_names: &["this"],
1481        },
1482        ParamRule {
1483            node_kind: "optional_parameter",
1484            name_field: ParamNameField::WithFallback("pattern"),
1485            type_field: "type",
1486            skip_names: &["this"],
1487        },
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: &["new_expression"],
1495    new_expr_type_field: "constructor",
1496    composite_literal_nodes: &[],
1497    member_access: &[MemberAccess {
1498        node_kind: "member_expression",
1499        object_field: "object",
1500        property_field: "property",
1501    }],
1502    scoped_call_nodes: &[],
1503
1504    self_keywords: &["this"],
1505
1506    init_strategy: InitStrategy::ConstructorBody {
1507        class_nodes: &["class_declaration", "abstract_class_declaration"],
1508        init_names: &["constructor"],
1509        init_node_kind: "method_definition",
1510        self_keyword: "this",
1511        access_kind: "member_expression",
1512        obj_field: "object",
1513        prop_field: "property",
1514    },
1515
1516    import_extractor: None,
1517    external_method: false,
1518
1519    builtins: &[
1520        "console",
1521        "parseInt",
1522        "parseFloat",
1523        "isNaN",
1524        "isFinite",
1525        "setTimeout",
1526        "setInterval",
1527        "clearTimeout",
1528        "clearInterval",
1529        "Promise",
1530        "Array",
1531        "Object",
1532        "Map",
1533        "Set",
1534        "WeakMap",
1535        "WeakSet",
1536        "JSON",
1537        "Math",
1538        "Date",
1539        "RegExp",
1540        "Error",
1541        "TypeError",
1542        "RangeError",
1543        "Symbol",
1544        "Proxy",
1545        "Reflect",
1546        "String",
1547        "Number",
1548        "Boolean",
1549        "BigInt",
1550        "require",
1551        "module",
1552        "exports",
1553        "process",
1554        "Buffer",
1555        "global",
1556        "window",
1557        "document",
1558        "fetch",
1559        "Response",
1560        "Request",
1561        "Headers",
1562        "URL",
1563        "undefined",
1564        "encodeURIComponent",
1565        "decodeURIComponent",
1566        "encodeURI",
1567        "decodeURI",
1568        "AbortController",
1569        "TextEncoder",
1570        "TextDecoder",
1571        "Uint8Array",
1572        "Int8Array",
1573        "Float32Array",
1574        "ArrayBuffer",
1575        "DataView",
1576        "ReadableStream",
1577        "WritableStream",
1578        "Blob",
1579        "File",
1580        "FormData",
1581        "URLSearchParams",
1582        "Event",
1583        "EventTarget",
1584        "CustomEvent",
1585        "queueMicrotask",
1586        "structuredClone",
1587        "atob",
1588        "btoa",
1589        "crypto",
1590        "performance",
1591        "navigator",
1592    ],
1593};
1594
1595static RUST_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1596    class_scope_nodes: &["struct_item"],
1597    impl_scope_nodes: &["impl_item"],
1598    function_scope_nodes: &["function_item"],
1599    class_name_field: ClassNameField::Simple("name"),
1600
1601    assignment_rules: &[AssignmentRule {
1602        node_kind: "let_declaration",
1603        strategy: AssignmentStrategy::PatternBased,
1604    }],
1605    assignment_recurse_into: &["block", "expression_statement"],
1606
1607    param_rules: &[ParamRule {
1608        node_kind: "parameter",
1609        name_field: ParamNameField::RustPattern,
1610        type_field: "type",
1611        skip_names: &["self"],
1612    }],
1613
1614    return_type_field: Some("return_type"),
1615
1616    call_nodes: &["call_expression"],
1617    call_style: CallNodeStyle::FunctionField("function"),
1618    new_expr_nodes: &[],
1619    new_expr_type_field: "constructor",
1620    composite_literal_nodes: &[],
1621    member_access: &[MemberAccess {
1622        node_kind: "field_expression",
1623        object_field: "value",
1624        property_field: "field",
1625    }],
1626    scoped_call_nodes: &["scoped_identifier"],
1627
1628    self_keywords: &["self"],
1629
1630    init_strategy: InitStrategy::StructFields {
1631        struct_nodes: &["struct_item"],
1632    },
1633
1634    import_extractor: None,
1635    external_method: false,
1636
1637    builtins: &[
1638        "println",
1639        "eprintln",
1640        "print",
1641        "eprint",
1642        "dbg",
1643        "format",
1644        "write",
1645        "writeln",
1646        "vec",
1647        "panic",
1648        "todo",
1649        "unimplemented",
1650        "unreachable",
1651        "assert",
1652        "assert_eq",
1653        "assert_ne",
1654        "debug_assert",
1655        "Some",
1656        "None",
1657        "Ok",
1658        "Err",
1659        "Box",
1660        "Vec",
1661        "String",
1662        "HashMap",
1663        "HashSet",
1664        "Arc",
1665        "Rc",
1666        "Mutex",
1667        "RwLock",
1668        "Cell",
1669        "RefCell",
1670        "Option",
1671        "Result",
1672        "Iterator",
1673        "IntoIterator",
1674        "Clone",
1675        "Copy",
1676        "Debug",
1677        "Display",
1678        "Default",
1679        "From",
1680        "Into",
1681        "TryFrom",
1682        "TryInto",
1683        "Send",
1684        "Sync",
1685        "Sized",
1686        "Unpin",
1687        "cfg",
1688        "derive",
1689        "include",
1690        "env",
1691    ],
1692};
1693
1694static GO_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1695    class_scope_nodes: &["type_declaration"],
1696    impl_scope_nodes: &[],
1697    function_scope_nodes: &["function_declaration", "method_declaration"],
1698    class_name_field: ClassNameField::TypeSpec {
1699        spec_kind: "type_spec",
1700        field: "name",
1701    },
1702
1703    assignment_rules: &[
1704        AssignmentRule {
1705            node_kind: "short_var_declaration",
1706            strategy: AssignmentStrategy::ShortVar,
1707        },
1708        AssignmentRule {
1709            node_kind: "var_declaration",
1710            strategy: AssignmentStrategy::VarSpec,
1711        },
1712    ],
1713    assignment_recurse_into: &["block"],
1714
1715    param_rules: &[ParamRule {
1716        node_kind: "parameter_declaration",
1717        name_field: ParamNameField::Simple("name"),
1718        type_field: "type",
1719        skip_names: &[],
1720    }],
1721
1722    return_type_field: Some("result"),
1723
1724    call_nodes: &["call_expression"],
1725    call_style: CallNodeStyle::FunctionField("function"),
1726    new_expr_nodes: &[],
1727    new_expr_type_field: "constructor",
1728    composite_literal_nodes: &["composite_literal"],
1729    member_access: &[MemberAccess {
1730        node_kind: "selector_expression",
1731        object_field: "operand",
1732        property_field: "field",
1733    }],
1734    scoped_call_nodes: &[],
1735
1736    self_keywords: &[],
1737
1738    init_strategy: InitStrategy::StructFields {
1739        struct_nodes: &["type_declaration"],
1740    },
1741
1742    import_extractor: None,
1743    external_method: true,
1744
1745    builtins: &[
1746        "fmt",
1747        "log",
1748        "os",
1749        "io",
1750        "strings",
1751        "strconv",
1752        "bytes",
1753        "make",
1754        "len",
1755        "cap",
1756        "append",
1757        "copy",
1758        "delete",
1759        "close",
1760        "panic",
1761        "recover",
1762        "new",
1763        "print",
1764        "println",
1765        "error",
1766        "string",
1767        "int",
1768        "int8",
1769        "int16",
1770        "int32",
1771        "int64",
1772        "uint",
1773        "uint8",
1774        "uint16",
1775        "uint32",
1776        "uint64",
1777        "float32",
1778        "float64",
1779        "complex64",
1780        "complex128",
1781        "bool",
1782        "byte",
1783        "rune",
1784        "uintptr",
1785        "Println",
1786        "Printf",
1787        "Sprintf",
1788        "Fprintf",
1789        "Errorf",
1790    ],
1791};
1792
1793// ─── Tier 1 Scope Resolve Configs ─────────────────────────────────────────────
1794
1795static JAVA_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1796    class_scope_nodes: &[
1797        "class_declaration",
1798        "interface_declaration",
1799        "enum_declaration",
1800    ],
1801    impl_scope_nodes: &[],
1802    function_scope_nodes: &["method_declaration", "constructor_declaration"],
1803    class_name_field: ClassNameField::Simple("name"),
1804
1805    assignment_rules: &[
1806        AssignmentRule {
1807            node_kind: "local_variable_declaration",
1808            strategy: AssignmentStrategy::Declarators,
1809        },
1810        AssignmentRule {
1811            node_kind: "expression_statement",
1812            strategy: AssignmentStrategy::LeftRight,
1813        },
1814    ],
1815    assignment_recurse_into: &["block"],
1816
1817    param_rules: &[ParamRule {
1818        node_kind: "formal_parameter",
1819        name_field: ParamNameField::Simple("name"),
1820        type_field: "type",
1821        skip_names: &[],
1822    }],
1823
1824    return_type_field: Some("type"),
1825
1826    call_nodes: &["method_invocation"],
1827    call_style: CallNodeStyle::DirectMethod {
1828        object_field: "object",
1829        method_field: "name",
1830    },
1831    new_expr_nodes: &["object_creation_expression"],
1832    new_expr_type_field: "type",
1833    composite_literal_nodes: &[],
1834    member_access: &[MemberAccess {
1835        node_kind: "method_invocation",
1836        object_field: "object",
1837        property_field: "name",
1838    }],
1839    scoped_call_nodes: &[],
1840
1841    self_keywords: &["this"],
1842
1843    init_strategy: InitStrategy::None,
1844    import_extractor: None,
1845    external_method: false,
1846
1847    builtins: &[
1848        "System",
1849        "String",
1850        "Integer",
1851        "Long",
1852        "Double",
1853        "Float",
1854        "Boolean",
1855        "Object",
1856        "Class",
1857        "Math",
1858        "Collections",
1859        "Arrays",
1860        "List",
1861        "Map",
1862        "Set",
1863        "ArrayList",
1864        "HashMap",
1865        "HashSet",
1866        "Optional",
1867        "Stream",
1868        "Exception",
1869        "RuntimeException",
1870        "NullPointerException",
1871        "println",
1872        "printf",
1873        "format",
1874    ],
1875};
1876
1877static CSHARP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1878    class_scope_nodes: &[
1879        "class_declaration",
1880        "interface_declaration",
1881        "struct_declaration",
1882        "enum_declaration",
1883    ],
1884    impl_scope_nodes: &[],
1885    function_scope_nodes: &["method_declaration", "constructor_declaration"],
1886    class_name_field: ClassNameField::Simple("name"),
1887
1888    assignment_rules: &[
1889        AssignmentRule {
1890            node_kind: "local_declaration_statement",
1891            strategy: AssignmentStrategy::Declarators,
1892        },
1893        AssignmentRule {
1894            node_kind: "expression_statement",
1895            strategy: AssignmentStrategy::LeftRight,
1896        },
1897    ],
1898    assignment_recurse_into: &["block"],
1899
1900    param_rules: &[ParamRule {
1901        node_kind: "parameter",
1902        name_field: ParamNameField::Simple("name"),
1903        type_field: "type",
1904        skip_names: &[],
1905    }],
1906
1907    return_type_field: Some("type"),
1908
1909    call_nodes: &["invocation_expression"],
1910    call_style: CallNodeStyle::FunctionField("function"),
1911    new_expr_nodes: &["object_creation_expression"],
1912    new_expr_type_field: "type",
1913    composite_literal_nodes: &[],
1914    member_access: &[MemberAccess {
1915        node_kind: "member_access_expression",
1916        object_field: "expression",
1917        property_field: "name",
1918    }],
1919    scoped_call_nodes: &[],
1920
1921    self_keywords: &["this"],
1922
1923    init_strategy: InitStrategy::None,
1924    import_extractor: None,
1925    external_method: false,
1926
1927    builtins: &[
1928        "Console",
1929        "String",
1930        "Int32",
1931        "Int64",
1932        "Double",
1933        "Boolean",
1934        "Object",
1935        "Math",
1936        "List",
1937        "Dictionary",
1938        "HashSet",
1939        "Task",
1940        "Async",
1941        "Exception",
1942        "ArgumentException",
1943        "WriteLine",
1944        "ReadLine",
1945        "ToString",
1946        "Equals",
1947    ],
1948};
1949
1950static CPP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
1951    class_scope_nodes: &["class_specifier", "struct_specifier"],
1952    impl_scope_nodes: &[],
1953    function_scope_nodes: &["function_definition"],
1954    class_name_field: ClassNameField::Simple("name"),
1955
1956    assignment_rules: &[
1957        AssignmentRule {
1958            node_kind: "declaration",
1959            strategy: AssignmentStrategy::Declarators,
1960        },
1961        AssignmentRule {
1962            node_kind: "expression_statement",
1963            strategy: AssignmentStrategy::LeftRight,
1964        },
1965    ],
1966    assignment_recurse_into: &["compound_statement"],
1967
1968    param_rules: &[ParamRule {
1969        node_kind: "parameter_declaration",
1970        name_field: ParamNameField::Simple("declarator"),
1971        type_field: "type",
1972        skip_names: &[],
1973    }],
1974
1975    return_type_field: Some("type"),
1976
1977    call_nodes: &["call_expression"],
1978    call_style: CallNodeStyle::FunctionField("function"),
1979    new_expr_nodes: &["new_expression"],
1980    new_expr_type_field: "type",
1981    composite_literal_nodes: &[],
1982    member_access: &[MemberAccess {
1983        node_kind: "field_expression",
1984        object_field: "argument",
1985        property_field: "field",
1986    }],
1987    scoped_call_nodes: &["qualified_identifier"],
1988
1989    self_keywords: &["this"],
1990
1991    init_strategy: InitStrategy::StructFields {
1992        struct_nodes: &["class_specifier", "struct_specifier"],
1993    },
1994    import_extractor: None,
1995    external_method: false,
1996
1997    builtins: &[
1998        "std",
1999        "cout",
2000        "cin",
2001        "endl",
2002        "printf",
2003        "scanf",
2004        "malloc",
2005        "free",
2006        "string",
2007        "vector",
2008        "map",
2009        "set",
2010        "pair",
2011        "make_pair",
2012        "shared_ptr",
2013        "unique_ptr",
2014        "make_shared",
2015        "make_unique",
2016        "nullptr",
2017        "size_t",
2018        "int",
2019        "char",
2020        "double",
2021        "float",
2022        "bool",
2023    ],
2024};
2025
2026static RUBY_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2027    class_scope_nodes: &["class", "module"],
2028    impl_scope_nodes: &[],
2029    function_scope_nodes: &["method", "singleton_method"],
2030    class_name_field: ClassNameField::Simple("name"),
2031
2032    assignment_rules: &[AssignmentRule {
2033        node_kind: "assignment",
2034        strategy: AssignmentStrategy::LeftRight,
2035    }],
2036    assignment_recurse_into: &["body_statement"],
2037
2038    param_rules: &[],
2039
2040    return_type_field: None,
2041
2042    call_nodes: &["call"],
2043    call_style: CallNodeStyle::DirectMethod {
2044        object_field: "receiver",
2045        method_field: "method",
2046    },
2047    new_expr_nodes: &[],
2048    new_expr_type_field: "constructor",
2049    composite_literal_nodes: &[],
2050    member_access: &[MemberAccess {
2051        node_kind: "call",
2052        object_field: "receiver",
2053        property_field: "method",
2054    }],
2055    scoped_call_nodes: &["scope_resolution"],
2056
2057    self_keywords: &["self"],
2058
2059    init_strategy: InitStrategy::None,
2060    import_extractor: None,
2061    external_method: false,
2062
2063    builtins: &[
2064        "puts",
2065        "print",
2066        "p",
2067        "require",
2068        "require_relative",
2069        "include",
2070        "extend",
2071        "attr_accessor",
2072        "attr_reader",
2073        "attr_writer",
2074        "raise",
2075        "rescue",
2076        "yield",
2077        "block_given?",
2078        "Array",
2079        "Hash",
2080        "String",
2081        "Integer",
2082        "Float",
2083        "Symbol",
2084        "nil",
2085        "true",
2086        "false",
2087    ],
2088};
2089
2090static KOTLIN_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2091    class_scope_nodes: &[
2092        "class_declaration",
2093        "object_declaration",
2094        "companion_object",
2095    ],
2096    impl_scope_nodes: &[],
2097    function_scope_nodes: &["function_declaration", "secondary_constructor"],
2098    class_name_field: ClassNameField::Simple("name"),
2099
2100    assignment_rules: &[AssignmentRule {
2101        node_kind: "property_declaration",
2102        strategy: AssignmentStrategy::Declarators,
2103    }],
2104    assignment_recurse_into: &["statements", "block", "function_body"],
2105
2106    param_rules: &[ParamRule {
2107        node_kind: "parameter",
2108        name_field: ParamNameField::Simple("name"),
2109        type_field: "type",
2110        skip_names: &[],
2111    }],
2112
2113    return_type_field: Some("type"),
2114
2115    call_nodes: &["call_expression"],
2116    call_style: CallNodeStyle::FirstChild,
2117    new_expr_nodes: &[],
2118    new_expr_type_field: "constructor",
2119    composite_literal_nodes: &[],
2120    member_access: &[MemberAccess {
2121        node_kind: "navigation_expression",
2122        object_field: "expression",
2123        property_field: "navigation_suffix",
2124    }],
2125    scoped_call_nodes: &[],
2126
2127    self_keywords: &["this"],
2128
2129    init_strategy: InitStrategy::ConstructorBody {
2130        class_nodes: &["class_declaration"],
2131        init_names: &["init"],
2132        init_node_kind: "anonymous_initializer",
2133        self_keyword: "this",
2134        access_kind: "navigation_expression",
2135        obj_field: "expression",
2136        prop_field: "navigation_suffix",
2137    },
2138    import_extractor: None,
2139    external_method: false,
2140
2141    builtins: &[
2142        "println",
2143        "print",
2144        "listOf",
2145        "mapOf",
2146        "setOf",
2147        "arrayOf",
2148        "mutableListOf",
2149        "mutableMapOf",
2150        "mutableSetOf",
2151        "String",
2152        "Int",
2153        "Long",
2154        "Double",
2155        "Float",
2156        "Boolean",
2157        "Any",
2158        "Unit",
2159        "Nothing",
2160        "Pair",
2161        "Triple",
2162        "require",
2163        "check",
2164        "error",
2165        "TODO",
2166        "emptyList",
2167        "emptyMap",
2168        "emptySet",
2169        "lazy",
2170        "run",
2171        "let",
2172        "also",
2173        "apply",
2174        "with",
2175        "takeIf",
2176        "takeUnless",
2177        "Throwable",
2178        "Exception",
2179        "RuntimeException",
2180        "IllegalArgumentException",
2181        "IllegalStateException",
2182        "UnsupportedOperationException",
2183        "Regex",
2184        "Sequence",
2185        "Iterable",
2186        "Iterator",
2187        "coroutineScope",
2188        "launch",
2189        "async",
2190        "withContext",
2191        "runBlocking",
2192        "Flow",
2193        "StateFlow",
2194        "SharedFlow",
2195        "Dispatchers",
2196        "Job",
2197        "SupervisorJob",
2198        "CoroutineScope",
2199        "suspend",
2200        "Channel",
2201    ],
2202};
2203
2204static PHP_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2205    class_scope_nodes: &[
2206        "class_declaration",
2207        "interface_declaration",
2208        "trait_declaration",
2209    ],
2210    impl_scope_nodes: &[],
2211    function_scope_nodes: &["function_definition", "method_declaration"],
2212    class_name_field: ClassNameField::Simple("name"),
2213
2214    assignment_rules: &[AssignmentRule {
2215        node_kind: "expression_statement",
2216        strategy: AssignmentStrategy::LeftRight,
2217    }],
2218    assignment_recurse_into: &["compound_statement"],
2219
2220    param_rules: &[ParamRule {
2221        node_kind: "simple_parameter",
2222        name_field: ParamNameField::Simple("name"),
2223        type_field: "type",
2224        skip_names: &[],
2225    }],
2226
2227    return_type_field: Some("return_type"),
2228
2229    call_nodes: &["function_call_expression", "member_call_expression"],
2230    call_style: CallNodeStyle::FunctionField("function"),
2231    new_expr_nodes: &["object_creation_expression"],
2232    new_expr_type_field: "type",
2233    composite_literal_nodes: &[],
2234    member_access: &[MemberAccess {
2235        node_kind: "member_call_expression",
2236        object_field: "object",
2237        property_field: "name",
2238    }],
2239    scoped_call_nodes: &["scoped_call_expression"],
2240
2241    self_keywords: &["$this"],
2242
2243    init_strategy: InitStrategy::None,
2244    import_extractor: None,
2245    external_method: false,
2246
2247    builtins: &[
2248        "echo",
2249        "print",
2250        "var_dump",
2251        "print_r",
2252        "isset",
2253        "unset",
2254        "empty",
2255        "array",
2256        "count",
2257        "strlen",
2258        "substr",
2259        "strpos",
2260        "is_null",
2261        "is_array",
2262        "is_string",
2263        "is_int",
2264        "Exception",
2265        "RuntimeException",
2266        "InvalidArgumentException",
2267    ],
2268};
2269
2270static SWIFT_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2271    class_scope_nodes: &[
2272        "class_declaration",
2273        "protocol_declaration",
2274        "struct_declaration",
2275        "enum_declaration",
2276    ],
2277    impl_scope_nodes: &["extension_declaration"],
2278    function_scope_nodes: &[
2279        "function_declaration",
2280        "init_declaration",
2281        "deinit_declaration",
2282        "subscript_declaration",
2283        "property_declaration",
2284    ],
2285    class_name_field: ClassNameField::Simple("name"),
2286
2287    assignment_rules: &[AssignmentRule {
2288        node_kind: "property_declaration",
2289        strategy: AssignmentStrategy::Declarators,
2290    }],
2291    assignment_recurse_into: &[
2292        "function_body",
2293        "computed_property",
2294        "code_block",
2295        "statements",
2296        "if_statement",
2297        "guard_statement",
2298        "for_statement",
2299        "while_statement",
2300        "repeat_while_statement",
2301        "switch_statement",
2302    ],
2303
2304    param_rules: &[ParamRule {
2305        node_kind: "parameter",
2306        name_field: ParamNameField::Simple("name"),
2307        type_field: "type",
2308        skip_names: &[],
2309    }],
2310
2311    return_type_field: Some("return_type"),
2312
2313    call_nodes: &["call_expression"],
2314    call_style: CallNodeStyle::FirstChild,
2315    new_expr_nodes: &[],
2316    new_expr_type_field: "constructor",
2317    composite_literal_nodes: &[],
2318    member_access: &[MemberAccess {
2319        node_kind: "navigation_expression",
2320        object_field: "target",
2321        property_field: "suffix",
2322    }],
2323    scoped_call_nodes: &[],
2324
2325    self_keywords: &["self"],
2326
2327    init_strategy: InitStrategy::ConstructorBody {
2328        class_nodes: &["class_declaration", "struct_declaration"],
2329        init_names: &["init"],
2330        init_node_kind: "init_declaration",
2331        self_keyword: "self",
2332        access_kind: "navigation_expression",
2333        obj_field: "target",
2334        prop_field: "suffix",
2335    },
2336    import_extractor: None,
2337    external_method: false,
2338
2339    builtins: &[
2340        "print",
2341        "debugPrint",
2342        "fatalError",
2343        "precondition",
2344        "assert",
2345        "String",
2346        "Int",
2347        "Double",
2348        "Float",
2349        "Bool",
2350        "Array",
2351        "Dictionary",
2352        "Set",
2353        "Optional",
2354        "Result",
2355        "Error",
2356        "NSError",
2357        "nil",
2358        "Any",
2359        "AnyObject",
2360        "Void",
2361        "Never",
2362        "Data",
2363        "URL",
2364        "URLRequest",
2365        "URLSession",
2366        "Codable",
2367        "Hashable",
2368        "Equatable",
2369        "Comparable",
2370        "Identifiable",
2371        "Task",
2372        "MainActor",
2373        "Sendable",
2374        "min",
2375        "max",
2376        "abs",
2377        "zip",
2378        "stride",
2379        "type",
2380        "DispatchQueue",
2381        "NotificationCenter",
2382        "UserDefaults",
2383        "NSObject",
2384        "Bundle",
2385        "FileManager",
2386        "true",
2387        "false",
2388    ],
2389};
2390
2391static SCALA_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2392    class_scope_nodes: &["class_definition", "object_definition", "trait_definition"],
2393    impl_scope_nodes: &[],
2394    function_scope_nodes: &["function_definition", "function_declaration"],
2395    class_name_field: ClassNameField::Simple("name"),
2396
2397    assignment_rules: &[AssignmentRule {
2398        node_kind: "val_definition",
2399        strategy: AssignmentStrategy::Declarators,
2400    }],
2401    assignment_recurse_into: &["template_body"],
2402
2403    param_rules: &[ParamRule {
2404        node_kind: "parameter",
2405        name_field: ParamNameField::Simple("name"),
2406        type_field: "type",
2407        skip_names: &[],
2408    }],
2409
2410    return_type_field: Some("return_type"),
2411
2412    call_nodes: &["call_expression"],
2413    call_style: CallNodeStyle::FunctionField("function"),
2414    new_expr_nodes: &[],
2415    new_expr_type_field: "constructor",
2416    composite_literal_nodes: &[],
2417    member_access: &[MemberAccess {
2418        node_kind: "field_expression",
2419        object_field: "value",
2420        property_field: "field",
2421    }],
2422    scoped_call_nodes: &[],
2423
2424    self_keywords: &["this"],
2425
2426    init_strategy: InitStrategy::None,
2427    import_extractor: None,
2428    external_method: false,
2429
2430    builtins: &[
2431        "println", "print", "require", "assert", "String", "Int", "Long", "Double", "Float",
2432        "Boolean", "List", "Map", "Set", "Seq", "Vector", "Option", "Some", "None", "Future",
2433        "Try", "Either", "Left", "Right",
2434    ],
2435};
2436
2437// ─── Tier 2 Scope Resolve Configs (Minimal) ───────────────────────────────────
2438
2439static DART_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2440    class_scope_nodes: &["class_declaration", "mixin_declaration", "enum_declaration"],
2441    impl_scope_nodes: &[],
2442    function_scope_nodes: &["function_signature", "method_signature"],
2443    class_name_field: ClassNameField::Simple("name"),
2444
2445    assignment_rules: &[],
2446    assignment_recurse_into: &[],
2447
2448    param_rules: &[ParamRule {
2449        node_kind: "formal_parameter",
2450        name_field: ParamNameField::Simple("name"),
2451        type_field: "type",
2452        skip_names: &[],
2453    }],
2454
2455    return_type_field: None,
2456
2457    call_nodes: &["function_expression_body"],
2458    call_style: CallNodeStyle::FunctionField("function"),
2459    new_expr_nodes: &[],
2460    new_expr_type_field: "constructor",
2461    composite_literal_nodes: &[],
2462    member_access: &[],
2463    scoped_call_nodes: &[],
2464
2465    self_keywords: &["this"],
2466
2467    init_strategy: InitStrategy::None,
2468    import_extractor: None,
2469    external_method: false,
2470
2471    builtins: &[
2472        "print",
2473        "debugPrint",
2474        "String",
2475        "int",
2476        "double",
2477        "bool",
2478        "List",
2479        "Map",
2480        "Set",
2481        "Future",
2482        "Stream",
2483    ],
2484};
2485
2486static ZIG_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2487    class_scope_nodes: &[],
2488    impl_scope_nodes: &[],
2489    function_scope_nodes: &["function_declaration", "test_declaration"],
2490    class_name_field: ClassNameField::Simple("name"),
2491
2492    assignment_rules: &[],
2493    assignment_recurse_into: &[],
2494
2495    param_rules: &[],
2496
2497    return_type_field: None,
2498
2499    call_nodes: &["call_expression"],
2500    call_style: CallNodeStyle::FunctionField("function"),
2501    new_expr_nodes: &[],
2502    new_expr_type_field: "constructor",
2503    composite_literal_nodes: &[],
2504    member_access: &[MemberAccess {
2505        node_kind: "field_expression",
2506        object_field: "object",
2507        property_field: "field",
2508    }],
2509    scoped_call_nodes: &[],
2510
2511    self_keywords: &[],
2512
2513    init_strategy: InitStrategy::None,
2514    import_extractor: None,
2515    external_method: false,
2516
2517    builtins: &[
2518        "std",
2519        "print",
2520        "debug",
2521        "assert",
2522        "expect",
2523        "allocator",
2524        "mem",
2525        "testing",
2526    ],
2527};
2528
2529static BASH_SCOPE_CONFIG: ScopeResolveConfig = ScopeResolveConfig {
2530    class_scope_nodes: &[],
2531    impl_scope_nodes: &[],
2532    function_scope_nodes: &["function_definition"],
2533    class_name_field: ClassNameField::Simple("name"),
2534
2535    assignment_rules: &[],
2536    assignment_recurse_into: &[],
2537
2538    param_rules: &[],
2539
2540    return_type_field: None,
2541
2542    call_nodes: &["command"],
2543    call_style: CallNodeStyle::FunctionField("name"),
2544    new_expr_nodes: &[],
2545    new_expr_type_field: "constructor",
2546    composite_literal_nodes: &[],
2547    member_access: &[],
2548    scoped_call_nodes: &[],
2549
2550    self_keywords: &[],
2551
2552    init_strategy: InitStrategy::None,
2553    import_extractor: None,
2554    external_method: false,
2555
2556    builtins: &[
2557        "echo", "printf", "cd", "ls", "cat", "grep", "sed", "awk", "if", "then", "else", "fi",
2558        "for", "while", "do", "done", "exit", "return", "export", "source", "eval",
2559    ],
2560};
2561
2562macro_rules! all_configs {
2563    () => {{
2564        &[
2565            #[cfg(feature = "lang-typescript")]
2566            &TYPESCRIPT_CONFIG,
2567            #[cfg(feature = "lang-typescript")]
2568            &TSX_CONFIG,
2569            #[cfg(feature = "lang-javascript")]
2570            &JAVASCRIPT_CONFIG,
2571            #[cfg(feature = "lang-python")]
2572            &PYTHON_CONFIG,
2573            #[cfg(feature = "lang-go")]
2574            &GO_CONFIG,
2575            #[cfg(feature = "lang-rust")]
2576            &RUST_CONFIG,
2577            #[cfg(feature = "lang-java")]
2578            &JAVA_CONFIG,
2579            #[cfg(feature = "lang-c")]
2580            &C_CONFIG,
2581            #[cfg(feature = "lang-cpp")]
2582            &CPP_CONFIG,
2583            #[cfg(feature = "lang-ruby")]
2584            &RUBY_CONFIG,
2585            #[cfg(feature = "lang-csharp")]
2586            &CSHARP_CONFIG,
2587            #[cfg(feature = "lang-php")]
2588            &PHP_CONFIG,
2589            #[cfg(feature = "lang-fortran")]
2590            &FORTRAN_CONFIG,
2591            #[cfg(feature = "lang-swift")]
2592            &SWIFT_CONFIG,
2593            #[cfg(feature = "lang-elixir")]
2594            &ELIXIR_CONFIG,
2595            #[cfg(feature = "lang-bash")]
2596            &BASH_CONFIG,
2597            #[cfg(feature = "lang-hcl")]
2598            &HCL_CONFIG,
2599            #[cfg(feature = "lang-kotlin")]
2600            &KOTLIN_CONFIG,
2601            #[cfg(feature = "lang-xml")]
2602            &XML_CONFIG,
2603            #[cfg(feature = "lang-dart")]
2604            &DART_CONFIG,
2605            #[cfg(feature = "lang-perl")]
2606            &PERL_CONFIG,
2607            #[cfg(feature = "lang-ocaml")]
2608            &OCAML_CONFIG,
2609            #[cfg(feature = "lang-ocaml")]
2610            &OCAML_INTERFACE_CONFIG,
2611            #[cfg(feature = "lang-scala")]
2612            &SCALA_CONFIG,
2613            #[cfg(feature = "lang-zig")]
2614            &ZIG_CONFIG,
2615            #[cfg(feature = "lang-nix")]
2616            &NIX_CONFIG,
2617            #[cfg(feature = "lang-haskell")]
2618            &HASKELL_CONFIG,
2619            #[cfg(feature = "lang-elm")]
2620            &ELM_CONFIG,
2621            #[cfg(feature = "lang-clojure")]
2622            &CLOJURE_CONFIG,
2623            #[cfg(feature = "lang-edn")]
2624            &EDN_CONFIG,
2625            #[cfg(feature = "lang-d")]
2626            &D_CONFIG,
2627        ]
2628    }};
2629}
2630
2631static ALL_CONFIGS: &[&LanguageConfig] = all_configs!();
2632
2633pub fn get_language_config(extension: &str) -> Option<&'static LanguageConfig> {
2634    ALL_CONFIGS
2635        .iter()
2636        .find(|c| c.extensions.contains(&extension))
2637        .copied()
2638}
2639
2640pub fn get_all_code_extensions() -> &'static [&'static str] {
2641    // Derived from ALL_CONFIGS to avoid duplication drift.
2642    // When you add an extension to a LanguageConfig, it's automatically included here.
2643    static EXTENSIONS: std::sync::LazyLock<Vec<&'static str>> = std::sync::LazyLock::new(|| {
2644        ALL_CONFIGS
2645            .iter()
2646            .flat_map(|c| c.extensions.iter().copied())
2647            .collect()
2648    });
2649    &EXTENSIONS
2650}