Skip to main content

dk_engine/parser/langs/
scala.rs

1//! Scala language configuration for the query-driven parser.
2
3use crate::parser::lang_config::{CommentStyle, LanguageConfig};
4use dk_core::{Symbol, Visibility};
5use tree_sitter::Language;
6
7/// Scala language configuration for [`QueryDrivenParser`](crate::parser::engine::QueryDrivenParser).
8pub struct ScalaConfig;
9
10impl LanguageConfig for ScalaConfig {
11    fn language(&self) -> Language {
12        tree_sitter_scala::LANGUAGE.into()
13    }
14
15    fn extensions(&self) -> &'static [&'static str] {
16        &["scala", "sc"]
17    }
18
19    fn symbols_query(&self) -> &'static str {
20        include_str!("../queries/scala_symbols.scm")
21    }
22
23    fn calls_query(&self) -> &'static str {
24        include_str!("../queries/scala_calls.scm")
25    }
26
27    fn imports_query(&self) -> &'static str {
28        include_str!("../queries/scala_imports.scm")
29    }
30
31    fn comment_style(&self) -> CommentStyle {
32        CommentStyle::SlashSlash
33    }
34
35    fn resolve_visibility(&self, _modifiers: Option<&str>, _name: &str) -> Visibility {
36        // Scala defaults to public. Visibility modifiers (private/protected)
37        // appear as `access_modifier` child nodes, but we handle those in
38        // `adjust_symbol` by walking the AST.
39        Visibility::Public
40    }
41
42    fn adjust_symbol(&self, sym: &mut Symbol, node: &tree_sitter::Node, source: &[u8]) {
43        // Check for access_modifier children (private/protected).
44        let mut cursor = node.walk();
45        for child in node.children(&mut cursor) {
46            if child.kind() == "access_modifier" || child.kind() == "modifiers" {
47                let text = &source[child.start_byte()..child.end_byte()];
48                let text_str = std::str::from_utf8(text).unwrap_or("");
49                if text_str.contains("private") {
50                    sym.visibility = Visibility::Private;
51                    return;
52                }
53                // Scala's protected is roughly equivalent to crate-level visibility.
54                if text_str.contains("protected") {
55                    sym.visibility = Visibility::Private;
56                    return;
57                }
58            }
59        }
60    }
61
62    fn is_external_import(&self, _module_path: &str) -> bool {
63        // Scala imports are package-based. Without build tool context
64        // we can't distinguish internal vs external, so treat all as external.
65        true
66    }
67}