swc_plugin/
pseudo_scoped_key.rs

1use once_cell::sync::OnceCell;
2
3/// Simple substitution for scoped_thread_local with limited interface parity.
4///
5/// The only available fn in this struct is `with`, which is being used for the
6/// consumers when they need to access global scope handler (HANDLER.with()).
7/// Any other interfaces to support thread local is not available.
8pub struct PseudoScopedKey<T> {
9    // As we can't use scoped_thread_local for the global HANDLER, it is challenging
10    // to set its inner handler for each plugin scope's diagnostic emitter.
11    // Via lazy init OnceCell we keep static HANDLER as immutable, also allows to set
12    // plugin specific values when proc_macro expands plugin's transform helper.
13    pub inner: OnceCell<T>,
14}
15
16impl<T> PseudoScopedKey<T> {
17    pub fn with<F, R>(&self, f: F) -> R
18    where
19        F: FnOnce(&T) -> R,
20    {
21        f(self.inner.get().expect("Should set handler before call"))
22    }
23}
24
25// This is to conform some of swc_common::errors::Handler's thread-safety
26// required properties.
27//
28// NOTE: This only works cause we know each plugin transform doesn't need any
29// thread safety. However, if wasm gets thread support and if we're going to
30// support it this should be revisited.
31unsafe impl<T> std::marker::Sync for PseudoScopedKey<T> {}