use oxc_ecmascript::constant_evaluation::ConstantValue;
use rustc_hash::{FxHashMap, FxHashSet};
use oxc_data_structures::stack::NonEmptyStack;
use oxc_span::{Atom, SourceType};
use oxc_syntax::symbol::SymbolId;
use crate::{CompressOptions, symbol_value::SymbolValues};
pub struct MinifierState<'a> {
pub source_type: SourceType,
pub options: CompressOptions,
pub dce: bool,
pub pure_functions: FxHashMap<SymbolId, Option<ConstantValue<'a>>>,
pub symbol_values: SymbolValues<'a>,
pub class_symbols_stack: ClassSymbolsStack<'a>,
pub changed: bool,
}
impl MinifierState<'_> {
pub fn new(source_type: SourceType, options: CompressOptions, dce: bool) -> Self {
Self {
source_type,
options,
dce,
pure_functions: FxHashMap::default(),
symbol_values: SymbolValues::default(),
class_symbols_stack: ClassSymbolsStack::new(),
changed: false,
}
}
}
pub struct ClassSymbolsStack<'a> {
stack: NonEmptyStack<FxHashSet<Atom<'a>>>,
}
impl<'a> ClassSymbolsStack<'a> {
pub fn new() -> Self {
Self { stack: NonEmptyStack::new(FxHashSet::default()) }
}
pub fn is_exhausted(&self) -> bool {
self.stack.is_exhausted()
}
pub fn push_class_scope(&mut self) {
self.stack.push(FxHashSet::default());
}
pub fn pop_class_scope(&mut self, declared_private_symbols: impl Iterator<Item = Atom<'a>>) {
let mut used_private_symbols = self.stack.pop();
declared_private_symbols.for_each(|name| {
used_private_symbols.remove(&name);
});
self.stack.last_mut().extend(used_private_symbols);
}
pub fn push_private_member_to_current_class(&mut self, name: Atom<'a>) {
self.stack.last_mut().insert(name);
}
pub fn is_private_member_used_in_current_class(&self, name: &Atom<'a>) -> bool {
self.stack.last().contains(name)
}
}