use alloc::vec::Vec;
use crate::query::{adj_ast, match_ast_group_d};
use crate::syntax::builders::array_node::build_array_node;
use crate::syntax::builders::object::build_object_node;
use crate::syntax::builders::object_creation::build_object_creation_node;
use crate::syntax::fields::go::composite_literal;
use crate::syntax::readers::go::common::literal_elements;
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError};
use crate::utilities::text_nodes::node_to_str;
use crate::{CodeGraph, NodeId};
const VALID_PARAMETERS: &[&str] = &["literal_value", "qualified_type"];
const NAMED_TYPES: &[&str] = &["type_identifier", "qualified_type"];
const ARRAY_TYPES: &[&str] = &["array_type", "implicit_length_array_type", "slice_type"];
pub fn reader(
args: &mut SyntaxGraphArgs<'_>,
n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
let graph = args.ast_graph;
let c_ids = adj_ast(graph, n_id, None, &[]);
if let [type_id, value_id] = *c_ids.as_slice() {
if graph.label_type(value_id) == Some("literal_value")
&& !match_ast_group_d(graph, value_id, "keyed_element", None).is_empty()
{
let name = node_to_str(graph, type_id);
let initializer_id = if graph.label_type(type_id) == Some("map_type") {
None
} else {
Some(type_id)
};
return build_object_creation_node(
args,
n_id,
name,
Some(value_id),
initializer_id,
None,
)
.map(Some);
}
}
let type_id = args.required_field_alt(n_id, composite_literal::TYPE)?;
if ARRAY_TYPES.contains(&graph.label_type(type_id).unwrap_or_default()) {
let body_id = args.required_field_alt(n_id, composite_literal::BODY)?;
let elements = literal_elements(graph, body_id);
return build_array_node(args, n_id, &elements).map(Some);
}
let name = if NAMED_TYPES.contains(&graph.label_type(type_id).unwrap_or_default()) {
Some(node_to_str(graph, type_id))
} else {
None
};
let filtered: Vec<NodeId> = c_ids
.into_iter()
.filter(|c_id| VALID_PARAMETERS.contains(&graph.label_type(*c_id).unwrap_or_default()))
.collect();
build_object_node(args, n_id, &filtered, name, None).map(Some)
}