use crate::{
query::{adj_ast, match_ast_d},
syntax::{
builders::{
for_each_statement::build_for_each_statement_node,
for_statement::build_for_statement_node,
},
SyntaxGraphArgs, SyntaxGraphError,
},
CodeGraph, NodeId,
};
pub fn reader(
args: &mut SyntaxGraphArgs<'_>,
n_id: NodeId,
) -> Result<Option<NodeId>, SyntaxGraphError> {
let graph = args.ast_graph;
let class_childs = adj_ast(graph, n_id, Some(1), &[]);
let body_id = match_ast_d(graph, n_id, "block", Some(1))
.or_else(|| class_childs.first().copied())
.ok_or(SyntaxGraphError::MissingAstNode)?;
let mut var_node = match_ast_d(graph, n_id, "variable_declaration", Some(1))
.or_else(|| class_childs.last().copied())
.ok_or(SyntaxGraphError::MissingAstNode)?;
let in_node = match_ast_d(graph, n_id, "in", Some(1));
if graph.label_type(var_node) == Some("variable_declaration") {
if let Some(s_id) = match_ast_d(graph, var_node, "identifier", Some(1)) {
var_node = s_id;
}
}
if let Some(in_id) = in_node {
let iterable_item = class_childs
.windows(2)
.find_map(|window| match window {
[current, next] if *current == in_id => Some(*next),
_ => None,
})
.ok_or(SyntaxGraphError::UnexpectedAstShape)?;
return build_for_each_statement_node(args, n_id, var_node, iterable_item, Some(body_id))
.map(Some);
}
build_for_statement_node(args, n_id, Some(var_node), None, None, body_id).map(Some)
}