refactor(minifier): remove Tri, use Option<bool> instead (#6912)

This commit is contained in:
Boshen 2024-10-26 04:28:34 +00:00
parent d3c5c78cba
commit 2c7ac29ece
3 changed files with 30 additions and 74 deletions

View file

@ -10,7 +10,7 @@ use oxc_syntax::{
};
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};
use crate::{node_util::Ctx, tri::Tri, CompressorPass};
use crate::{node_util::Ctx, CompressorPass};
/// Constant Folding
///
@ -270,20 +270,20 @@ impl<'a, 'b> PeepholeFoldConstants {
}
BinaryOperator::Equality => Self::try_abstract_equality_comparison(left, right, ctx),
BinaryOperator::Inequality => {
Self::try_abstract_equality_comparison(left, right, ctx).not()
Self::try_abstract_equality_comparison(left, right, ctx).map(|b| !b)
}
BinaryOperator::StrictEquality => {
Self::try_strict_equality_comparison(left, right, ctx)
}
BinaryOperator::StrictInequality => {
Self::try_strict_equality_comparison(left, right, ctx).not()
Self::try_strict_equality_comparison(left, right, ctx).map(|b| !b)
}
_ => Tri::Unknown,
_ => None,
};
let value = match value {
Tri::True => true,
Tri::False => false,
Tri::Unknown => return None,
Some(true) => true,
Some(false) => false,
None => return None,
};
Some(ctx.ast.expression_boolean_literal(e.span, value))
}
@ -293,7 +293,7 @@ impl<'a, 'b> PeepholeFoldConstants {
left_expr: &'b Expression<'a>,
right_expr: &'b Expression<'a>,
ctx: Ctx<'a, 'b>,
) -> Tri {
) -> Option<bool> {
let left = ValueType::from(left_expr);
let right = ValueType::from(right_expr);
if left != ValueType::Undetermined && right != ValueType::Undetermined {
@ -304,7 +304,7 @@ impl<'a, 'b> PeepholeFoldConstants {
(left, right),
(ValueType::Null, ValueType::Undefined) | (ValueType::Undefined, ValueType::Null)
) {
return Tri::True;
return Some(true);
}
if matches!((left, right), (ValueType::Number, ValueType::String))
@ -327,7 +327,7 @@ impl<'a, 'b> PeepholeFoldConstants {
);
}
return Tri::Unknown;
return None;
}
if matches!((left, right), (ValueType::String, ValueType::Number))
@ -350,7 +350,7 @@ impl<'a, 'b> PeepholeFoldConstants {
);
}
return Tri::Unknown;
return None;
}
if matches!(left, ValueType::BigInt) || matches!(right, ValueType::BigInt) {
@ -358,25 +358,25 @@ impl<'a, 'b> PeepholeFoldConstants {
let right_bigint = ctx.get_side_free_bigint_value(right_expr);
if let (Some(l_big), Some(r_big)) = (left_bigint, right_bigint) {
return Tri::from(l_big.eq(&r_big));
return Some(l_big.eq(&r_big));
}
}
if matches!(left, ValueType::String | ValueType::Number)
&& matches!(right, ValueType::Object)
{
return Tri::Unknown;
return None;
}
if matches!(left, ValueType::Object)
&& matches!(right, ValueType::String | ValueType::Number)
{
return Tri::Unknown;
return None;
}
return Tri::False;
return Some(false);
}
Tri::Unknown
None
}
/// <https://tc39.es/ecma262/#sec-strict-equality-comparison>
@ -385,13 +385,13 @@ impl<'a, 'b> PeepholeFoldConstants {
left_expr: &'b Expression<'a>,
right_expr: &'b Expression<'a>,
ctx: Ctx<'a, 'b>,
) -> Tri {
) -> Option<bool> {
let left = ValueType::from(left_expr);
let right = ValueType::from(right_expr);
if left != ValueType::Undetermined && right != ValueType::Undetermined {
// Strict equality can only be true for values of the same type.
if left != right {
return Tri::False;
return Some(false);
}
return match left {
ValueType::Number => {
@ -400,13 +400,13 @@ impl<'a, 'b> PeepholeFoldConstants {
if let (Some(l_num), Some(r_num)) = (left_number, right_number) {
if l_num.is_nan() || r_num.is_nan() {
return Tri::False;
return Some(false);
}
return Tri::from(l_num == r_num);
return Some(l_num == r_num);
}
Tri::Unknown
None
}
ValueType::String => {
let left_string = ctx.get_side_free_string_value(left_expr);
@ -414,28 +414,28 @@ impl<'a, 'b> PeepholeFoldConstants {
if let (Some(left_string), Some(right_string)) = (left_string, right_string) {
// In JS, browsers parse \v differently. So do not compare strings if one contains \v.
if left_string.contains('\u{000B}') || right_string.contains('\u{000B}') {
return Tri::Unknown;
return None;
}
return Tri::from(left_string == right_string);
return Some(left_string == right_string);
}
Tri::Unknown
None
}
ValueType::Undefined | ValueType::Null => Tri::True,
ValueType::Undefined | ValueType::Null => Some(true),
ValueType::Boolean if right.is_boolean() => {
let left = ctx.get_boolean_value(left_expr);
let right = ctx.get_boolean_value(right_expr);
if let (Some(left_bool), Some(right_bool)) = (left, right) {
return Tri::from(left_bool == right_bool);
return Some(left_bool == right_bool);
}
Tri::Unknown
None
}
// TODO
ValueType::BigInt
| ValueType::Object
| ValueType::Boolean
| ValueType::Undetermined => Tri::Unknown,
| ValueType::Undetermined => None,
};
}
@ -443,9 +443,9 @@ impl<'a, 'b> PeepholeFoldConstants {
// There's only one special case:
// Any strict equality comparison against NaN returns false.
if left_expr.is_nan() || right_expr.is_nan() {
return Tri::False;
return Some(false);
}
Tri::Unknown
None
}
}

View file

@ -5,7 +5,6 @@ mod compressor;
mod keep_var;
mod node_util;
mod options;
mod tri;
#[cfg(test)]
mod tester;

View file

@ -1,43 +0,0 @@
/// Tri state
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Tri {
True,
False,
Unknown,
}
impl From<bool> for Tri {
fn from(value: bool) -> Self {
if value {
Tri::True
} else {
Tri::False
}
}
}
impl From<Option<bool>> for Tri {
fn from(value: Option<bool>) -> Self {
value.map_or(Tri::Unknown, From::from)
}
}
impl From<i8> for Tri {
fn from(value: i8) -> Self {
match value {
-1 => Self::False,
1 => Self::True,
_ => Self::Unknown,
}
}
}
impl Tri {
pub fn not(self) -> Self {
match self {
Self::True => Self::False,
Self::False => Self::True,
Self::Unknown => Self::Unknown,
}
}
}