use crate::{
ast::AstGraph,
query::{adj_ast, match_ast_d, match_ast_group_d},
syntax::{
builders::class_declaration::build_class_node, fields::Field, SyntaxGraphArgs,
SyntaxGraphError,
},
utilities::text_nodes::node_to_str,
NodeId,
};
use alloc::borrow::ToOwned;
use alloc::string::String;
const NAME: Field<false> = Field::new("name_id");
#[must_use]
pub fn extract_modifiers(graph: &AstGraph, n_id: NodeId) -> (Option<NodeId>, Option<String>) {
let Some(modifiers_id) = match_ast_d(graph, n_id, "modifiers", Some(1)) else {
return (None, None);
};
let access_modifiers = match_ast_d(graph, modifiers_id, "visibility_modifier", Some(1))
.map(|vis_id| node_to_str(graph, vis_id).trim().to_owned());
let annotation_ids = match_ast_group_d(graph, modifiers_id, "annotation", Some(1));
let has_non_annotation = adj_ast(graph, modifiers_id, Some(1), &[])
.iter()
.any(|c_id| !annotation_ids.contains(c_id));
(has_non_annotation.then_some(modifiers_id), access_modifiers)
}
pub fn reader(
args: &mut SyntaxGraphArgs<'_>,
n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
let graph = args.ast_graph;
let name_id = args
.optional_field_alt(n_id, NAME)
.or_else(|| match_ast_d(graph, n_id, "identifier", Some(1)));
let name = name_id.map_or_else(|| "AnonymousClass".to_owned(), |id| node_to_str(graph, id));
let block_id = match_ast_d(graph, n_id, "class_body", Some(1))
.or_else(|| adj_ast(graph, n_id, Some(1), &[]).last().copied());
let (modifiers_id, access_modifiers) = extract_modifiers(graph, n_id);
build_class_node(
args,
n_id,
name,
block_id,
&[],
None,
modifiers_id,
access_modifiers,
)
.map(Some)
}