mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(minifier): constant fold instanceof (#8142)
This commit is contained in:
parent
75264ed7d6
commit
6615e1ea93
2 changed files with 62 additions and 1 deletions
|
|
@ -347,6 +347,27 @@ pub trait ConstantEvaluation<'a> {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
BinaryOperator::Instanceof => {
|
||||||
|
if left.may_have_side_effects() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let left_ty = ValueType::from(left);
|
||||||
|
if left_ty == ValueType::Undetermined {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if left_ty == ValueType::Object {
|
||||||
|
if let Some(right_ident) = right.get_identifier_reference() {
|
||||||
|
if right_ident.name == "Object" && self.is_global_reference(right_ident) {
|
||||||
|
return Some(ConstantValue::Boolean(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// Non-object types are never instances.
|
||||||
|
Some(ConstantValue::Boolean(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,8 @@ impl<'a, 'b> PeepholeFoldConstants {
|
||||||
| BinaryOperator::Division
|
| BinaryOperator::Division
|
||||||
| BinaryOperator::Remainder
|
| BinaryOperator::Remainder
|
||||||
| BinaryOperator::Multiplication
|
| BinaryOperator::Multiplication
|
||||||
| BinaryOperator::Exponential => {
|
| BinaryOperator::Exponential
|
||||||
|
| BinaryOperator::Instanceof => {
|
||||||
ctx.eval_binary_expression(e).map(|v| ctx.value_to_expr(e.span, v))
|
ctx.eval_binary_expression(e).map(|v| ctx.value_to_expr(e.span, v))
|
||||||
}
|
}
|
||||||
BinaryOperator::Addition => Self::try_fold_add(e, ctx),
|
BinaryOperator::Addition => Self::try_fold_add(e, ctx),
|
||||||
|
|
@ -1503,6 +1504,45 @@ mod test {
|
||||||
test("(+x & 1) & 2", "+x & 0");
|
test("(+x & 1) & 2", "+x & 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fold_instance_of() {
|
||||||
|
// Non object types are never instances of anything.
|
||||||
|
test("64 instanceof Object", "false");
|
||||||
|
test("64 instanceof Number", "false");
|
||||||
|
test("'' instanceof Object", "false");
|
||||||
|
test("'' instanceof String", "false");
|
||||||
|
test("true instanceof Object", "false");
|
||||||
|
test("true instanceof Boolean", "false");
|
||||||
|
test("!0 instanceof Object", "false");
|
||||||
|
test("!0 instanceof Boolean", "false");
|
||||||
|
test("false instanceof Object", "false");
|
||||||
|
test("null instanceof Object", "false");
|
||||||
|
test("undefined instanceof Object", "false");
|
||||||
|
test("NaN instanceof Object", "false");
|
||||||
|
test("Infinity instanceof Object", "false");
|
||||||
|
|
||||||
|
// Array and object literals are known to be objects.
|
||||||
|
test("[] instanceof Object", "true");
|
||||||
|
test("({}) instanceof Object", "true");
|
||||||
|
|
||||||
|
// These cases is foldable, but no handled currently.
|
||||||
|
test_same("new Foo() instanceof Object");
|
||||||
|
// These would require type information to fold.
|
||||||
|
test_same("[] instanceof Foo");
|
||||||
|
test_same("({}) instanceof Foo");
|
||||||
|
|
||||||
|
test("(function() {}) instanceof Object", "true");
|
||||||
|
|
||||||
|
// An unknown value should never be folded.
|
||||||
|
test_same("x instanceof Foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fold_instance_of_additional() {
|
||||||
|
test("(typeof {}) instanceof Object", "false");
|
||||||
|
test("(+{}) instanceof Number", "false");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fold_left_child_op() {
|
fn test_fold_left_child_op() {
|
||||||
test_same("x & infinity & 2"); // FIXME: want x & 0
|
test_same("x & infinity & 2"); // FIXME: want x & 0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue