swc_ecma_preset_env/corejs3/
builtin.rs

1use std::fmt;
2
3use crate::util::{PooledStr, SwcFold};
4
5#[derive(Clone, Copy)]
6pub(crate) struct CoreJSPolyfillDescriptor {
7    name: u32,
8    pure: u32,
9    global: u32,
10    exclude: u32,
11}
12
13include!(concat!(env!("OUT_DIR"), "/corejs3_builtin/lib.rs"));
14
15pub struct StaticProperty(&'static [(PooledStr, (u32, u32, u32, u32))]);
16
17pub fn builtin_types_get(query: &str) -> Option<CoreJSPolyfillDescriptor> {
18    let idx = BUILTIN_INDEX.get(query)?;
19    let (name, pure, global, exclude) = BUILTINS_VALUES[idx];
20    Some(CoreJSPolyfillDescriptor {
21        pure,
22        global,
23        name,
24        exclude,
25    })
26}
27
28pub fn instance_properties_get(query: &str) -> Option<CoreJSPolyfillDescriptor> {
29    let idx = INSTRANCE_PROPS_INDEX.get(query)?;
30    let (name, pure, global, exclude) = INSTRANCE_PROPS_VALUES[idx];
31    Some(CoreJSPolyfillDescriptor {
32        pure,
33        global,
34        name,
35        exclude,
36    })
37}
38
39pub fn static_properties_get(query: &str) -> Option<StaticProperty> {
40    let idx = STATIC_PROPS_INDEX.get(query)?;
41    let (start, end) = STATIC_PROPS_LIST[idx];
42    Some(StaticProperty(
43        &STATIC_PROPS_STORE[start as usize..end as usize],
44    ))
45}
46
47impl StaticProperty {
48    pub fn get(&self, query: &str) -> Option<CoreJSPolyfillDescriptor> {
49        let idx = self
50            .0
51            .binary_search_by_key(&query, |(k, ..)| k.as_str())
52            .ok()?;
53        let (_, (name, pure, global, exclude)) = self.0[idx];
54        Some(CoreJSPolyfillDescriptor {
55            pure,
56            global,
57            name,
58            exclude,
59        })
60    }
61}
62
63impl CoreJSPolyfillDescriptor {
64    pub fn name(&self) -> &'static str {
65        PooledStr(self.name).as_str()
66    }
67
68    pub fn pure(&self) -> Option<&'static str> {
69        (self.pure != 0).then(|| PooledStr(self.pure).as_str())
70    }
71
72    pub fn global(&self) -> impl ExactSizeIterator<Item = &'static str> {
73        use precomputed_map::store::AccessSeq;
74
75        let (offset, len) = unpack_store(self.global);
76        (offset..offset + len)
77            .map(|idx| GlobalStore::index(idx).unwrap())
78            .map(|idx| PooledStr(idx).as_str())
79    }
80
81    pub fn exclude(&self) -> impl ExactSizeIterator<Item = &'static str> {
82        use precomputed_map::store::AccessSeq;
83
84        let (offset, len) = unpack_store(self.exclude);
85        (offset..offset + len)
86            .map(|idx| ExcludeStore::index(idx).unwrap())
87            .map(|idx| PooledStr(idx).as_str())
88    }
89}
90
91pub fn common_iterators() -> impl ExactSizeIterator<Item = &'static str> {
92    COMMON_ITERATORS.iter().map(|s| s.as_str())
93}
94
95pub fn promise_dependencies() -> impl ExactSizeIterator<Item = &'static str> {
96    PROMISE_DEPENDENCIES.iter().map(|s| s.as_str())
97}
98
99fn unpack_store(id: u32) -> (usize, usize) {
100    let offset = id & ((1 << 24) - 1);
101    let len = id >> 24;
102    (offset as usize, len as usize)
103}
104
105impl fmt::Debug for CoreJSPolyfillDescriptor {
106    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107        f.debug_struct("CoreJSPolyfillDescriptor")
108            .field("name", &self.name())
109            .finish_non_exhaustive()
110    }
111}