Skip to main content

code_analyze_core/languages/
java.rs

1// SPDX-FileCopyrightText: 2026 code-analyze-mcp contributors
2// SPDX-License-Identifier: Apache-2.0
3/// Tree-sitter query for extracting Java elements (methods and classes).
4pub const ELEMENT_QUERY: &str = r"
5(method_declaration
6  name: (identifier) @method_name) @function
7(class_declaration
8  name: (identifier) @class_name) @class
9(interface_declaration
10  name: (identifier) @interface_name) @class
11(enum_declaration
12  name: (identifier) @enum_name) @class
13";
14
15/// Tree-sitter query for extracting function calls.
16pub const CALL_QUERY: &str = r"
17(method_invocation
18  name: (identifier) @call)
19";
20
21/// Tree-sitter query for extracting type references.
22pub const REFERENCE_QUERY: &str = r"
23(type_identifier) @type_ref
24";
25
26/// Tree-sitter query for extracting Java imports.
27pub const IMPORT_QUERY: &str = r"
28(import_declaration) @import_path
29";
30
31use tree_sitter::Node;
32
33/// Extract inheritance information from a Java class node.
34#[must_use]
35pub fn extract_inheritance(node: &Node, source: &str) -> Vec<String> {
36    let mut inherits = Vec::new();
37
38    // Extract superclass (extends)
39    if let Some(superclass) = node.child_by_field_name("superclass") {
40        for i in 0..superclass.named_child_count() {
41            if let Some(child) = superclass.named_child(u32::try_from(i).unwrap_or(u32::MAX))
42                && child.kind() == "type_identifier"
43            {
44                let text = &source[child.start_byte()..child.end_byte()];
45                inherits.push(format!("extends {text}"));
46            }
47        }
48    }
49
50    // Extract interfaces (implements)
51    if let Some(interfaces) = node.child_by_field_name("interfaces") {
52        for i in 0..interfaces.named_child_count() {
53            if let Some(type_list) = interfaces.named_child(u32::try_from(i).unwrap_or(u32::MAX)) {
54                for j in 0..type_list.named_child_count() {
55                    if let Some(type_node) =
56                        type_list.named_child(u32::try_from(j).unwrap_or(u32::MAX))
57                        && type_node.kind() == "type_identifier"
58                    {
59                        let text = &source[type_node.start_byte()..type_node.end_byte()];
60                        inherits.push(format!("implements {text}"));
61                    }
62                }
63            }
64        }
65    }
66
67    inherits
68}