diff --git a/crates/oxc_minifier/src/node_util/mod.rs b/crates/oxc_minifier/src/node_util/mod.rs index 3f00c72aa10f86..986ec2fbb5413a 100644 --- a/crates/oxc_minifier/src/node_util/mod.rs +++ b/crates/oxc_minifier/src/node_util/mod.rs @@ -217,7 +217,7 @@ pub trait NodeUtil { Expression::UnaryExpression(unary_expr) => match unary_expr.operator { UnaryOperator::UnaryPlus => self.get_number_value(&unary_expr.argument), UnaryOperator::UnaryNegation => { - self.get_number_value(&unary_expr.argument).map(|v| v.not()) + self.get_number_value(&unary_expr.argument).map(|v| -v) } UnaryOperator::BitwiseNot => { self.get_number_value(&unary_expr.argument).map(|value| { diff --git a/crates/oxc_minifier/src/node_util/number_value.rs b/crates/oxc_minifier/src/node_util/number_value.rs index e2e1ce8af4ecb3..f6520e78ccda45 100644 --- a/crates/oxc_minifier/src/node_util/number_value.rs +++ b/crates/oxc_minifier/src/node_util/number_value.rs @@ -1,3 +1,5 @@ +use num_traits::Zero; + #[derive(PartialEq)] pub enum NumberValue { Number(f64), @@ -7,21 +9,21 @@ pub enum NumberValue { } impl NumberValue { - #[must_use] - pub fn not(&self) -> Self { - match self { - Self::Number(num) => Self::Number(-num), - Self::PositiveInfinity => Self::NegativeInfinity, - Self::NegativeInfinity => Self::PositiveInfinity, - Self::NaN => Self::NaN, - } - } - pub fn is_nan(&self) -> bool { matches!(self, Self::NaN) } } +impl Zero for NumberValue { + fn zero() -> Self { + Self::Number(0.0) + } + + fn is_zero(&self) -> bool { + matches!(self, Self::Number(num) if num.is_zero()) + } +} + impl std::ops::Add for NumberValue { type Output = Self; @@ -46,6 +48,94 @@ impl std::ops::Add for NumberValue { } } +impl std::ops::Sub for NumberValue { + type Output = Self; + + fn sub(self, other: Self) -> Self { + self + (-other) + } +} + +impl std::ops::Mul for NumberValue { + type Output = Self; + + fn mul(self, other: Self) -> Self { + match self { + Self::Number(num) => match other { + Self::Number(other_num) => Self::Number(num * other_num), + Self::PositiveInfinity | Self::NegativeInfinity if num.is_zero() => Self::NaN, + Self::PositiveInfinity => Self::PositiveInfinity, + Self::NegativeInfinity => Self::NegativeInfinity, + Self::NaN => Self::NaN, + }, + Self::NaN => Self::NaN, + Self::PositiveInfinity | Self::NegativeInfinity => match other { + Self::Number(num) if num > 0.0 => self, + Self::Number(num) if num < 0.0 => -self, + Self::PositiveInfinity => self, + Self::NegativeInfinity => -self, + _ => Self::NaN, + }, + } + } +} + +impl std::ops::Div for NumberValue { + type Output = Self; + + fn div(self, other: Self) -> Self { + match self { + Self::Number(num) => match other { + Self::Number(other_num) if other_num.is_zero() => Self::NaN, + Self::Number(other_num) => Self::Number(num / other_num), + Self::PositiveInfinity | Self::NegativeInfinity if num < 0.0 => -other, + Self::PositiveInfinity | Self::NegativeInfinity if num > 0.0 => other, + _ => Self::NaN, + }, + Self::NaN => Self::NaN, + Self::PositiveInfinity | Self::NegativeInfinity => match other { + Self::Number(num) if num > 0.0 => self, + Self::Number(num) if num < 0.0 => -self, + _ => Self::NaN, + }, + } + } +} + +impl std::ops::Rem for NumberValue { + type Output = Self; + + fn rem(self, other: Self) -> Self { + match self { + Self::Number(num) => match other { + Self::Number(other_num) if other_num.is_zero() => Self::NaN, + Self::Number(other_num) => Self::Number(num % other_num), + Self::PositiveInfinity | Self::NegativeInfinity if num.is_zero() => Self::NaN, + Self::PositiveInfinity | Self::NegativeInfinity => self, + Self::NaN => Self::NaN, + }, + Self::NaN => Self::NaN, + Self::PositiveInfinity | Self::NegativeInfinity => match other { + Self::Number(num) if !num.is_zero() => self, + _ => Self::NaN, + }, + } + } +} + +impl std::ops::Neg for NumberValue { + type Output = Self; + + fn neg(self) -> Self { + match self { + Self::Number(num) => Self::Number(-num), + Self::PositiveInfinity => Self::NegativeInfinity, + Self::NegativeInfinity => Self::PositiveInfinity, + Self::NaN => Self::NaN, + } + } +} + impl TryFrom for f64 { type Error = ();