use alloc::vec::Vec;
use crate::query::{adj_ast, match_ast};
use crate::syntax::builders::argument::build_argument_node;
use crate::syntax::builders::named_argument::build_named_argument_node;
use crate::syntax::fields::c_sharp::{argument, attribute_argument};
use crate::syntax::readers::constants::C_SHARP_EXPRESSION;
use crate::syntax::{SyntaxGraphArgs, SyntaxGraphError};
use crate::utilities::text_nodes::node_to_str;
use crate::{CodeGraph, NodeId};
fn is_valid_argument_type(kind: &str) -> bool {
C_SHARP_EXPRESSION.contains(&kind) || kind == "declaration_expression"
}
pub fn reader(
args: &mut SyntaxGraphArgs<'_>,
n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
let graph = args.ast_graph;
let match_map = match_ast(graph, n_id, &[":"], None);
let name_field = match graph.label_type(n_id) {
Some("argument") => args.optional_field_alt(n_id, argument::NAME),
Some("attribute_argument") => args.optional_field_alt(n_id, attribute_argument::NAME),
_ => return Err(SyntaxGraphError::UnexpectedAstShape),
};
if let Some(var_id) = name_field {
if match_map.get(":").copied().flatten().is_some() {
if let Some(val_id) = match_map.get("__1__").copied().flatten() {
let name = node_to_str(graph, var_id);
return build_named_argument_node(args, n_id, Some(name), val_id).map(Some);
}
}
let value_ids: Vec<NodeId> = adj_ast(graph, n_id, Some(1), &[])
.into_iter()
.filter(|c_id| *c_id != var_id)
.filter(|c_id| graph.label_type(*c_id).is_some_and(is_valid_argument_type))
.collect();
if let Some(val_id) = value_ids.last().copied() {
let name = node_to_str(graph, var_id);
return build_named_argument_node(args, n_id, Some(name), val_id).map(Some);
}
}
let valid_children: Vec<NodeId> = adj_ast(graph, n_id, Some(1), &[])
.into_iter()
.filter(|c_id| graph.label_type(*c_id).is_some_and(is_valid_argument_type))
.collect();
build_argument_node(args, n_id, &valid_children).map(Some)
}