Skip to content

Commit 1c49ef5

Browse files
committed
enum for reference
1 parent 8fff786 commit 1c49ef5

File tree

8 files changed

+117
-57
lines changed

8 files changed

+117
-57
lines changed

crates/swc_ecma_minifier/src/compress/optimize/iife.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ impl Optimizer<'_> {
225225
param.id.sym,
226226
param.id.ctxt
227227
);
228+
debug_assert!(param.node_id != NodeId::DUMMY);
228229
vars.insert(param.node_id, arg.clone());
229230
} else {
230231
trace_op!(
@@ -240,6 +241,7 @@ impl Optimizer<'_> {
240241
param.id.ctxt
241242
);
242243

244+
debug_assert!(param.node_id != NodeId::DUMMY);
243245
vars.insert(param.node_id, Expr::undefined(param.span()));
244246
}
245247
}
@@ -268,6 +270,7 @@ impl Optimizer<'_> {
268270
continue;
269271
}
270272

273+
debug_assert!(param_id.node_id != NodeId::DUMMY);
271274
vars.insert(
272275
param_id.node_id,
273276
ArrayLit {

crates/swc_ecma_minifier/src/compress/optimize/inline.rs

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
22
use swc_atoms::atom;
33
use swc_common::{util::take::Take, EqIgnoreSpan, Mark, NodeId};
44
use swc_ecma_ast::*;
5+
use swc_ecma_transforms_base::resolve::RefTo;
56
use swc_ecma_usage_analyzer::alias::{collect_infects_from, AliasConfig};
67
use swc_ecma_utils::{
78
class_has_side_effect, collect_decls, contains_this_expr, find_pat_ids, ExprExt, Remapper,
@@ -212,17 +213,21 @@ impl Optimizer<'_> {
212213
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => false,
213214

214215
Expr::Ident(id) if !id.eq_ignore_span(ident) => {
215-
let node_id = self.r.find_binding_by_ident(id);
216-
debug_assert!(id.node_id != node_id);
216+
let node_id = match self.r.find_binding_by_ident(id) {
217+
RefTo::Binding(node_id) => Some(node_id),
218+
RefTo::Unresolved => None,
219+
RefTo::Itself => unreachable!(),
220+
};
217221

218222
if !usage.flags.contains(VarUsageInfoFlags::ASSIGNED_FN_LOCAL) {
219223
false
220-
} else if let Some(u) = self.data.vars.get(&node_id) {
221-
let mut should_inline =
222-
!u.flags.contains(VarUsageInfoFlags::REASSIGNED)
223-
&& u.flags.contains(VarUsageInfoFlags::DECLARED);
224+
} else if let Some(node_id) = node_id {
225+
if let Some(u) = self.data.vars.get(&node_id) {
226+
let mut should_inline =
227+
!u.flags.contains(VarUsageInfoFlags::REASSIGNED)
228+
&& u.flags.contains(VarUsageInfoFlags::DECLARED);
224229

225-
should_inline &=
230+
should_inline &=
226231
// Function declarations are hoisted
227232
//
228233
// As we copy expressions, this can cause a problem.
@@ -233,33 +238,36 @@ impl Optimizer<'_> {
233238
|| !u.flags.contains(VarUsageInfoFlags::DECLARED_AS_FN_DECL)
234239
|| usage.callee_count == 0;
235240

236-
if u.flags.contains(VarUsageInfoFlags::DECLARED_AS_FOR_INIT)
237-
&& !usage.flags.contains(VarUsageInfoFlags::IS_FN_LOCAL)
238-
{
239-
should_inline &= !matches!(
240-
u.var_kind,
241-
Some(VarDeclKind::Let | VarDeclKind::Const)
242-
)
243-
}
244-
245-
if u.flags.intersects(
246-
VarUsageInfoFlags::DECLARED_AS_FN_DECL
247-
.union(VarUsageInfoFlags::DECLARED_AS_FN_EXPR),
248-
) {
249-
if self.options.keep_fnames
250-
|| self.mangle_options.is_some_and(|v| v.keep_fn_names)
241+
if u.flags.contains(VarUsageInfoFlags::DECLARED_AS_FOR_INIT)
242+
&& !usage.flags.contains(VarUsageInfoFlags::IS_FN_LOCAL)
251243
{
252-
should_inline = false
244+
should_inline &= !matches!(
245+
u.var_kind,
246+
Some(VarDeclKind::Let | VarDeclKind::Const)
247+
)
253248
}
254-
}
255249

256-
if u.flags.contains(VarUsageInfoFlags::DECLARED_AS_FN_EXPR) {
257-
if self.options.inline != 3 {
258-
return;
250+
if u.flags.intersects(
251+
VarUsageInfoFlags::DECLARED_AS_FN_DECL
252+
.union(VarUsageInfoFlags::DECLARED_AS_FN_EXPR),
253+
) {
254+
if self.options.keep_fnames
255+
|| self.mangle_options.is_some_and(|v| v.keep_fn_names)
256+
{
257+
should_inline = false
258+
}
259+
}
260+
261+
if u.flags.contains(VarUsageInfoFlags::DECLARED_AS_FN_EXPR) {
262+
if self.options.inline != 3 {
263+
return;
264+
}
259265
}
260-
}
261266

262-
should_inline
267+
should_inline
268+
} else {
269+
false
270+
}
263271
} else {
264272
false
265273
}
@@ -319,7 +327,11 @@ impl Optimizer<'_> {
319327
} = **usage;
320328
let mut inc_usage = || {
321329
if let Expr::Ident(i) = &*init {
322-
let node_id = self.r.find_binding_by_ident(i);
330+
let node_id = match self.r.find_binding_by_ident(i) {
331+
RefTo::Binding(node_id) => node_id,
332+
RefTo::Unresolved => return,
333+
RefTo::Itself => unreachable!(),
334+
};
323335
debug_assert!(i.node_id != node_id);
324336
if let Some(u) = self.data.vars.get_mut(&node_id) {
325337
u.flags |= flags & VarUsageInfoFlags::USED_AS_ARG;
@@ -470,8 +482,11 @@ impl Optimizer<'_> {
470482

471483
Expr::Object(..) if self.options.pristine_globals => {
472484
for id in idents_used_by_ignoring_nested(init) {
473-
let node_id = self.r.find_binding_by_node_id(id);
474-
debug_assert!(node_id != id);
485+
let node_id = match self.r.find_binding_by_node_id(id) {
486+
RefTo::Binding(node_id) => node_id,
487+
RefTo::Unresolved => continue,
488+
RefTo::Itself => unreachable!(),
489+
};
475490
if let Some(v_usage) = self.data.vars.get(&id) {
476491
if v_usage.flags.contains(VarUsageInfoFlags::REASSIGNED) {
477492
return;
@@ -518,8 +533,11 @@ impl Optimizer<'_> {
518533

519534
_ => {
520535
for id in idents_used_by(init) {
521-
let node_id = self.r.find_binding_by_node_id(id);
522-
debug_assert!(node_id != id);
536+
let node_id = match self.r.find_binding_by_node_id(id) {
537+
RefTo::Binding(node_id) => node_id,
538+
RefTo::Unresolved => continue,
539+
RefTo::Itself => unreachable!(),
540+
};
523541
if let Some(v_usage) = self.data.vars.get(&node_id) {
524542
if v_usage.property_mutation_count > usage.property_mutation_count
525543
|| v_usage.flags.intersects(
@@ -901,8 +919,11 @@ impl Optimizer<'_> {
901919
}
902920
}
903921
Expr::Ident(i) => {
904-
let node_id = self.r.find_binding_by_ident(i);
905-
debug_assert!(i.node_id != node_id);
922+
let node_id = match self.r.find_binding_by_ident(i) {
923+
RefTo::Binding(node_id) => node_id,
924+
RefTo::Unresolved => return,
925+
RefTo::Itself => unreachable!(),
926+
};
906927

907928
if let Some(mut value) = self
908929
.vars

crates/swc_ecma_minifier/src/compress/optimize/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use rustc_hash::{FxHashMap, FxHashSet};
77
use swc_atoms::Atom;
88
use swc_common::{pass::Repeated, util::take::Take, NodeId, Spanned, SyntaxContext, DUMMY_SP};
99
use swc_ecma_ast::*;
10-
use swc_ecma_transforms_base::{rename::contains_eval, resolve::Resolver};
10+
use swc_ecma_transforms_base::{
11+
rename::contains_eval,
12+
resolve::{RefTo, Resolver},
13+
};
1114
use swc_ecma_transforms_optimization::debug_assert_valid;
1215
use swc_ecma_usage_analyzer::{analyzer::UsageAnalyzer, marks::Marks};
1316
use swc_ecma_utils::{
@@ -349,9 +352,10 @@ impl Optimizer<'_> {
349352
return false;
350353
}
351354

352-
if self.r.find_binding_by_ident(id) != NodeId::DUMMY {
353-
return true;
354-
}
355+
match self.r.find_binding_by_ident(id) {
356+
RefTo::Itself | RefTo::Binding(_) => return true,
357+
_ => {}
358+
};
355359

356360
if id.ctxt != self.marks.top_level_ctxt {
357361
return true;

crates/swc_ecma_minifier/src/compress/optimize/util.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use swc_common::{util::take::Take, Mark, NodeId, SyntaxContext, DUMMY_SP};
99
use swc_ecma_ast::*;
1010
use swc_ecma_transforms_base::{
1111
perf::{Parallel, ParallelExt},
12-
resolve::Resolver,
12+
resolve::{RefTo, Resolver},
1313
};
1414
use swc_ecma_utils::{collect_decls, ExprCtx, ExprExt, Remapper};
1515
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
@@ -521,7 +521,11 @@ impl VisitMut for NormalMultiReplacer<'_> {
521521
}
522522

523523
if let Expr::Ident(i) = e {
524-
let node_id = self.r.find_binding_by_ident(i);
524+
let node_id = match self.r.find_binding_by_ident(i) {
525+
RefTo::Binding(node_id) => node_id,
526+
RefTo::Unresolved => return,
527+
RefTo::Itself => unreachable!(),
528+
};
525529
if let Some(new) = self.var(&node_id) {
526530
debug!("multi-replacer: Replaced `{}`", i);
527531
self.changed = true;

crates/swc_ecma_minifier/src/program_data.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ impl Storage for ProgramData {
217217
}
218218

219219
fn var_or_default(&mut self, id: NodeId) -> &mut Self::VarData {
220+
debug_assert!(id != NodeId::DUMMY);
220221
self.vars.entry(id).or_default()
221222
}
222223

@@ -235,6 +236,7 @@ impl Storage for ProgramData {
235236
for (id, mut var_info) in child.vars {
236237
// trace!("merge({:?},{}{:?})", kind, id.0, id.1);
237238
let inited = self.initialized_vars.contains(&id);
239+
debug_assert!(id != NodeId::DUMMY);
238240
match self.vars.entry(id) {
239241
Entry::Occupied(mut e) => {
240242
if var_info.flags.contains(VarUsageInfoFlags::INLINE_PREVENTED) {
@@ -367,6 +369,7 @@ impl Storage for ProgramData {
367369
fn report_usage(&mut self, ctx: Ctx, i: NodeId) {
368370
let inited = self.initialized_vars.contains(&i);
369371

372+
debug_assert!(i != NodeId::DUMMY);
370373
let e = self.vars.entry(i).or_insert_with(|| {
371374
let mut default = VarUsageInfo::default();
372375
default.flags.insert(VarUsageInfoFlags::USED_ABOVE_DECL);
@@ -395,6 +398,7 @@ impl Storage for ProgramData {
395398
}
396399

397400
fn report_assign(&mut self, ctx: Ctx, i: NodeId, is_op: bool, ty: Value<Type>) {
401+
debug_assert!(i != NodeId::DUMMY);
398402
let e = self.vars.entry(i).or_default();
399403

400404
let inited = self.initialized_vars.contains(&i);
@@ -545,6 +549,7 @@ impl Storage for ProgramData {
545549
.collect::<Vec<_>>();
546550

547551
for other in to_mark_mutate {
552+
debug_assert!(other != NodeId::DUMMY);
548553
let other = self.vars.entry(other).or_default();
549554

550555
other.property_mutation_count += 1;

crates/swc_ecma_transforms_base/src/resolve/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use swc_common::NodeId;
66
use swc_ecma_ast::*;
77
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
88

9-
use crate::resolve::{
9+
pub use self::reference::RefTo;
10+
use self::{
1011
reference::ReferenceMap,
1112
scope::{ScopeArena, ScopeId},
1213
};
@@ -44,11 +45,11 @@ pub fn name_resolution(root: &mut impl VisitMutWith<Resolver>) -> Resolver {
4445
}
4546

4647
impl Resolver {
47-
pub fn find_binding_by_node_id(&self, id: NodeId) -> NodeId {
48+
pub fn find_binding_by_node_id(&self, id: NodeId) -> RefTo {
4849
self.references.get_binding(id)
4950
}
5051

51-
pub fn find_binding_by_ident(&self, ident: &Ident) -> NodeId {
52+
pub fn find_binding_by_ident(&self, ident: &Ident) -> RefTo {
5253
self.references.get_binding(ident.node_id)
5354
}
5455
}
@@ -81,7 +82,7 @@ impl Resolver {
8182
let id = self.next_node_id();
8283
debug_assert!(node.node_id == NodeId::DUMMY);
8384
node.node_id = id;
84-
self.references.add_reference(id, NodeId::DUMMY);
85+
self.references.add_unresolved_reference(id);
8586
}
8687

8788
fn lookup_binding(&mut self, name: &Atom, scope: ScopeId) -> Option<NodeId> {

crates/swc_ecma_transforms_base/src/resolve/reference.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,33 @@
11
use swc_common::NodeId;
22

33
#[derive(Debug, Default)]
4-
pub(super) struct ReferenceMap(Vec<NodeId>);
4+
pub(super) struct ReferenceMap(Vec<RefTo>);
5+
6+
#[derive(Debug, Clone, Copy)]
7+
pub enum RefTo {
8+
Unresolved,
9+
Itself,
10+
Binding(NodeId),
11+
}
512

613
impl ReferenceMap {
714
pub(super) fn add_binding(&mut self, id: NodeId) {
815
debug_assert!(self.0.len() == id.as_u32() as usize);
9-
self.0.push(id);
16+
self.0.push(RefTo::Itself);
1017
}
1118

1219
pub(super) fn add_reference(&mut self, from: NodeId, to: NodeId) {
1320
debug_assert!(self.0.len() == from.as_u32() as usize);
14-
self.0.push(to);
21+
debug_assert!(from != to);
22+
self.0.push(RefTo::Binding(to));
23+
}
24+
25+
pub(super) fn add_unresolved_reference(&mut self, from: NodeId) {
26+
debug_assert!(self.0.len() == from.as_u32() as usize);
27+
self.0.push(RefTo::Unresolved);
1528
}
1629

17-
pub(super) fn get_binding(&self, id: NodeId) -> NodeId {
30+
pub(super) fn get_binding(&self, id: NodeId) -> RefTo {
1831
debug_assert!(
1932
(id.as_u32() as usize) < self.0.len(),
2033
"id: {id:#?}, self.0.len(): {}",

crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use ctx::BitContext;
22
use rustc_hash::FxHashMap;
33
use swc_common::{NodeId, SyntaxContext};
44
use swc_ecma_ast::*;
5-
use swc_ecma_transforms_base::resolve::Resolver;
5+
use swc_ecma_transforms_base::resolve::{RefTo, Resolver};
66
use swc_ecma_utils::{find_pat_ids, ExprCtx, ExprExt, IsEmpty, StmtExt, Type, Value};
77
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
88
use swc_timer::timer;
@@ -159,8 +159,11 @@ where
159159
self.scope.mark_used_arguments();
160160
}
161161

162-
let node_id = self.r.find_binding_by_ident(i);
163-
debug_assert!(i.node_id != node_id);
162+
let node_id = match self.r.find_binding_by_ident(i) {
163+
RefTo::Binding(node_id) => node_id,
164+
RefTo::Unresolved => return,
165+
RefTo::Itself => unreachable!(),
166+
};
164167

165168
if let Some(recr) = self.used_recursively.get(&node_id) {
166169
if let RecursiveUsage::Var { can_ignore: false } = recr {
@@ -502,8 +505,11 @@ where
502505

503506
for arg in &n.args {
504507
for_each_id_ref_in_expr(&arg.expr, &mut |arg| {
505-
let node_id = self.r.find_binding_by_ident(arg);
506-
debug_assert!(arg.node_id != node_id);
508+
let node_id = match self.r.find_binding_by_ident(arg) {
509+
RefTo::Binding(node_id) => node_id,
510+
RefTo::Unresolved => return,
511+
RefTo::Itself => unreachable!(),
512+
};
507513
self.data.var_or_default(node_id).mark_used_as_arg();
508514
})
509515
}
@@ -1034,8 +1040,11 @@ where
10341040
}
10351041

10361042
for_each_id_ref_in_expr(&e.obj, &mut |obj| {
1037-
let node_id = self.r.find_binding_by_ident(obj);
1038-
debug_assert!(obj.node_id != node_id);
1043+
let node_id = match self.r.find_binding_by_ident(obj) {
1044+
RefTo::Binding(node_id) => node_id,
1045+
RefTo::Unresolved => return,
1046+
RefTo::Itself => unreachable!(),
1047+
};
10391048
let v = self.data.var_or_default(node_id);
10401049
v.mark_has_property_access();
10411050

0 commit comments

Comments
 (0)