use alloc::vec;
use alloc::vec::Vec;
use crate::query::{match_ast_group, match_ast_group_d};
use crate::syntax::builders::expression_statement::{
build_variable_declaration_group_node, VarNameEntry,
};
use crate::syntax::builders::variable_declaration::build_variable_declaration_node;
use crate::syntax::fields::go::var_spec;
use crate::syntax::readers::go::common::pair_declaration_value_ids;
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError};
use crate::utilities::text_nodes::node_to_str;
use crate::NodeId;
fn collect_specs(args: &SyntaxGraphArgs<'_>, n_id: NodeId) -> Vec<NodeId> {
let mut groups = match_ast_group(args.ast_graph, n_id, &["var_spec", "const_spec"], Some(2));
let mut spec_ids = groups.remove("var_spec").unwrap_or_default();
spec_ids.append(&mut groups.remove("const_spec").unwrap_or_default());
spec_ids
}
fn spec_entries(
args: &SyntaxGraphArgs<'_>,
spec_id: NodeId,
) -> Result<Vec<VarNameEntry>, SyntaxGraphError> {
let graph = args.ast_graph;
let mut name_ids = match_ast_group_d(graph, spec_id, "identifier", Some(1));
if name_ids.is_empty() {
name_ids = vec![args.required_field_alt(spec_id, var_spec::NAME)?];
}
let type_name = args
.optional_field_alt(spec_id, var_spec::TYPE)
.map(|id| node_to_str(graph, id));
let value_field_id = args.optional_field_alt(spec_id, var_spec::VALUE);
let value_ids = pair_declaration_value_ids(graph, value_field_id, name_ids.len());
Ok(name_ids
.into_iter()
.zip(value_ids)
.map(|(name_id, value_id)| VarNameEntry {
name: node_to_str(graph, name_id),
name_id,
type_name: type_name.clone(),
value_id,
})
.collect())
}
pub fn reader(
args: &mut SyntaxGraphArgs<'_>,
n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
let spec_ids = collect_specs(args, n_id);
if spec_ids.is_empty() {
let var_name = node_to_str(args.ast_graph, n_id);
return build_variable_declaration_node(args, n_id, var_name, None, None, None, None)
.map(Some);
}
let mut entries: Vec<VarNameEntry> = Vec::new();
for spec_id in spec_ids {
entries.extend(spec_entries(args, spec_id)?);
}
build_variable_declaration_group_node(args, n_id, &entries).map(Some)
}