mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +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 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};
|
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::UnaryExpression(e) => self.eval_unary_expression(e),
|
||||||
Expression::Identifier(ident) => self.resolve_binding(ident),
|
Expression::Identifier(ident) => self.resolve_binding(ident),
|
||||||
Expression::NumericLiteral(lit) => Some(ConstantValue::Number(lit.value)),
|
Expression::NumericLiteral(lit) => Some(ConstantValue::Number(lit.value)),
|
||||||
|
Expression::NullLiteral(_) => Some(ConstantValue::Null),
|
||||||
Expression::StringLiteral(lit) => {
|
Expression::StringLiteral(lit) => {
|
||||||
Some(ConstantValue::String(Cow::Borrowed(lit.value.as_str())))
|
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() {
|
if left_type.is_number() || right_type.is_number() {
|
||||||
let lval = self.eval_expression(left)?;
|
let lval = self.eval_expression(left)?;
|
||||||
let rval = self.eval_expression(right)?;
|
let rval = self.eval_expression(right)?;
|
||||||
let lnum = lval.into_number()?;
|
let lnum = lval.to_number()?;
|
||||||
let rnum = rval.into_number()?;
|
let rnum = rval.to_number()?;
|
||||||
return Some(ConstantValue::Number(lnum + rnum));
|
return Some(ConstantValue::Number(lnum + rnum));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
|
use core::f64;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
use crate::ToJsString;
|
use crate::{ToJsString, ToNumber};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum ConstantValue<'a> {
|
pub enum ConstantValue<'a> {
|
||||||
|
|
@ -11,6 +12,7 @@ pub enum ConstantValue<'a> {
|
||||||
String(Cow<'a, str>),
|
String(Cow<'a, str>),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Undefined,
|
Undefined,
|
||||||
|
Null,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ConstantValue<'a> {
|
impl<'a> ConstantValue<'a> {
|
||||||
|
|
@ -68,6 +70,21 @@ impl<'a> ToJsString<'a> for ConstantValue<'a> {
|
||||||
Self::String(s) => Some(s.clone()),
|
Self::String(s) => Some(s.clone()),
|
||||||
Self::Boolean(b) => Some(Cow::Borrowed(if *b { "true" } else { "false" })),
|
Self::Boolean(b) => Some(Cow::Borrowed(if *b { "true" } else { "false" })),
|
||||||
Self::Undefined => Some(Cow::Borrowed("undefined")),
|
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]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn test_fold_arithmetic2() {
|
fn test_fold_arithmetic2() {
|
||||||
test_same("x = y + 10 + 20");
|
test_same("x = y + 10 + 20");
|
||||||
test_same("x = y / 2 / 4");
|
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("x = y * 2.25 * z * 3");
|
||||||
test_same("z = x * y");
|
test_same("z = x * y");
|
||||||
test_same("x = y * 5");
|
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]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn test_fold_arithmetic3() {
|
fn test_fold_arithmetic3() {
|
||||||
test("x = null * undefined", "x = NaN");
|
test("x = null * undefined", "x = NaN");
|
||||||
test("x = null * 1", "x = 0");
|
test("x = null * 1", "x = 0");
|
||||||
|
|
@ -1194,6 +1192,9 @@ mod test {
|
||||||
test("x = (null + 1) * 2", "x = 2");
|
test("x = (null + 1) * 2", "x = 2");
|
||||||
test("x = null ** 0", "x = 1");
|
test("x = null ** 0", "x = 1");
|
||||||
test("x = (-0) ** 3", "x = -0");
|
test("x = (-0) ** 3", "x = -0");
|
||||||
|
|
||||||
|
test("x = 1 + null", "x = 1");
|
||||||
|
test("x = null + 1", "x = 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ impl<'a, 'b> Ctx<'a, 'b> {
|
||||||
ConstantValue::String(s) => self.ast.expression_string_literal(span, s),
|
ConstantValue::String(s) => self.ast.expression_string_literal(span, s),
|
||||||
ConstantValue::Boolean(b) => self.ast.expression_boolean_literal(span, b),
|
ConstantValue::Boolean(b) => self.ast.expression_boolean_literal(span, b),
|
||||||
ConstantValue::Undefined => self.ast.void_0(span),
|
ConstantValue::Undefined => self.ast.void_0(span),
|
||||||
|
ConstantValue::Null => self.ast.expression_null_literal(span),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue