Skip to main content

qex_core/chunk/languages/
java.rs

1use super::{extract_preceding_comments, find_name, NodeMetadata, LanguageChunker};
2use crate::chunk::ChunkType;
3
4pub struct JavaChunker;
5
6impl LanguageChunker for JavaChunker {
7    fn tree_sitter_language(&self) -> tree_sitter::Language {
8        tree_sitter_java::LANGUAGE.into()
9    }
10
11    fn language_name(&self) -> &str {
12        "java"
13    }
14
15    fn file_extensions(&self) -> &[&str] {
16        &["java"]
17    }
18
19    fn is_splittable(&self, node_type: &str) -> bool {
20        matches!(
21            node_type,
22            "method_declaration"
23                | "class_declaration"
24                | "interface_declaration"
25                | "enum_declaration"
26                | "constructor_declaration"
27        )
28    }
29
30    fn has_nested_chunks(&self, node_type: &str) -> bool {
31        matches!(
32            node_type,
33            "class_declaration" | "interface_declaration" | "enum_declaration"
34        )
35    }
36
37    fn classify_node(&self, node_type: &str, parent_name: Option<&str>) -> ChunkType {
38        match node_type {
39            "class_declaration" => ChunkType::Class,
40            "interface_declaration" => ChunkType::Interface,
41            "enum_declaration" => ChunkType::Enum,
42            "method_declaration" | "constructor_declaration" => {
43                if parent_name.is_some() {
44                    ChunkType::Method
45                } else {
46                    ChunkType::Function
47                }
48            }
49            _ => ChunkType::ModuleLevel,
50        }
51    }
52
53    fn extract_metadata(&self, node: tree_sitter::Node, source: &str) -> NodeMetadata {
54        let mut meta = NodeMetadata::default();
55
56        match node.kind() {
57            "method_declaration" | "constructor_declaration" => {
58                meta.name = find_name(node, source);
59                meta.docstring = extract_preceding_comments(node, source);
60                // Check for annotations
61                if let Some(prev) = node.prev_sibling() {
62                    if prev.kind() == "marker_annotation" || prev.kind() == "annotation" {
63                        let text = &source[prev.start_byte()..prev.end_byte()];
64                        meta.decorators.push(text.to_string());
65                    }
66                }
67            }
68            "class_declaration" | "interface_declaration" | "enum_declaration" => {
69                meta.name = find_name(node, source);
70                meta.docstring = extract_preceding_comments(node, source);
71            }
72            _ => {
73                meta.name = find_name(node, source);
74                meta.docstring = extract_preceding_comments(node, source);
75            }
76        }
77
78        meta
79    }
80}