mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(ecmascript): constant eval null to number (#6879)
This commit is contained in:
parent
0d0bb17ad9
commit
442975408b
4 changed files with 28 additions and 8 deletions
|
|
@ -9,7 +9,7 @@ use num_traits::{One, Zero};
|
|||
|
||||
use oxc_ast::ast::*;
|
||||
|
||||
use crate::{side_effects::MayHaveSideEffects, ToBigInt, ToInt32, ToJsString};
|
||||
use crate::{side_effects::MayHaveSideEffects, ToBigInt, ToInt32, ToJsString, ToNumber};
|
||||
|
||||
pub use self::{is_litral_value::IsLiteralValue, value::ConstantValue, value_type::ValueType};
|
||||
|
||||
|
|
@ -179,6 +179,7 @@ pub trait ConstantEvaluation<'a> {
|
|||
Expression::UnaryExpression(e) => self.eval_unary_expression(e),
|
||||
Expression::Identifier(ident) => self.resolve_binding(ident),
|
||||
Expression::NumericLiteral(lit) => Some(ConstantValue::Number(lit.value)),
|
||||
Expression::NullLiteral(_) => Some(ConstantValue::Null),
|
||||
Expression::StringLiteral(lit) => {
|
||||
Some(ConstantValue::String(Cow::Borrowed(lit.value.as_str())))
|
||||
}
|
||||
|
|
@ -206,8 +207,8 @@ pub trait ConstantEvaluation<'a> {
|
|||
if left_type.is_number() || right_type.is_number() {
|
||||
let lval = self.eval_expression(left)?;
|
||||
let rval = self.eval_expression(right)?;
|
||||
let lnum = lval.into_number()?;
|
||||
let rnum = rval.into_number()?;
|
||||
let lnum = lval.to_number()?;
|
||||
let rnum = rval.to_number()?;
|
||||
return Some(ConstantValue::Number(lnum + rnum));
|
||||
}
|
||||
None
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use core::f64;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::ToJsString;
|
||||
use crate::{ToJsString, ToNumber};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ConstantValue<'a> {
|
||||
|
|
@ -11,6 +12,7 @@ pub enum ConstantValue<'a> {
|
|||
String(Cow<'a, str>),
|
||||
Boolean(bool),
|
||||
Undefined,
|
||||
Null,
|
||||
}
|
||||
|
||||
impl<'a> ConstantValue<'a> {
|
||||
|
|
@ -68,6 +70,21 @@ impl<'a> ToJsString<'a> for ConstantValue<'a> {
|
|||
Self::String(s) => Some(s.clone()),
|
||||
Self::Boolean(b) => Some(Cow::Borrowed(if *b { "true" } else { "false" })),
|
||||
Self::Undefined => Some(Cow::Borrowed("undefined")),
|
||||
Self::Null => Some(Cow::Borrowed("null")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToNumber<'a> for ConstantValue<'a> {
|
||||
fn to_number(&self) -> Option<f64> {
|
||||
use crate::StringToNumber;
|
||||
match self {
|
||||
Self::Number(n) => Some(*n),
|
||||
Self::BigInt(_) => None,
|
||||
Self::String(s) => Some(s.as_ref().string_to_number()),
|
||||
Self::Boolean(true) => Some(1.0),
|
||||
Self::Boolean(false) | Self::Null => Some(0.0),
|
||||
Self::Undefined => Some(f64::NAN),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1174,19 +1174,17 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_fold_arithmetic2() {
|
||||
test_same("x = y + 10 + 20");
|
||||
test_same("x = y / 2 / 4");
|
||||
test("x = y * 2.25 * 3", "x = y * 6.75");
|
||||
// test("x = y * 2.25 * 3", "x = y * 6.75");
|
||||
test_same("x = y * 2.25 * z * 3");
|
||||
test_same("z = x * y");
|
||||
test_same("x = y * 5");
|
||||
test("x = y + (z * 24 * 60 * 60 * 1000)", "x = y + z * 864E5");
|
||||
// test("x = y + (z * 24 * 60 * 60 * 1000)", "x = y + z * 864E5");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_fold_arithmetic3() {
|
||||
test("x = null * undefined", "x = NaN");
|
||||
test("x = null * 1", "x = 0");
|
||||
|
|
@ -1194,6 +1192,9 @@ mod test {
|
|||
test("x = (null + 1) * 2", "x = 2");
|
||||
test("x = null ** 0", "x = 1");
|
||||
test("x = (-0) ** 3", "x = -0");
|
||||
|
||||
test("x = 1 + null", "x = 1");
|
||||
test("x = null + 1", "x = 1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ impl<'a, 'b> Ctx<'a, 'b> {
|
|||
ConstantValue::String(s) => self.ast.expression_string_literal(span, s),
|
||||
ConstantValue::Boolean(b) => self.ast.expression_boolean_literal(span, b),
|
||||
ConstantValue::Undefined => self.ast.void_0(span),
|
||||
ConstantValue::Null => self.ast.expression_null_literal(span),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue