use alloc::borrow::ToOwned;
use alloc::format;
use alloc::string::String;
use crate::query::{get_node_by_path, label_text};
use crate::syntax::builders::class_declaration::build_class_node;
use crate::syntax::fields::java::{class_declaration, record_declaration};
use crate::syntax::metadata::java::add_class_to_metadata;
use crate::syntax::readers::java::common::extract_modifiers;
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError};
use crate::utilities::text_nodes::node_to_str;
use crate::{CodeGraph, NodeId};
fn inherited_class(args: &SyntaxGraphArgs<'_>, n_id: NodeId) -> Option<String> {
let graph = args.ast_graph;
let extends = get_node_by_path(graph, n_id, &["superclass", "type_identifier"])
.and_then(|extends_id| label_text(graph, extends_id))
.map(ToOwned::to_owned);
let implements = get_node_by_path(
graph,
n_id,
&["super_interfaces", "type_list", "type_identifier"],
)
.and_then(|implements_id| label_text(graph, implements_id))
.filter(|value| !value.is_empty());
match (extends, implements) {
(Some(extends), Some(implements)) => Some(format!("{extends},{implements}")),
(Some(extends), None) => Some(extends),
(None, Some(implements)) => Some(implements.to_owned()),
(None, None) => None,
}
}
pub fn reader(
args: &mut SyntaxGraphArgs<'_>,
n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
let (name_id, block_id, parameters_id) = match args.ast_graph.label_type(n_id) {
Some("record_declaration") => (
args.required_field_alt(n_id, record_declaration::NAME)?,
args.required_field_alt(n_id, record_declaration::BODY)?,
Some(args.required_field_alt(n_id, record_declaration::PARAMETERS)?),
),
Some("class_declaration") => (
args.required_field_alt(n_id, class_declaration::NAME)?,
args.required_field_alt(n_id, class_declaration::BODY)?,
None,
),
_ => return Err(SyntaxGraphError::UnexpectedAstShape),
};
let name = node_to_str(args.ast_graph, name_id);
let inherited = inherited_class(args, n_id);
let attr_list_ids: &[NodeId] = match ¶meters_id {
Some(id) => core::slice::from_ref(id),
None => &[],
};
if args.syntax_graph.nodes.contains_key(&NodeId(0)) {
add_class_to_metadata(args, n_id, &name)?;
}
let (modifiers_id, access_modifiers) = extract_modifiers(args.ast_graph, n_id);
build_class_node(
args,
n_id,
name,
Some(block_id),
attr_list_ids,
inherited,
modifiers_id,
access_modifiers,
)
.map(Some)
}