use oxc_syntax::{
scope::ScopeId,
symbol::{SymbolFlags, SymbolId},
};
use oxc_traverse::BoundIdentifier;
use crate::context::TraverseCtx;
pub(super) struct ClassBindings<'a> {
pub name: Option<BoundIdentifier<'a>>,
pub temp: Option<BoundIdentifier<'a>>,
pub brand: Option<BoundIdentifier<'a>>,
pub outer_hoist_scope_id: ScopeId,
pub static_private_fields_use_temp: bool,
pub temp_var_is_created: bool,
}
impl<'a> ClassBindings<'a> {
pub fn new(
name_binding: Option<BoundIdentifier<'a>>,
temp_binding: Option<BoundIdentifier<'a>>,
brand_binding: Option<BoundIdentifier<'a>>,
outer_scope_id: ScopeId,
static_private_fields_use_temp: bool,
temp_var_is_created: bool,
) -> Self {
Self {
name: name_binding,
temp: temp_binding,
brand: brand_binding,
outer_hoist_scope_id: outer_scope_id,
static_private_fields_use_temp,
temp_var_is_created,
}
}
pub fn dummy() -> Self {
Self::new(None, None, None, ScopeId::new(0), false, false)
}
pub fn name_symbol_id(&self) -> Option<SymbolId> {
self.name.as_ref().map(|binding| binding.symbol_id)
}
pub fn brand(&self) -> &BoundIdentifier<'a> {
self.brand.as_ref().unwrap()
}
pub fn get_or_init_static_binding(
&mut self,
ctx: &mut TraverseCtx<'a>,
) -> &BoundIdentifier<'a> {
if self.static_private_fields_use_temp {
self.temp.get_or_insert_with(|| {
Self::create_temp_binding(self.name.as_ref(), self.outer_hoist_scope_id, ctx)
})
} else {
self.name.as_ref().unwrap()
}
}
pub fn create_temp_binding(
name_binding: Option<&BoundIdentifier<'a>>,
outer_hoist_scope_id: ScopeId,
ctx: &mut TraverseCtx<'a>,
) -> BoundIdentifier<'a> {
let name = name_binding.map_or("Class", |binding| binding.name.as_str());
ctx.generate_uid(name, outer_hoist_scope_id, SymbolFlags::FunctionScopedVariable)
}
}