Skip to main content

stylex_transform/transform/fold/
fold_import_decl.rs

1use swc_core::{
2  common::comments::Comments,
3  ecma::{
4    ast::{ImportDecl, ImportNamedSpecifier, ImportSpecifier, ModuleExportName},
5    utils::drop_span,
6  },
7};
8
9use crate::{StyleXTransform, shared::utils::ast::convertors::convert_atom_to_string};
10use stylex_enums::core::TransformationCycle;
11use stylex_structures::named_import_source::ImportSources;
12
13impl<C> StyleXTransform<C>
14where
15  C: Comments,
16{
17  pub(crate) fn fold_import_decl_impl(&mut self, import_decl: ImportDecl) -> ImportDecl {
18    if self.state.cycle == TransformationCycle::Skip {
19      return import_decl;
20    }
21
22    if self.state.cycle == TransformationCycle::Initializing {
23      if import_decl.type_only {
24        return import_decl;
25      }
26
27      let src = &import_decl.src;
28      let declaration = &src.value;
29
30      let import_sources = self.state.import_sources_stringified();
31
32      self.state.top_imports.push(drop_span(import_decl.clone()));
33
34      let source_path = convert_atom_to_string(&import_decl.src.value);
35
36      for specifier in &import_decl.specifiers {
37        match &specifier {
38          ImportSpecifier::Default(import_specifier) => {
39            let import_specifier_ident = import_specifier.local.clone();
40
41            let import_specifier_string = import_specifier_ident.sym.to_string();
42            if !self
43              .state
44              .import_specifiers
45              .contains(&import_specifier_string)
46            {
47              self.state.import_specifiers.push(import_specifier_string);
48            }
49
50            if import_sources.contains(&convert_atom_to_string(declaration))
51              && self
52                .state
53                .import_as(&convert_atom_to_string(&import_decl.src.value))
54                .is_none()
55            {
56              let local_name = import_specifier.local.sym.to_string();
57
58              self.state.import_paths.insert(source_path.clone());
59
60              self
61                .state
62                .stylex_import
63                .insert(ImportSources::Regular(local_name));
64            }
65          },
66          ImportSpecifier::Namespace(import_specifier) => {
67            let import_specifier_ident = import_specifier.local.clone();
68
69            let import_specifier_string = import_specifier_ident.sym.to_string();
70
71            if !self
72              .state
73              .import_specifiers
74              .contains(&import_specifier_string)
75            {
76              self.state.import_specifiers.push(import_specifier_string);
77            }
78
79            if import_sources.contains(&convert_atom_to_string(declaration))
80              && self
81                .state
82                .import_as(&convert_atom_to_string(&import_decl.src.value))
83                .is_none()
84            {
85              let local_name = import_specifier.local.sym.to_string();
86
87              self.state.import_paths.insert(source_path.clone());
88
89              self
90                .state
91                .stylex_import
92                .insert(ImportSources::Regular(local_name));
93            }
94          },
95          ImportSpecifier::Named(import_specifier) => {
96            let import_specifier_ident = import_specifier.local.clone();
97
98            let import_specifier_string = import_specifier_ident.sym.to_string();
99
100            if !self
101              .state
102              .import_specifiers
103              .contains(&import_specifier_string)
104            {
105              self.state.import_specifiers.push(import_specifier_string);
106            }
107
108            if import_sources.contains(&convert_atom_to_string(declaration)) {
109              let local_name = import_specifier.local.sym.to_string();
110
111              match &import_specifier.imported {
112                Some(imported) => {
113                  let imported_name = match imported {
114                    ModuleExportName::Ident(ident) => ident.sym.to_string(),
115                    ModuleExportName::Str(strng) => convert_atom_to_string(&strng.value),
116                  };
117
118                  self.fill_stylex_create_import(
119                    &source_path,
120                    imported_name,
121                    &local_name,
122                    import_specifier,
123                  );
124                },
125                None => {
126                  let imported_name = import_specifier.local.sym.to_string();
127
128                  self.fill_stylex_create_import(
129                    &source_path,
130                    imported_name,
131                    &local_name,
132                    import_specifier,
133                  );
134                },
135              }
136            }
137          },
138        };
139      }
140
141      import_decl
142    } else {
143      import_decl
144    }
145  }
146
147  fn fill_stylex_create_import(
148    &mut self,
149    source_path: &str,
150    imported_name: String,
151    local_name: &str,
152    import_specifier: &ImportNamedSpecifier,
153  ) {
154    if let Some(source_path) = self.state.import_as(source_path)
155      && source_path.eq(&imported_name)
156    {
157      self.state.import_paths.insert(source_path.clone());
158
159      self
160        .state
161        .stylex_import
162        .insert(ImportSources::Regular(local_name.to_string()));
163    }
164
165    if self.state.import_as(source_path).is_none() {
166      self.state.import_paths.insert(source_path.to_string());
167
168      let local_name_ident_atom = import_specifier.local.clone().sym;
169
170      match imported_name.as_str() {
171        "create" => {
172          self
173            .state
174            .stylex_create_import
175            .insert(local_name_ident_atom);
176        },
177        "props" => {
178          self.state.stylex_props_import.insert(local_name_ident_atom);
179        },
180        "attrs" => {
181          self.state.stylex_attrs_import.insert(local_name_ident_atom);
182        },
183        "keyframes" => {
184          self
185            .state
186            .stylex_keyframes_import
187            .insert(local_name_ident_atom);
188        },
189        "firstThatWorks" => {
190          self
191            .state
192            .stylex_first_that_works_import
193            .insert(local_name_ident_atom);
194        },
195        "defineVars" => {
196          self
197            .state
198            .stylex_define_vars_import
199            .insert(local_name_ident_atom);
200        },
201        "defineConsts" => {
202          self
203            .state
204            .stylex_define_consts_import
205            .insert(local_name_ident_atom);
206        },
207        "defineMarker" => {
208          self
209            .state
210            .stylex_define_marker_import
211            .insert(local_name_ident_atom);
212        },
213        "createTheme" => {
214          self
215            .state
216            .stylex_create_theme_import
217            .insert(local_name_ident_atom);
218        },
219        "positionTry" => {
220          self
221            .state
222            .stylex_position_try_import
223            .insert(local_name_ident_atom);
224        },
225        "viewTransitionClass" => {
226          self
227            .state
228            .stylex_view_transition_class_import
229            .insert(local_name_ident_atom);
230        },
231        "types" => {
232          self.state.stylex_types_import.insert(local_name_ident_atom);
233        },
234        "when" => {
235          self.state.stylex_when_import.insert(local_name_ident_atom);
236        },
237        "env" => {
238          self.state.stylex_env_import.insert(local_name_ident_atom);
239        },
240        "defaultMarker" => {
241          self
242            .state
243            .stylex_default_marker_import
244            .insert(local_name_ident_atom);
245        },
246        _ => {},
247      }
248    }
249  }
250}