use alloc::vec;
use alloc::vec::Vec;
use crate::path_search::search::{SearchArgs, SearchResult};
use crate::query::adj_ast;
use crate::syntax::SyntaxNode;
use crate::CodeGraph;
const COMPOUND_OPERATORS: [&str; 3] = ["+=", "*=", "/="];
pub fn search(args: &SearchArgs<'_>) -> Vec<SearchResult> {
let Some(SyntaxNode::Assignment {
variable_id,
operator,
..
}) = args.graph.nodes.get(&args.n_id)
else {
return Vec::new();
};
let assign_id = *variable_id;
let target = args.graph.nodes.get(&assign_id);
if target.and_then(SyntaxNode::symbol) == Some(args.symbol) {
let compound = operator
.as_deref()
.is_some_and(|value| COMPOUND_OPERATORS.contains(&value));
if compound {
if !args.def_only {
return vec![(false, args.n_id)];
}
return Vec::new();
}
return vec![(true, args.n_id)];
}
if args.graph.label_type(assign_id) == Some("ArgumentList") {
let mut out: Vec<SearchResult> = Vec::new();
for c_id in adj_ast(args.graph, assign_id, Some(1), &["SymbolLookup"]) {
if args.graph.nodes.get(&c_id).and_then(SyntaxNode::symbol) == Some(args.symbol) {
out.push((true, args.n_id));
}
}
return out;
}
if !args.def_only
&& target
.and_then(SyntaxNode::expression)
.is_some_and(|expression| !expression.is_empty() && expression.contains(args.symbol))
{
return vec![(false, args.n_id)];
}
Vec::new()
}