use crate::CompilerState;
use leo_ast::{Expression, Location, Node, NodeID, const_eval::Value};
use leo_errors::StaticAnalyzerError;
use leo_span::{Span, Symbol};
pub struct ConstPropagationVisitor<'a> {
pub state: &'a mut CompilerState,
pub program: Symbol,
pub module: Vec<Symbol>,
pub changed: bool,
pub const_not_evaluated: Option<Span>,
pub array_index_not_evaluated: Option<Span>,
pub array_length_not_evaluated: Option<Span>,
pub repeat_count_not_evaluated: Option<Span>,
}
impl ConstPropagationVisitor<'_> {
pub fn in_scope<T>(&mut self, id: NodeID, func: impl FnOnce(&mut Self) -> T) -> T {
self.state.symbol_table.enter_existing_scope(Some(id));
let result = func(self);
self.state.symbol_table.enter_parent();
result
}
pub fn in_module_scope<T>(&mut self, module: &[Symbol], func: impl FnOnce(&mut Self) -> T) -> T {
let parent_module = self.module.clone();
self.module = module.to_vec();
let result = func(self);
self.module = parent_module;
result
}
pub fn emit_err(&self, err: StaticAnalyzerError) {
self.state.handler.emit_err(err);
}
pub fn value_to_expression(&self, value: &Value, span: Span, id: NodeID) -> Option<Expression> {
let ty = self.state.type_table.get(&id)?;
let symbol_table = &self.state.symbol_table;
let struct_lookup = |loc: &Location| {
symbol_table
.lookup_struct(self.program, loc)
.unwrap()
.members
.iter()
.map(|mem| (mem.identifier.name, mem.type_.clone()))
.collect()
};
value.to_expression(span, &self.state.node_builder, &ty, &struct_lookup)
}
pub fn value_to_expression_node(&self, value: &Value, previous: &impl Node) -> Option<Expression> {
self.value_to_expression(value, previous.span(), previous.id())
}
}