next_custom_transforms/transforms/
import_analyzer.rs1use rustc_hash::{FxHashMap, FxHashSet};
2use swc_core::{
3 atoms::{atom, Atom, Wtf8Atom},
4 ecma::{
5 ast::{
6 Expr, Id, ImportDecl, ImportNamedSpecifier, ImportSpecifier, MemberExpr, MemberProp,
7 Module,
8 },
9 visit::{noop_visit_type, Visit, VisitWith},
10 },
11};
12
13#[derive(Debug, Default)]
14pub(crate) struct ImportMap {
15 imports: FxHashMap<Id, (Wtf8Atom, Atom)>,
17
18 namespace_imports: FxHashMap<Id, Wtf8Atom>,
19
20 imported_modules: FxHashSet<Wtf8Atom>,
21}
22
23#[allow(unused)]
24impl ImportMap {
25 pub fn is_import(&self, e: &Expr, module: &str, orig_name: &str) -> bool {
27 match e {
28 Expr::Ident(i) => {
29 if let Some((i_src, i_sym)) = self.imports.get(&i.to_id()) {
30 i_src == module && i_sym == orig_name
31 } else {
32 false
33 }
34 }
35
36 Expr::Member(MemberExpr {
37 obj: box Expr::Ident(obj),
38 prop: MemberProp::Ident(prop),
39 ..
40 }) => {
41 if let Some(obj_src) = self.namespace_imports.get(&obj.to_id()) {
42 obj_src == module && prop.sym == *orig_name
43 } else {
44 false
45 }
46 }
47
48 _ => false,
49 }
50 }
51
52 pub fn analyze(m: &Module) -> Self {
53 let mut data = ImportMap::default();
54
55 m.visit_with(&mut Analyzer { data: &mut data });
56
57 data
58 }
59}
60
61struct Analyzer<'a> {
62 data: &'a mut ImportMap,
63}
64
65impl Visit for Analyzer<'_> {
66 noop_visit_type!();
67
68 fn visit_import_decl(&mut self, import: &ImportDecl) {
69 self.data.imported_modules.insert(import.src.value.clone());
70
71 for s in &import.specifiers {
72 let (local, orig_sym) = match s {
73 ImportSpecifier::Named(ImportNamedSpecifier {
74 local, imported, ..
75 }) => match imported {
76 Some(imported) => (local.to_id(), imported.atom().into_owned()),
77 _ => (local.to_id(), local.sym.clone()),
78 },
79 ImportSpecifier::Default(s) => (s.local.to_id(), atom!("default")),
80 ImportSpecifier::Namespace(s) => {
81 self.data
82 .namespace_imports
83 .insert(s.local.to_id(), import.src.value.clone());
84 continue;
85 }
86 };
87
88 self.data
89 .imports
90 .insert(local, (import.src.value.clone(), orig_sym));
91 }
92 }
93}