swc_bundler/
id.rs

1use std::{
2    fmt,
3    sync::atomic::{AtomicU32, Ordering::SeqCst},
4};
5
6use rustc_hash::FxHashMap;
7use swc_atoms::Atom;
8use swc_common::{sync::Lock, FileName, Mark, SyntaxContext, DUMMY_SP};
9use swc_ecma_ast::{Expr, Ident};
10use swc_ecma_utils::ident::IdentLike;
11
12#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub struct ModuleId(u32);
14
15impl fmt::Display for ModuleId {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        fmt::Display::fmt(&self.0, f)
18    }
19}
20
21impl fmt::Debug for ModuleId {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        write!(f, "ModuleId({})", self.0)?;
24        Ok(())
25    }
26}
27
28#[derive(Debug, Default)]
29pub(crate) struct ModuleIdGenerator {
30    v: AtomicU32,
31    /// `(module_id, local_mark, export_mark)`
32    cache: Lock<FxHashMap<FileName, (ModuleId, Mark, Mark)>>,
33}
34
35impl ModuleIdGenerator {
36    pub fn gen(&self, file_name: &FileName) -> (ModuleId, Mark, Mark) {
37        let mut w = self.cache.lock();
38        if let Some(v) = w.get(file_name) {
39            return *v;
40        }
41
42        let id = ModuleId(self.v.fetch_add(1, SeqCst));
43        let local_mark = Mark::fresh(Mark::root());
44        let export_mark = Mark::fresh(Mark::root());
45        let v = (id, local_mark, export_mark);
46        w.insert(file_name.clone(), v);
47        (id, local_mark, export_mark)
48    }
49}
50
51#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
52pub struct Id(Atom, SyntaxContext);
53
54impl fmt::Debug for Id {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        write!(f, "{}{:?}", self.0, self.1)
57    }
58}
59
60impl Id {
61    pub fn new(sym: Atom, ctxt: SyntaxContext) -> Self {
62        Id(sym, ctxt)
63    }
64
65    pub fn sym(&self) -> &Atom {
66        &self.0
67    }
68
69    pub fn ctxt(&self) -> SyntaxContext {
70        self.1
71    }
72
73    pub fn into_ident(self) -> Ident {
74        Ident::new(self.0, DUMMY_SP, self.1)
75    }
76
77    pub fn with_ctxt(mut self, ctxt: SyntaxContext) -> Self {
78        self.1 = ctxt;
79        self
80    }
81}
82
83impl IdentLike for Id {
84    fn from_ident(i: &Ident) -> Self {
85        i.into()
86    }
87
88    fn to_id(&self) -> (Atom, SyntaxContext) {
89        (self.0.clone(), self.1)
90    }
91
92    fn into_id(self) -> (Atom, SyntaxContext) {
93        (self.0, self.1)
94    }
95}
96
97impl From<Ident> for Id {
98    fn from(i: Ident) -> Self {
99        Id(i.sym, i.ctxt)
100    }
101}
102
103impl From<&Ident> for Id {
104    fn from(i: &Ident) -> Self {
105        Id(i.sym.clone(), i.ctxt)
106    }
107}
108
109impl PartialEq<Ident> for Id {
110    fn eq(&self, other: &Ident) -> bool {
111        self.0 == other.sym && self.1 == other.ctxt
112    }
113}
114
115impl PartialEq<Atom> for Id {
116    fn eq(&self, other: &Atom) -> bool {
117        self.0 == *other
118    }
119}
120
121impl From<Id> for Ident {
122    #[inline]
123    fn from(id: Id) -> Self {
124        id.into_ident()
125    }
126}
127
128impl From<Id> for Expr {
129    #[inline]
130    fn from(id: Id) -> Self {
131        id.into_ident().into()
132    }
133}