use crate::ConditionalTreeNode;
use indexmap::IndexSet;
use leo_ast::Identifier;
use leo_errors::StaticAnalyzerWarning;
use leo_span::{Span, Symbol};
pub struct AwaitChecker {
pub(crate) to_await: Vec<ConditionalTreeNode>,
pub(crate) static_to_await: IndexSet<Symbol>,
}
impl AwaitChecker {
pub fn new() -> Self {
Self { to_await: Vec::new(), static_to_await: IndexSet::new() }
}
pub fn remove(&mut self, id: &Identifier) -> bool {
let is_not_first = self.to_await.iter_mut().any(|node| node.remove_element(&id.name));
self.static_to_await.shift_remove(&id.name);
is_not_first
}
pub fn set_futures(&mut self, futures: IndexSet<Symbol>) {
if futures.is_empty() {
self.to_await = Vec::new();
} else {
self.to_await = vec![ConditionalTreeNode::new(futures.clone())];
}
self.static_to_await = futures;
}
pub fn create_then_scope(
&mut self,
is_finalize: bool,
_input: Span,
) -> Result<Vec<ConditionalTreeNode>, StaticAnalyzerWarning> {
if is_finalize {
let mut current_nodes = Vec::new();
for node in self.to_await.iter() {
current_nodes.push(node.clone().create_child());
}
self.to_await = current_nodes.clone();
Ok(current_nodes)
} else {
Ok(Vec::new())
}
}
pub fn exit_then_scope(
&mut self,
is_finalize: bool,
parent_nodes: Vec<ConditionalTreeNode>,
) -> Vec<ConditionalTreeNode> {
if is_finalize { core::mem::replace(&mut self.to_await, parent_nodes) } else { Vec::new() }
}
pub fn exit_statement_scope(&mut self, is_finalize: bool, then_nodes: Vec<ConditionalTreeNode>) {
if is_finalize {
self.to_await.extend(then_nodes);
}
}
}