Skip to content

Commit 0af0267

Browse files
committed
refactor(minifier): side effect detection needs symbols resolution (#8715)
1 parent 4a2f2a9 commit 0af0267

14 files changed

+156
-409
lines changed

crates/oxc_ecmascript/src/constant_evaluation/mod.rs

+14-17
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ pub use is_literal_value::IsLiteralValue;
1414
pub use value::ConstantValue;
1515
pub use value_type::ValueType;
1616

17-
pub trait ConstantEvaluation<'a> {
18-
fn is_global_reference(&self, ident: &IdentifierReference<'a>) -> bool {
19-
matches!(ident.name.as_str(), "undefined" | "NaN" | "Infinity")
20-
}
21-
17+
pub trait ConstantEvaluation<'a>: MayHaveSideEffects<'a> {
2218
fn resolve_binding(&self, ident: &IdentifierReference<'a>) -> Option<ConstantValue<'a>> {
2319
match ident.name.as_str() {
2420
"undefined" if self.is_global_reference(ident) => Some(ConstantValue::Undefined),
@@ -36,7 +32,7 @@ pub trait ConstantEvaluation<'a> {
3632
// and there are only a very few cases where we can compute a number value, but there could
3733
// also be side effects. e.g. `void doSomething()` has value NaN, regardless of the behavior
3834
// of `doSomething()`
39-
if value.is_some() && expr.may_have_side_effects() {
35+
if value.is_some() && self.expression_may_have_side_efffects(expr) {
4036
None
4137
} else {
4238
value
@@ -45,23 +41,23 @@ pub trait ConstantEvaluation<'a> {
4541

4642
fn get_side_free_string_value(&self, expr: &Expression<'a>) -> Option<Cow<'a, str>> {
4743
let value = expr.to_js_string();
48-
if value.is_some() && !expr.may_have_side_effects() {
44+
if value.is_some() && !self.expression_may_have_side_efffects(expr) {
4945
return value;
5046
}
5147
None
5248
}
5349

5450
fn get_side_free_boolean_value(&self, expr: &Expression<'a>) -> Option<bool> {
5551
let value = self.get_boolean_value(expr);
56-
if value.is_some() && !expr.may_have_side_effects() {
52+
if value.is_some() && !self.expression_may_have_side_efffects(expr) {
5753
return value;
5854
}
5955
None
6056
}
6157

6258
fn get_side_free_bigint_value(&self, expr: &Expression<'a>) -> Option<BigInt> {
6359
let value = expr.to_big_int();
64-
if value.is_some() && expr.may_have_side_effects() {
60+
if value.is_some() && self.expression_may_have_side_efffects(expr) {
6561
None
6662
} else {
6763
value
@@ -205,7 +201,9 @@ pub trait ConstantEvaluation<'a> {
205201
) -> Option<ConstantValue<'a>> {
206202
match operator {
207203
BinaryOperator::Addition => {
208-
if left.may_have_side_effects() || right.may_have_side_effects() {
204+
if self.expression_may_have_side_efffects(left)
205+
|| self.expression_may_have_side_efffects(right)
206+
{
209207
return None;
210208
}
211209
let left_type = ValueType::from(left);
@@ -321,7 +319,7 @@ pub trait ConstantEvaluation<'a> {
321319
None
322320
}
323321
BinaryOperator::Instanceof => {
324-
if left.may_have_side_effects() {
322+
if self.expression_may_have_side_efffects(left) {
325323
return None;
326324
}
327325
if let Expression::Identifier(right_ident) = right {
@@ -380,8 +378,9 @@ pub trait ConstantEvaluation<'a> {
380378
};
381379
Some(ConstantValue::String(Cow::Borrowed(s)))
382380
}
383-
UnaryOperator::Void => (expr.argument.is_literal() || !expr.may_have_side_effects())
384-
.then_some(ConstantValue::Undefined),
381+
UnaryOperator::Void => (expr.argument.is_literal()
382+
|| !self.expression_may_have_side_efffects(&expr.argument))
383+
.then_some(ConstantValue::Undefined),
385384
UnaryOperator::LogicalNot => self
386385
.get_side_free_boolean_value(&expr.argument)
387386
.map(|b| !b)
@@ -424,10 +423,9 @@ pub trait ConstantEvaluation<'a> {
424423
if let Some(ConstantValue::String(s)) = self.eval_expression(&expr.object) {
425424
Some(ConstantValue::Number(s.encode_utf16().count().to_f64().unwrap()))
426425
} else {
427-
if expr.object.may_have_side_effects() {
426+
if self.expression_may_have_side_efffects(&expr.object) {
428427
return None;
429428
}
430-
431429
if let Expression::ArrayExpression(arr) = &expr.object {
432430
Some(ConstantValue::Number(arr.elements.len().to_f64().unwrap()))
433431
} else {
@@ -448,10 +446,9 @@ pub trait ConstantEvaluation<'a> {
448446
if let Some(ConstantValue::String(s)) = self.eval_expression(&expr.object) {
449447
Some(ConstantValue::Number(s.encode_utf16().count().to_f64().unwrap()))
450448
} else {
451-
if expr.object.may_have_side_effects() {
449+
if self.expression_may_have_side_efffects(&expr.object) {
452450
return None;
453451
}
454-
455452
if let Expression::ArrayExpression(arr) = &expr.object {
456453
Some(ConstantValue::Number(arr.elements.len().to_f64().unwrap()))
457454
} else {

0 commit comments

Comments
 (0)