mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(minifier): fold invalid typeof comparisons (#8550)
This commit is contained in:
parent
c479a58718
commit
7cc81ef5ef
1 changed files with 51 additions and 2 deletions
|
|
@ -607,12 +607,12 @@ impl<'a, 'b> PeepholeFoldConstants {
|
|||
))
|
||||
}
|
||||
|
||||
// `typeof a === typeof b` -> `typeof a == typeof b`, `typeof a != typeof b` -> `typeof a != typeof b`,
|
||||
// `typeof a == typeof a` -> `true`, `typeof a != typeof a` -> `false`
|
||||
fn try_fold_binary_typeof_comparison(
|
||||
bin_expr: &mut BinaryExpression<'a>,
|
||||
ctx: Ctx<'a, 'b>,
|
||||
) -> Option<Expression<'a>> {
|
||||
// `typeof a === typeof b` -> `typeof a == typeof b`, `typeof a != typeof b` -> `typeof a != typeof b`,
|
||||
// `typeof a == typeof a` -> `true`, `typeof a != typeof a` -> `false`
|
||||
if bin_expr.operator.is_equality() {
|
||||
if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) =
|
||||
(&bin_expr.left, &bin_expr.right)
|
||||
|
|
@ -653,6 +653,41 @@ impl<'a, 'b> PeepholeFoldConstants {
|
|||
}
|
||||
}
|
||||
|
||||
// `typeof a === 'asd` -> `false``
|
||||
// `typeof a !== 'b'` -> `true``
|
||||
if let Expression::UnaryExpression(left) = &bin_expr.left {
|
||||
if left.operator.is_typeof() && bin_expr.operator.is_equality() {
|
||||
let right_ty = ValueType::from(&bin_expr.right);
|
||||
|
||||
if !right_ty.is_undetermined() && right_ty != ValueType::String {
|
||||
return Some(ctx.ast.expression_boolean_literal(
|
||||
bin_expr.span,
|
||||
bin_expr.operator == BinaryOperator::Inequality
|
||||
|| bin_expr.operator == BinaryOperator::StrictInequality,
|
||||
));
|
||||
}
|
||||
if let Expression::StringLiteral(string_lit) = &bin_expr.right {
|
||||
if !matches!(
|
||||
string_lit.value.as_str(),
|
||||
"string"
|
||||
| "number"
|
||||
| "bigint"
|
||||
| "boolean"
|
||||
| "symbol"
|
||||
| "undefined"
|
||||
| "object"
|
||||
| "function"
|
||||
) {
|
||||
return Some(ctx.ast.expression_boolean_literal(
|
||||
bin_expr.span,
|
||||
bin_expr.operator == BinaryOperator::Inequality
|
||||
|| bin_expr.operator == BinaryOperator::StrictInequality,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
|
|
@ -1736,6 +1771,20 @@ mod test {
|
|||
test("typeof foo.bar !== typeof foo.bar", "typeof foo.bar != typeof foo.bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_invalid_typeof_comparison() {
|
||||
test("typeof foo == 123", "false");
|
||||
test("typeof foo == '123'", "false");
|
||||
test("typeof foo === null", "false");
|
||||
test("typeof foo === undefined", "false");
|
||||
test("typeof foo !== 123", "true");
|
||||
test("typeof foo !== '123'", "true");
|
||||
test("typeof foo != null", "true");
|
||||
test("typeof foo != undefined", "true");
|
||||
test_same("typeof foo === 'string'");
|
||||
test_same("typeof foo === 'number'");
|
||||
}
|
||||
|
||||
// TODO: All big ints are rare and difficult to handle.
|
||||
mod bigint {
|
||||
use super::{
|
||||
|
|
|
|||
Loading…
Reference in a new issue