mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +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
|
||||
}
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,7 +245,8 @@ impl<'a, 'b> PeepholeFoldConstants {
|
|||
| BinaryOperator::Division
|
||||
| BinaryOperator::Remainder
|
||||
| BinaryOperator::Multiplication
|
||||
| BinaryOperator::Exponential => {
|
||||
| BinaryOperator::Exponential
|
||||
| BinaryOperator::Instanceof => {
|
||||
ctx.eval_binary_expression(e).map(|v| ctx.value_to_expr(e.span, v))
|
||||
}
|
||||
BinaryOperator::Addition => Self::try_fold_add(e, ctx),
|
||||
|
|
@ -1503,6 +1504,45 @@ mod test {
|
|||
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]
|
||||
fn test_fold_left_child_op() {
|
||||
test_same("x & infinity & 2"); // FIXME: want x & 0
|
||||
|
|
|
|||
Loading…
Reference in a new issue