mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
fix(minifier): reference read has side effect (#6851)
This commit is contained in:
parent
c658d9336d
commit
686727fc96
4 changed files with 21 additions and 66 deletions
|
|
@ -430,22 +430,6 @@ pub trait ConstantEvaluation<'a> {
|
|||
left_string.cmp(&right_string) == Ordering::Less,
|
||||
));
|
||||
}
|
||||
|
||||
// Special case: `typeof a < typeof a` is always false.
|
||||
if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) =
|
||||
(left_expr, right_expr)
|
||||
{
|
||||
if (left.operator, right.operator) == (UnaryOperator::Typeof, UnaryOperator::Typeof)
|
||||
{
|
||||
if let (Expression::Identifier(left), Expression::Identifier(right)) =
|
||||
(&left.argument, &right.argument)
|
||||
{
|
||||
if left.name == right.name {
|
||||
return Some(ConstantValue::Boolean(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: bigint is handled very differently in the spec
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ impl<'a, 'b> CheckForStateChange<'a, 'b> for Expression<'a> {
|
|||
.expressions
|
||||
.iter()
|
||||
.any(|expr| expr.check_for_state_change(check_for_new_objects)),
|
||||
Self::Identifier(_ident) =>
|
||||
/* TODO: ident.reference_flags == ReferenceFlags::Write */
|
||||
{
|
||||
false
|
||||
}
|
||||
Self::Identifier(ident) => match ident.name.as_str() {
|
||||
"undefined" | "NaN" | "Infinity" => false,
|
||||
// Reference read can have a side effect.
|
||||
_ => true,
|
||||
},
|
||||
Self::UnaryExpression(unary_expr) => {
|
||||
unary_expr.check_for_state_change(check_for_new_objects)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use oxc_ecmascript::{
|
|||
use oxc_span::{GetSpan, SPAN};
|
||||
use oxc_syntax::{
|
||||
number::{NumberBase, ToJsString},
|
||||
operator::{BinaryOperator, LogicalOperator, UnaryOperator},
|
||||
operator::{BinaryOperator, LogicalOperator},
|
||||
};
|
||||
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};
|
||||
|
||||
|
|
@ -411,23 +411,6 @@ impl<'a, 'b> PeepholeFoldConstants {
|
|||
return Tri::from(left_string == right_string);
|
||||
}
|
||||
|
||||
if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) =
|
||||
(left_expr, right_expr)
|
||||
{
|
||||
if (left.operator, right.operator)
|
||||
== (UnaryOperator::Typeof, UnaryOperator::Typeof)
|
||||
{
|
||||
if let (Expression::Identifier(left), Expression::Identifier(right)) =
|
||||
(&left.argument, &right.argument)
|
||||
{
|
||||
if left.name == right.name {
|
||||
// Special case, typeof a == typeof a is always true.
|
||||
return Tri::True;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tri::Unknown
|
||||
}
|
||||
ValueType::Undefined | ValueType::Null => Tri::True,
|
||||
|
|
@ -713,28 +696,28 @@ mod test {
|
|||
fn test_boolean_number_comparison() {
|
||||
test_same("!x==+y");
|
||||
test_same("!x<=+y");
|
||||
test("!x !== +y", "true");
|
||||
test_same("!x !== +y");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_number_boolean_comparison() {
|
||||
test_same("+x==!y");
|
||||
test_same("+x<=!y");
|
||||
test("+x === !y", "false");
|
||||
test_same("+x === !y");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boolean_string_comparison() {
|
||||
test_same("!x==''+y");
|
||||
test_same("!x<=''+y");
|
||||
test("!x !== '' + y", "true");
|
||||
test_same("!x !== '' + y");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string_boolean_comparison() {
|
||||
test_same("''+x==!y");
|
||||
test_same("''+x<=!y");
|
||||
test("'' + x === !y", "false");
|
||||
test_same("'' + x === !y");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -746,8 +729,8 @@ mod test {
|
|||
test("+'a' < +'b'", "false");
|
||||
test_same("typeof a < 'a'");
|
||||
test_same("'a' >= typeof a");
|
||||
test("typeof a < typeof a", "false");
|
||||
test("typeof a >= typeof a", "true");
|
||||
test_same("typeof a < typeof a");
|
||||
test_same("typeof a >= typeof a");
|
||||
test("typeof 3 > typeof 4", "false");
|
||||
test("typeof function() {} < typeof function() {}", "false");
|
||||
test("'a' == 'a'", "true");
|
||||
|
|
@ -756,11 +739,11 @@ mod test {
|
|||
test_same("typeof a != 'number'");
|
||||
test_same("'undefined' == typeof a");
|
||||
test_same("'undefined' == typeof a");
|
||||
test("typeof a == typeof a", "true");
|
||||
test_same("typeof a == typeof a");
|
||||
test("'a' === 'a'", "true");
|
||||
test("'b' !== 'a'", "true");
|
||||
test("typeof a === typeof a", "true");
|
||||
test("typeof a !== typeof a", "false");
|
||||
test_same("typeof a === typeof a");
|
||||
test_same("typeof a !== typeof a");
|
||||
test_same("'' + x <= '' + y");
|
||||
test_same("'' + x != '' + y");
|
||||
test_same("'' + x === '' + y");
|
||||
|
|
@ -783,7 +766,7 @@ mod test {
|
|||
test("1 !== '1'", "true");
|
||||
test_same("+x>''+y");
|
||||
test_same("+x==''+y");
|
||||
test("+x !== '' + y", "true");
|
||||
test_same("+x !== '' + y");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -799,7 +782,7 @@ mod test {
|
|||
test("'1' !== 1", "true");
|
||||
test_same("''+x<+y");
|
||||
test_same("''+x==+y");
|
||||
test("'' + x === +y", "false");
|
||||
test_same("'' + x === +y");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -901,8 +884,8 @@ mod test {
|
|||
test_same("x>=NaN");
|
||||
test_same("NaN==x");
|
||||
test_same("x!=NaN");
|
||||
test("NaN === x", "false");
|
||||
test("x !== NaN", "true");
|
||||
test_same("NaN === x");
|
||||
test_same("x !== NaN");
|
||||
test_same("NaN==foo()");
|
||||
}
|
||||
|
||||
|
|
@ -1109,7 +1092,7 @@ mod test {
|
|||
fn test_fold_void() {
|
||||
test_same("void 0");
|
||||
test("void 1", "void 0");
|
||||
test("void x", "void 0");
|
||||
test_same("void x");
|
||||
test_same("void x()");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ commit: 06454619
|
|||
|
||||
runtime Summary:
|
||||
AST Parsed : 18444/18444 (100.00%)
|
||||
Positive Passed: 18269/18444 (99.05%)
|
||||
Positive Passed: 18273/18444 (99.07%)
|
||||
tasks/coverage/test262/test/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js
|
||||
minify error: Test262Error: Expected SameValue(«function f(){}», «undefined») to be true
|
||||
|
||||
|
|
@ -420,15 +420,6 @@ minify error: Test262Error: #3.2: -0 - 0 === - 0. Actual: +0
|
|||
tasks/coverage/test262/test/language/expressions/super/call-spread-obj-getter-init.js
|
||||
transform error: Test262Error: Expected SameValue(«true», «false») to be true
|
||||
|
||||
tasks/coverage/test262/test/language/expressions/template-literal/literal-expr-tostr-error.js
|
||||
minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all
|
||||
|
||||
tasks/coverage/test262/test/language/expressions/template-literal/middle-list-many-expr-tostr-error.js
|
||||
minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all
|
||||
|
||||
tasks/coverage/test262/test/language/expressions/template-literal/middle-list-one-expr-tostr-error.js
|
||||
minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all
|
||||
|
||||
tasks/coverage/test262/test/language/expressions/unary-plus/S11.4.6_A3_T3.js
|
||||
minify error: Test262Error: #4: +"INFINITY" === Not-a-Number. Actual: Infinity
|
||||
|
||||
|
|
@ -438,9 +429,6 @@ minify error: Test262Error: #3.2: +(-0) === -0. Actual: +0
|
|||
tasks/coverage/test262/test/language/expressions/unary-plus/bigint-throws.js
|
||||
minify error: Test262Error: +0n throws TypeError Expected a TypeError to be thrown but no exception was thrown at all
|
||||
|
||||
tasks/coverage/test262/test/language/expressions/void/S11.4.2_A2_T2.js
|
||||
minify error: Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all
|
||||
|
||||
tasks/coverage/test262/test/language/global-code/decl-func.js
|
||||
codegen error: Test262Error: descriptor should not be configurable
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue