swc_plugin_proxy/metadata/
transform_plugin_metadata.rs

1#[cfg(feature = "__plugin_mode")]
2use swc_common::Mark;
3#[cfg(feature = "__plugin_mode")]
4use swc_trace_macro::swc_trace;
5
6#[cfg(all(feature = "__rkyv", feature = "__plugin_mode", target_arch = "wasm32"))]
7use crate::memory_interop::read_returned_result_from_host;
8#[cfg(feature = "__plugin_mode")]
9#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
10use crate::{PluginCommentsProxy, PluginSourceMapProxy};
11
12/// An arbitary metadata for given Program to run transform in plugin.
13/// These are not directly attached to Program's AST structures
14/// but required for certain transforms.
15#[cfg(feature = "__plugin_mode")]
16#[derive(Debug)]
17pub struct TransformPluginProgramMetadata {
18    /// Proxy to the comments for the Program passed into plugin.
19    /// This is a proxy to the actual data lives in the host. Only when plugin
20    /// attempts to read these it'll ask to the host to get values.
21    pub comments: Option<PluginCommentsProxy>,
22    /// Proxy to the sourceMap for the Program passed into plugin.
23    /// This is a proxy to the actual data lives in the host. Only when plugin
24    /// attempts to read these it'll ask to the host to get values.
25    pub source_map: PluginSourceMapProxy,
26    pub unresolved_mark: Mark,
27}
28
29#[cfg(target_arch = "wasm32")] // Allow testing
30extern "C" {
31    fn __copy_context_key_to_host_env(bytes_ptr: u32, bytes_ptr_len: u32);
32    fn __get_transform_plugin_config(allocated_ret_ptr: u32) -> u32;
33    fn __get_transform_context(key: u32, allocated_ret_ptr: u32) -> i32;
34    fn __get_experimental_transform_context(allocated_ret_ptr: u32) -> u32;
35    fn __get_raw_experiemtal_transform_context(allocated_ret_ptr: u32) -> u32;
36}
37
38#[cfg(feature = "__plugin_mode")]
39#[swc_trace]
40impl TransformPluginProgramMetadata {
41    /// Returns current plugin's configuration as a JSON string.
42    /// Plugin may need to deserialize this string manually.
43    pub fn get_transform_plugin_config(&self) -> Option<String> {
44        #[cfg(target_arch = "wasm32")]
45        return read_returned_result_from_host(|serialized_ptr| unsafe {
46            __get_transform_plugin_config(serialized_ptr)
47        });
48
49        #[cfg(not(target_arch = "wasm32"))]
50        None
51    }
52
53    /// Returns metadata value for given key.
54    #[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
55    pub fn get_context(
56        &self,
57        key: &swc_common::plugin::metadata::TransformPluginMetadataContextKind,
58    ) -> Option<String> {
59        #[cfg(target_arch = "wasm32")]
60        return read_returned_result_from_host(|serialized_ptr| unsafe {
61            __get_transform_context(*key as u32, serialized_ptr) as u32
62        });
63
64        #[cfg(not(target_arch = "wasm32"))]
65        None
66    }
67
68    /// Returns an experimental metadata value if exists. Returned value is
69    /// always a String, but depends on the nature of the metadata it may
70    /// require additional postprocessing.
71    ///
72    /// Each time this is called, it'll require a call between host-plugin which
73    /// involves serialization / deserialization.
74    ///
75    /// Note these metadata values can be changed anytime. There is no gaurantee
76    /// values will be available across different @swc/core versions.
77    #[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
78    pub fn get_experimental_context(&self, key: &str) -> Option<String> {
79        #[cfg(target_arch = "wasm32")]
80        return read_returned_result_from_host(|serialized_ptr| unsafe {
81            let serialized = swc_common::plugin::serialized::PluginSerializedBytes::try_serialize(
82                &swc_common::plugin::serialized::VersionedSerializable::new(key.to_string()),
83            )
84            .expect("Should be serializable");
85            let (key_ptr, key_ptr_len) = serialized.as_ptr();
86            __copy_context_key_to_host_env(key_ptr as u32, key_ptr_len as u32);
87
88            __get_experimental_transform_context(serialized_ptr)
89        });
90
91        #[cfg(not(target_arch = "wasm32"))]
92        None
93    }
94
95    /// Returns experimental metadata context, but returns whole value as a
96    /// HashMap.
97    ///
98    /// Each time this is called, it'll require a call between host-plugin which
99    /// involves serialization / deserialization.
100    #[allow(unreachable_code)]
101    pub fn get_raw_experimental_context(&self) -> rustc_hash::FxHashMap<String, String> {
102        // TODO: There is no clear usecase yet - enable when we have a correct usecase.
103        unimplemented!("Not supported yet");
104
105        #[cfg(target_arch = "wasm32")]
106        return read_returned_result_from_host(|serialized_ptr| unsafe {
107            __get_raw_experiemtal_transform_context(serialized_ptr)
108        })
109        .expect("Raw experimental metadata should exists, even if it's empty map");
110
111        #[cfg(not(target_arch = "wasm32"))]
112        rustc_hash::FxHashMap::default()
113    }
114}