Skip to content

Commit 956bfaf

Browse files
committed
enum for reference
1 parent 1bcf10a commit 956bfaf

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
@@ -4,6 +4,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
44
use swc_atoms::atom;
55
use swc_common::{util::take::Take, EqIgnoreSpan, Mark, NodeId};
66
use swc_ecma_ast::*;
7+
use swc_ecma_transforms_base::resolve::RefTo;
78
use swc_ecma_usage_analyzer::alias::{collect_infects_from, AliasConfig};
89
use swc_ecma_utils::{
910
class_has_side_effect, collect_decls, contains_this_expr, find_pat_ids, ExprExt, Remapper,
@@ -214,17 +215,21 @@ impl Optimizer<'_> {
214215
Expr::Ident(Ident { sym, .. }) if &**sym == "eval" => false,
215216

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

220224
if !usage.flags.contains(VarUsageInfoFlags::ASSIGNED_FN_LOCAL) {
221225
false
222-
} else if let Some(u) = self.data.vars.get(&node_id) {
223-
let mut should_inline =
224-
!u.flags.contains(VarUsageInfoFlags::REASSIGNED)
225-
&& u.flags.contains(VarUsageInfoFlags::DECLARED);
226+
} else if let Some(node_id) = node_id {
227+
if let Some(u) = self.data.vars.get(&node_id) {
228+
let mut should_inline =
229+
!u.flags.contains(VarUsageInfoFlags::REASSIGNED)
230+
&& u.flags.contains(VarUsageInfoFlags::DECLARED);
226231

227-
should_inline &=
232+
should_inline &=
228233
// Function declarations are hoisted
229234
//
230235
// As we copy expressions, this can cause a problem.
@@ -235,33 +240,36 @@ impl Optimizer<'_> {
235240
|| !u.flags.contains(VarUsageInfoFlags::DECLARED_AS_FN_DECL)
236241
|| usage.callee_count == 0;
237242

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

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

264-
should_inline
269+
should_inline
270+
} else {
271+
false
272+
}
265273
} else {
266274
false
267275
}
@@ -321,7 +329,11 @@ impl Optimizer<'_> {
321329
} = **usage;
322330
let mut inc_usage = || {
323331
if let Expr::Ident(i) = &*init {
324-
let node_id = self.r.find_binding_by_ident(i);
332+
let node_id = match self.r.find_binding_by_ident(i) {
333+
RefTo::Binding(node_id) => node_id,
334+
RefTo::Unresolved => return,
335+
RefTo::Itself => unreachable!(),
336+
};
325337
debug_assert!(i.node_id != node_id);
326338
if let Some(u) = self.data.vars.get_mut(&node_id) {
327339
u.flags |= flags & VarUsageInfoFlags::USED_AS_ARG;
@@ -472,8 +484,11 @@ impl Optimizer<'_> {
472484

473485
Expr::Object(..) if self.options.pristine_globals => {
474486
for id in idents_used_by_ignoring_nested(init) {
475-
let node_id = self.r.find_binding_by_node_id(id);
476-
debug_assert!(node_id != id);
487+
let node_id = match self.r.find_binding_by_node_id(id) {
488+
RefTo::Binding(node_id) => node_id,
489+
RefTo::Unresolved => continue,
490+
RefTo::Itself => unreachable!(),
491+
};
477492
if let Some(v_usage) = self.data.vars.get(&id) {
478493
if v_usage.flags.contains(VarUsageInfoFlags::REASSIGNED) {
479494
return;
@@ -520,8 +535,11 @@ impl Optimizer<'_> {
520535

521536
_ => {
522537
for id in idents_used_by(init) {
523-
let node_id = self.r.find_binding_by_node_id(id);
524-
debug_assert!(node_id != id);
538+
let node_id = match self.r.find_binding_by_node_id(id) {
539+
RefTo::Binding(node_id) => node_id,
540+
RefTo::Unresolved => continue,
541+
RefTo::Itself => unreachable!(),
542+
};
525543
if let Some(v_usage) = self.data.vars.get(&node_id) {
526544
if v_usage.property_mutation_count > usage.property_mutation_count
527545
|| v_usage.flags.intersects(
@@ -905,8 +923,11 @@ impl Optimizer<'_> {
905923
}
906924
}
907925
Expr::Ident(i) => {
908-
let node_id = self.r.find_binding_by_ident(i);
909-
debug_assert!(i.node_id != node_id);
926+
let node_id = match self.r.find_binding_by_ident(i) {
927+
RefTo::Binding(node_id) => node_id,
928+
RefTo::Unresolved => return,
929+
RefTo::Itself => unreachable!(),
930+
};
910931

911932
if let Some(mut value) = self
912933
.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::{
@@ -351,9 +354,10 @@ impl Optimizer<'_> {
351354
return false;
352355
}
353356

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

358362
if id.ctxt != self.marks.top_level_ctxt {
359363
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
@@ -11,7 +11,7 @@ use swc_ecma_transforms_base::perf::{Parallel, ParallelExt};
1111
use swc_ecma_utils::{collect_decls, contains_this_expr, ExprCtx, ExprExt, Remapper};
1212
use swc_ecma_transforms_base::{
1313
perf::{Parallel, ParallelExt},
14-
resolve::Resolver,
14+
resolve::{RefTo, Resolver},
1515
};
1616
use swc_ecma_utils::{collect_decls, ExprCtx, ExprExt, Remapper};
1717
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
@@ -532,7 +532,11 @@ impl VisitMut for NormalMultiReplacer<'_> {
532532
}
533533

534534
if let Expr::Ident(i) = e {
535-
let node_id = self.r.find_binding_by_ident(i);
535+
let node_id = match self.r.find_binding_by_ident(i) {
536+
RefTo::Binding(node_id) => node_id,
537+
RefTo::Unresolved => return,
538+
RefTo::Itself => unreachable!(),
539+
};
536540
if let Some(new) = self.var(&node_id) {
537541
debug!("multi-replacer: Replaced `{}`", i);
538542
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 {
@@ -504,8 +507,11 @@ where
504507

505508
for arg in &n.args {
506509
for_each_id_ref_in_expr(&arg.expr, &mut |arg| {
507-
let node_id = self.r.find_binding_by_ident(arg);
508-
debug_assert!(arg.node_id != node_id);
510+
let node_id = match self.r.find_binding_by_ident(arg) {
511+
RefTo::Binding(node_id) => node_id,
512+
RefTo::Unresolved => return,
513+
RefTo::Itself => unreachable!(),
514+
};
509515
self.data.var_or_default(node_id).mark_used_as_arg();
510516
})
511517
}
@@ -1036,8 +1042,11 @@ where
10361042
}
10371043

10381044
for_each_id_ref_in_expr(&e.obj, &mut |obj| {
1039-
let node_id = self.r.find_binding_by_ident(obj);
1040-
debug_assert!(obj.node_id != node_id);
1045+
let node_id = match self.r.find_binding_by_ident(obj) {
1046+
RefTo::Binding(node_id) => node_id,
1047+
RefTo::Unresolved => return,
1048+
RefTo::Itself => unreachable!(),
1049+
};
10411050
let v = self.data.var_or_default(node_id);
10421051
v.mark_has_property_access();
10431052

0 commit comments

Comments
 (0)