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> {}