use crate::annotation_aware_type_mapper::AnnotationAwareTypeMapper;
use crate::hir::Type;
use crate::string_optimization::StringOptimizer;
use anyhow::Result;
use std::collections::{HashMap, HashSet};
pub struct CodeGenContext<'a> {
pub type_mapper: &'a crate::type_mapper::TypeMapper,
pub annotation_aware_mapper: AnnotationAwareTypeMapper,
pub string_optimizer: StringOptimizer,
pub union_enum_generator: crate::union_enum_gen::UnionEnumGenerator,
pub generated_enums: Vec<proc_macro2::TokenStream>,
pub needs_hashmap: bool,
pub needs_hashset: bool,
pub needs_vecdeque: bool,
pub needs_fnv_hashmap: bool,
pub needs_ahash_hashmap: bool,
pub needs_arc: bool,
pub needs_rc: bool,
pub needs_cow: bool,
pub declared_vars: Vec<HashSet<String>>,
pub current_function_can_fail: bool,
pub current_return_type: Option<Type>,
pub module_mapper: crate::module_mapper::ModuleMapper,
pub imported_modules: std::collections::HashMap<String, crate::module_mapper::ModuleMapping>,
pub imported_items: std::collections::HashMap<String, String>,
pub mutable_vars: HashSet<String>,
pub needs_zerodivisionerror: bool,
pub needs_indexerror: bool,
pub is_classmethod: bool,
pub in_generator: bool,
pub generator_state_vars: HashSet<String>,
pub var_types: HashMap<String, Type>,
pub class_names: HashSet<String>,
pub mutating_methods: HashMap<String, HashSet<String>>,
}
impl<'a> CodeGenContext<'a> {
pub fn enter_scope(&mut self) {
self.declared_vars.push(HashSet::new());
}
pub fn exit_scope(&mut self) {
self.declared_vars.pop();
}
pub fn is_declared(&self, var_name: &str) -> bool {
self.declared_vars
.iter()
.any(|scope| scope.contains(var_name))
}
pub fn declare_var(&mut self, var_name: &str) {
if let Some(current_scope) = self.declared_vars.last_mut() {
current_scope.insert(var_name.to_string());
}
}
pub fn process_union_type(&mut self, types: &[crate::hir::Type]) -> String {
let (enum_name, enum_def) = self.union_enum_generator.generate_union_enum(types);
if !enum_def.is_empty() {
self.generated_enums.push(enum_def);
}
enum_name
}
}
pub trait RustCodeGen {
fn to_rust_tokens(&self, ctx: &mut CodeGenContext) -> Result<proc_macro2::TokenStream>;
}
pub trait ToRustExpr {
fn to_rust_expr(&self, ctx: &mut CodeGenContext) -> Result<syn::Expr>;
}