Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

perf(es/utils): Restrict recursion of get_type #9933

Merged
merged 7 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/empty-steaks-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
swc_ecma_ast: minor
swc_ecma_utils: major
---

perf(es/utils): Restrict recursion of `get_type`
8 changes: 4 additions & 4 deletions crates/swc_ecma_minifier/src/compress/optimize/bools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ impl Optimizer<'_> {
}

if !is_ret_val_ignored {
if let Known(Type::Bool) = e.left.get_type() {
if let Known(Type::Bool) = e.left.get_type(self.ctx.expr_ctx) {
} else {
// Don't change type.
return false;
}

if let Known(Type::Bool) = e.right.get_type() {
if let Known(Type::Bool) = e.right.get_type(self.ctx.expr_ctx) {
} else {
// Don't change type.
return false;
Expand Down Expand Up @@ -277,8 +277,8 @@ impl Optimizer<'_> {
_ => return None,
};

let lt = left.get_type();
let rt = right.get_type();
let lt = left.get_type(self.ctx.expr_ctx);
let rt = right.get_type(self.ctx.expr_ctx);
if let Value::Known(lt) = lt {
if let Value::Known(rt) = rt {
match (lt, rt) {
Expand Down
4 changes: 2 additions & 2 deletions crates/swc_ecma_minifier/src/compress/optimize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1630,11 +1630,11 @@ impl VisitMut for Optimizer<'_> {
self.optimize_bin_and_or(n);

if n.op == op!(bin, "+") {
if let Known(Type::Str) = n.left.get_type() {
if let Known(Type::Str) = n.left.get_type(self.ctx.expr_ctx) {
self.optimize_expr_in_str_ctx(&mut n.right);
}

if let Known(Type::Str) = n.right.get_type() {
if let Known(Type::Str) = n.right.get_type(self.ctx.expr_ctx) {
self.optimize_expr_in_str_ctx(&mut n.left);
}
}
Expand Down
15 changes: 9 additions & 6 deletions crates/swc_ecma_minifier/src/compress/optimize/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ impl Optimizer<'_> {
}
}

let lt = e.left.get_type();
let rt = e.right.get_type();
let lt = e.left.get_type(self.ctx.expr_ctx);
let rt = e.right.get_type(self.ctx.expr_ctx);

if e.op == op!("===") {
if let Known(lt) = lt {
Expand Down Expand Up @@ -127,7 +127,10 @@ impl Optimizer<'_> {
.into(),
)
};
match (n.left.get_type().opt()?, n.right.get_type().opt()?) {
match (
n.left.get_type(self.ctx.expr_ctx).opt()?,
n.right.get_type(self.ctx.expr_ctx).opt()?,
) {
// Abort if types differ, or one of them is unknown.
(lt, rt) if lt != rt => {}
(Type::Obj, Type::Obj) => {}
Expand Down Expand Up @@ -181,7 +184,7 @@ impl Optimizer<'_> {
| Expr::Bin(BinExpr { op: op!("<"), .. })
| Expr::Bin(BinExpr { op: op!(">="), .. })
| Expr::Bin(BinExpr { op: op!(">"), .. }) => {
if let Known(Type::Bool) = arg.get_type() {
if let Known(Type::Bool) = arg.get_type(self.ctx.expr_ctx) {
self.changed = true;
report_change!("Optimizing: `!!expr` => `expr`");
*e = *arg.take();
Expand Down Expand Up @@ -299,14 +302,14 @@ impl Optimizer<'_> {
_ => {}
}

let lt = bin.left.get_type();
let lt = bin.left.get_type(self.ctx.expr_ctx);
match lt {
// Don't change type
Known(Type::Bool) => {}
_ => return,
}

let rt = bin.right.get_type();
let rt = bin.right.get_type(self.ctx.expr_ctx);
match rt {
Known(Type::Bool) => {}
_ => return,
Expand Down
4 changes: 2 additions & 2 deletions crates/swc_ecma_minifier/src/compress/optimize/sequences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2371,7 +2371,7 @@ impl Optimizer<'_> {
Mergable::Drop => return Ok(false),
};

let a_type = a_right.as_deref().map(|a| a.get_type());
let a_type = a_right.as_deref().map(|a| a.get_type(self.ctx.expr_ctx));

if let Some(a_right) = a_right {
if a_right.is_this() || a_right.is_ident_ref_to("arguments") {
Expand Down Expand Up @@ -2484,7 +2484,7 @@ impl Optimizer<'_> {
let Some(a_type) = a_type else {
return Ok(false);
};
let b_type = b.right.get_type();
let b_type = b.right.get_type(self.ctx.expr_ctx);

if let Some(a_op) = a_op {
if can_drop_op_for(a_op, b.op, var_type, a_type, b_type) {
Expand Down
20 changes: 10 additions & 10 deletions crates/swc_ecma_minifier/src/compress/pure/bools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,19 @@ impl Pure<'_> {
matches!(op, op!("==") | op!("===") | op!("!=") | op!("!=="))
}

fn can_absorb_negate(e: &Expr) -> bool {
fn can_absorb_negate(e: &Expr, ctx: ExprCtx) -> bool {
match e {
Expr::Lit(_) => true,
Expr::Bin(BinExpr {
op: op!("&&") | op!("||"),
left,
right,
..
}) => can_absorb_negate(left) && can_absorb_negate(right),
}) => can_absorb_negate(left, ctx) && can_absorb_negate(right, ctx),
Expr::Bin(BinExpr { op, .. }) if is_eq(*op) => true,
Expr::Unary(UnaryExpr {
op: op!("!"), arg, ..
}) => arg.get_type() == Value::Known(Type::Bool),
}) => arg.get_type(ctx) == Value::Known(Type::Bool),
_ => false,
}
}
Expand All @@ -123,7 +123,7 @@ impl Pure<'_> {
return;
};

let arg_can_negate = can_absorb_negate(arg);
let arg_can_negate = can_absorb_negate(arg, self.expr_ctx);

match &mut **arg {
Expr::Bin(BinExpr { op, .. }) if is_eq(*op) => {
Expand Down Expand Up @@ -158,7 +158,7 @@ impl Pure<'_> {
}

pub(super) fn compress_cmp_with_long_op(&mut self, e: &mut BinExpr) {
fn should_optimize(l: &Expr, r: &Expr, opts: &CompressOptions) -> bool {
fn should_optimize(l: &Expr, r: &Expr, ctx: ExprCtx, opts: &CompressOptions) -> bool {
match (l, r) {
(
Expr::Unary(UnaryExpr {
Expand All @@ -168,7 +168,7 @@ impl Pure<'_> {
) => true,
_ => {
if opts.comparisons {
match (l.get_type(), r.get_type()) {
match (l.get_type(ctx), r.get_type(ctx)) {
(Value::Known(lt), Value::Known(rt)) => lt == rt,

_ => false,
Expand All @@ -185,8 +185,8 @@ impl Pure<'_> {
_ => return,
}

if should_optimize(&e.left, &e.right, self.options)
|| should_optimize(&e.right, &e.left, self.options)
if should_optimize(&e.left, &e.right, self.expr_ctx, self.options)
|| should_optimize(&e.right, &e.left, self.expr_ctx, self.options)
{
report_change!("bools: Compressing comparison of `typeof` with literal");
self.changed = true;
Expand Down Expand Up @@ -226,8 +226,8 @@ impl Pure<'_> {
right,
..
}) => {
let lt = left.get_type();
let rt = right.get_type();
let lt = left.get_type(self.expr_ctx);
let rt = right.get_type(self.expr_ctx);

if let (Value::Known(Type::Bool), Value::Known(Type::Bool)) = (lt, rt) {
let rb = right.as_pure_bool(self.expr_ctx);
Expand Down
8 changes: 4 additions & 4 deletions crates/swc_ecma_minifier/src/compress/pure/conds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl Pure<'_> {

let Expr::Cond(cond) = e else { return };

let lt = cond.cons.get_type();
let lt = cond.cons.get_type(self.expr_ctx);
if let Value::Known(Type::Bool) = lt {
let lb = cond.cons.as_pure_bool(self.expr_ctx);
if let Value::Known(true) = lb {
Expand Down Expand Up @@ -59,7 +59,7 @@ impl Pure<'_> {
}
}

let rt = cond.alt.get_type();
let rt = cond.alt.get_type(self.expr_ctx);
if let Value::Known(Type::Bool) = rt {
let rb = cond.alt.as_pure_bool(self.expr_ctx);
if let Value::Known(false) = rb {
Expand Down Expand Up @@ -220,8 +220,8 @@ impl Pure<'_> {
return;
}

let lt = bin.left.get_type();
let rt = bin.right.get_type();
let lt = bin.left.get_type(self.expr_ctx);
let rt = bin.right.get_type(self.expr_ctx);

let _lb = bin.left.as_pure_bool(self.expr_ctx);
let rb = bin.right.as_pure_bool(self.expr_ctx);
Expand Down
4 changes: 2 additions & 2 deletions crates/swc_ecma_minifier/src/compress/pure/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1675,8 +1675,8 @@ impl Pure<'_> {
_ => return,
};

let lt = cond.cons.get_type();
let rt = cond.alt.get_type();
let lt = cond.cons.get_type(self.expr_ctx);
let rt = cond.alt.get_type(self.expr_ctx);
match (lt, rt) {
(Known(Type::Bool), Known(Type::Bool)) => {}
_ => return,
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_minifier/src/compress/pure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub(crate) fn pure_optimizer<'a>(
unresolved_ctxt: SyntaxContext::empty().apply_mark(marks.unresolved_mark),
is_unresolved_ref_safe: false,
in_strict: options.module,
remaining_depth: 6,
remaining_depth: 4,
},
ctx: Default::default(),
changed: Default::default(),
Expand Down
12 changes: 6 additions & 6 deletions crates/swc_ecma_minifier/src/compress/pure/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ impl Pure<'_> {
_ => return,
};

match l_l.get_type() {
match l_l.get_type(self.expr_ctx) {
Known(Type::Str) => {}
_ => return,
}
match r_l.get_type() {
match r_l.get_type(self.expr_ctx) {
Known(Type::Str) => {}
_ => return,
}
Expand Down Expand Up @@ -487,8 +487,8 @@ impl Pure<'_> {
},
) = &mut *bin.left
{
let type_of_second = left.right.get_type();
let type_of_third = bin.right.get_type();
let type_of_second = left.right.get_type(self.expr_ctx);
let type_of_third = bin.right.get_type(self.expr_ctx);

if let Value::Known(Type::Str) = type_of_second {
if let Value::Known(Type::Str) = type_of_third {
Expand Down Expand Up @@ -534,8 +534,8 @@ impl Pure<'_> {
..
}) = e
{
let lt = left.get_type();
let rt = right.get_type();
let lt = left.get_type(self.expr_ctx);
let rt = right.get_type(self.expr_ctx);
if let Value::Known(Type::Str) = lt {
if let Value::Known(Type::Str) = rt {
match &**left {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ impl SimplifyExpr {
}
}

match expr.get_type() {
match expr.get_type(self.expr_ctx) {
// String concatenation
Known(StringType) => match expr {
Expr::Bin(BinExpr {
Expand Down Expand Up @@ -911,8 +911,8 @@ impl SimplifyExpr {

if (lv.is_unknown() && rv.is_unknown())
|| op == op!(bin, "+")
&& (!left.get_type().casted_to_number_on_add()
|| !right.get_type().casted_to_number_on_add())
&& (!left.get_type(self.expr_ctx).casted_to_number_on_add()
|| !right.get_type(self.expr_ctx).casted_to_number_on_add())
{
return Unknown;
}
Expand Down Expand Up @@ -1067,7 +1067,7 @@ impl SimplifyExpr {
}

// Try to evaluate based on the general type.
let (lt, rt) = (left.get_type(), right.get_type());
let (lt, rt) = (left.get_type(self.expr_ctx), right.get_type(self.expr_ctx));

if let (Known(StringType), Known(StringType)) = (lt, rt) {
if let (Known(lv), Known(rv)) = (
Expand Down Expand Up @@ -1099,7 +1099,10 @@ impl SimplifyExpr {

/// https://tc39.github.io/ecma262/#sec-abstract-equality-comparison
fn perform_abstract_eq_cmp(&mut self, span: Span, left: &Expr, right: &Expr) -> Value<bool> {
let (lt, rt) = (try_val!(left.get_type()), try_val!(right.get_type()));
let (lt, rt) = (
try_val!(left.get_type(self.expr_ctx)),
try_val!(right.get_type(self.expr_ctx)),
);

if lt == rt {
return self.perform_strict_eq_cmp(left, right);
Expand Down Expand Up @@ -1171,7 +1174,10 @@ impl SimplifyExpr {
_ => {}
}

let (lt, rt) = (try_val!(left.get_type()), try_val!(right.get_type()));
let (lt, rt) = (
try_val!(left.get_type(self.expr_ctx)),
try_val!(right.get_type(self.expr_ctx)),
);
// Strict equality can only be true for values of the same type.
if lt != rt {
return Known(false);
Expand Down
15 changes: 11 additions & 4 deletions crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,15 +276,19 @@ where
match &n.left {
AssignTarget::Pat(p) => {
for id in find_pat_ids(p) {
self.data
.report_assign(self.ctx, id, is_op_assign, n.right.get_type())
self.data.report_assign(
self.ctx,
id,
is_op_assign,
n.right.get_type(self.expr_ctx),
)
}
}
AssignTarget::Simple(e) => {
self.report_assign_expr_if_ident(
e.as_ident().map(Ident::from).as_ref(),
is_op_assign,
n.right.get_type(),
n.right.get_type(self.expr_ctx),
);
self.mark_mutation_if_member(e.as_member())
}
Expand Down Expand Up @@ -1304,7 +1308,10 @@ where
let ctx = Ctx {
inline_prevented: self.ctx.inline_prevented || prevent_inline,
in_pat_of_var_decl: true,
in_pat_of_var_decl_with_init: e.init.as_ref().map(|init| init.get_type()),
in_pat_of_var_decl_with_init: e
.init
.as_ref()
.map(|init| init.get_type(self.expr_ctx)),
in_decl_with_no_side_effect_for_member_access: e
.init
.as_deref()
Expand Down
Loading
Loading