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