#![allow(dead_code)] use std::{clone::Clone, cmp::Eq, hash::Hash}; use swc_common::{Span, SyntaxContext, DUMMY_SP}; use swc_ecma_ast::*; use swc_ecma_utils::ident::IdentLike; use swc_ecma_visit::{noop_visit_mut_type, VisitMut}; #[cfg(feature = "concurrent")] pub(crate) type Readonly = std::sync::Arc; #[cfg(not(feature = "concurrent"))] pub(crate) type Readonly = T; const TRACK: bool = false; pub(crate) trait VarDeclaratorExt: Into { fn into_module_item(self, injected_ctxt: SyntaxContext, name: &str) -> ModuleItem { ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl { span: DUMMY_SP.with_ctxt(injected_ctxt), kind: VarDeclKind::Const, declare: false, decls: if TRACK { vec![ self.into(), Str { span: DUMMY_SP, value: name.into(), has_escape: false, kind: Default::default(), } .assign_to(Ident::new("INJECTED_FROM".into(), DUMMY_SP)), ] } else { vec![self.into()] }, }))) } } impl VarDeclaratorExt for T where T: Into {} pub(crate) trait ExprExt: Into { #[track_caller] fn assign_to(self, lhs: T) -> VarDeclarator where T: IdentLike, { let init = self.into(); let lhs = lhs.into_id(); if cfg!(debug_assertions) { match &init { Expr::Ident(rhs) => { debug_assert_ne!(lhs, rhs.to_id()); } _ => {} } } VarDeclarator { span: DUMMY_SP, name: Pat::Ident(Ident::new(lhs.0, DUMMY_SP.with_ctxt(lhs.1)).into()), init: Some(Box::new(init)), definite: false, } } } impl ExprExt for T where T: Into {} #[derive(Debug)] pub(crate) struct CHashSet where V: Eq + Hash, { inner: CloneMap, } impl CHashSet where V: Eq + Hash, { // pub fn insert(&self, v: V) -> bool { // self.inner.insert(v, ()).is_none() // } } impl Default for CHashSet where V: Eq + Hash, { fn default() -> Self { Self { inner: Default::default(), } } } #[derive(Debug)] pub(crate) struct CloneMap where K: Eq + Hash, V: Clone, { #[cfg(feature = "concurrent")] inner: dashmap::DashMap, #[cfg(not(feature = "concurrent"))] inner: std::cell::RefCell>, } impl Default for CloneMap where K: Eq + Hash, V: Clone, { fn default() -> Self { Self { inner: Default::default(), } } } impl CloneMap where K: Eq + Hash, V: Clone, { #[cfg(feature = "concurrent")] pub fn get(&self, k: &K) -> Option { if let Some(v) = self.inner.get(k) { Some(v.value().clone()) } else { None } } #[cfg(not(feature = "concurrent"))] pub fn get(&self, k: &K) -> Option { if let Some(v) = self.inner.borrow().get(k) { Some(v.clone()) } else { None } } #[cfg(feature = "concurrent")] pub fn insert(&self, k: K, v: V) -> Option { self.inner.insert(k, v) } #[cfg(not(feature = "concurrent"))] pub fn insert(&self, k: K, v: V) -> Option { self.inner.borrow_mut().insert(k, v) } } pub(crate) struct HygieneRemover; impl VisitMut for HygieneRemover { noop_visit_mut_type!(); fn visit_mut_span(&mut self, s: &mut Span) { *s = s.with_ctxt(SyntaxContext::empty()) } } #[cfg(feature = "rayon")] pub(crate) use rayon::join; #[cfg(not(feature = "rayon"))] pub(crate) fn join(op_a: A, op_b: B) -> (RA, RB) where A: FnOnce() -> RA, B: FnOnce() -> RB, { (op_a(), op_b()) } #[cfg(feature = "rayon")] pub(crate) use rayon::iter::IntoParallelIterator; /// Fake trait #[cfg(not(feature = "rayon"))] pub(crate) trait IntoParallelIterator: Sized + IntoIterator { fn into_par_iter(self) -> ::IntoIter { self.into_iter() } } #[cfg(not(feature = "rayon"))] impl IntoParallelIterator for T where T: IntoIterator {}