use crate::Loc;
use bun_alloc::AstAlloc;
use bun_collections::StringArrayHashMap;
use bun_collections::array_hash_map::StringContext;
use crate::base::Ref;
use crate::e::String as EString;
pub struct TSNamespaceScope {
pub arg_ref: Ref,
pub exported_members: crate::nodes::StoreRef<TSNamespaceMemberMap>,
pub property_accesses: StringArrayHashMap<Ref, StringContext, AstAlloc>,
pub is_enum_scope: bool,
}
pub type TSNamespaceMemberMap = StringArrayHashMap<TSNamespaceMember, StringContext, AstAlloc>;
pub struct TSNamespaceMember {
pub loc: Loc,
pub data: Data,
}
#[derive(Clone, Copy)]
pub enum Data {
Property,
Namespace(crate::nodes::StoreRef<TSNamespaceMemberMap>),
EnumNumber(f64),
EnumString(crate::nodes::StoreRef<EString>),
EnumProperty,
}
impl Data {
pub fn is_enum(&self) -> bool {
matches!(
self,
Data::EnumNumber(_) | Data::EnumString(_) | Data::EnumProperty
)
}
}
#[derive(Clone, Default)]
pub enum Metadata {
#[default]
MNone,
MNever,
MUnknown,
MAny,
MVoid,
MNull,
MUndefined,
MFunction,
MArray,
MBoolean,
MString,
MObject,
MNumber,
MBigint,
MSymbol,
MPromise,
MIdentifier(Ref),
MDot(Vec<Ref>),
}
impl Metadata {
pub const DEFAULT: Self = Metadata::MNone;
pub fn finish_union<'b, F: Fn(Ref) -> &'b [u8]>(&mut self, load_name: F) -> Option<Self> {
let current = self;
match current {
Metadata::MIdentifier(r) => {
if load_name(*r) == b"Object" {
return Some(Metadata::MObject);
}
None
}
Metadata::MUnknown | Metadata::MAny | Metadata::MObject => Some(Metadata::MObject),
Metadata::MNever | Metadata::MNull | Metadata::MUndefined => {
*current = Metadata::MNone;
None
}
_ => None,
}
}
pub fn merge_union(&mut self, left: Self) {
let result = self;
if !matches!(left, Metadata::MNone) {
if core::mem::discriminant(result) != core::mem::discriminant(&left) {
*result = match result {
Metadata::MNever | Metadata::MUndefined | Metadata::MNull => left,
_ => Metadata::MObject,
};
} else {
if let Metadata::MIdentifier(r) = result {
let r = *r;
if let Metadata::MIdentifier(l) = left {
if !r.eql(l) {
*result = Metadata::MObject;
}
}
}
}
} else {
}
}
pub fn finish_intersection<'b, F: Fn(Ref) -> &'b [u8]>(
&mut self,
load_name: F,
) -> Option<Self> {
let current = self;
match current {
Metadata::MIdentifier(r) => {
if load_name(*r) == b"Object" {
return Some(Metadata::MObject);
}
None
}
Metadata::MNever => Some(Metadata::MNever),
Metadata::MAny | Metadata::MObject => Some(Metadata::MObject),
Metadata::MUnknown | Metadata::MNull | Metadata::MUndefined => {
*current = Metadata::MNone;
None
}
_ => None,
}
}
pub fn merge_intersection(&mut self, left: Self) {
let result = self;
if !matches!(left, Metadata::MNone) {
if core::mem::discriminant(result) != core::mem::discriminant(&left) {
*result = match result {
Metadata::MUnknown | Metadata::MUndefined | Metadata::MNull => left,
Metadata::MNever => Metadata::MNever,
_ => Metadata::MObject,
};
} else {
if let Metadata::MIdentifier(r) = result {
let r = *r;
if let Metadata::MIdentifier(l) = left {
if !r.eql(l) {
*result = Metadata::MObject;
}
}
}
}
} else {
if matches!(result, Metadata::MUnknown) {
*result = Metadata::MUndefined;
}
}
}
}
pub use crate::g::Class;