Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/oxc_ecmascript/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0).

### 🚜 Refactor

- 5a46641 ecmascript: Move `get_constant_value_for_reference_id` to `IsGlobalReference` trait (#11810) (Boshen)
- 5a46641 ecmascript: Move `get_constant_value_for_reference_id` to `GlobalContext` trait (#11810) (Boshen)



Expand Down Expand Up @@ -204,11 +204,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- b164072 ecmascript: Extract to_numeric (#9111) (sapphi-red)
- fc53cdd ecmascript: Generalize ToPrimitive (#9109) (sapphi-red)
- d951390 ecmascript: Use value_type in to_primitive (#9108) (sapphi-red)
- 8f79012 ecmascript: Pass IsGlobalReference to DetermineValueType instead of extending it (#9107) (sapphi-red)
- 8f79012 ecmascript: Pass GlobalContext to DetermineValueType instead of extending it (#9107) (sapphi-red)
- db1744c ecmascript: Remove "constant_evaluation" / "side_effects" features (#9114) (sapphi-red)
- 329de94 ecmascript: Extract ToPrimitive (#9102) (sapphi-red)
- d670ec7 ecmascript: Pass IsGlobalReference to MayHaveSideEffects instead of extending it (#9101) (sapphi-red)
- f4e2d4e ecmascript: Allow IsGlobalReference to return None (#9100) (sapphi-red)
- d670ec7 ecmascript: Pass GlobalContext to MayHaveSideEffects instead of extending it (#9101) (sapphi-red)
- f4e2d4e ecmascript: Allow GlobalContext to return None (#9100) (sapphi-red)

## [0.49.0] - 2025-02-10

Expand Down
20 changes: 4 additions & 16 deletions crates/oxc_ecmascript/src/array_join.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
use oxc_ast::ast::*;

use crate::{ToJsString, is_global_reference::IsGlobalReference};
use crate::{GlobalContext, ToJsString};

pub trait ArrayJoin<'a> {
/// `Array.prototype.join ( separator )`
/// <https://tc39.es/ecma262/#sec-array.prototype.join>
fn array_join(
&self,
is_global_reference: &impl IsGlobalReference<'a>,
separator: Option<&str>,
) -> Option<String>;
fn array_join(&self, ctx: &impl GlobalContext<'a>, separator: Option<&str>) -> Option<String>;
}

impl<'a> ArrayJoin<'a> for ArrayExpression<'a> {
fn array_join(
&self,
is_global_reference: &impl IsGlobalReference<'a>,
separator: Option<&str>,
) -> Option<String> {
let strings = self
.elements
.iter()
.map(|e| e.to_js_string(is_global_reference))
.collect::<Option<Vec<_>>>();
fn array_join(&self, ctx: &impl GlobalContext<'a>, separator: Option<&str>) -> Option<String> {
let strings = self.elements.iter().map(|e| e.to_js_string(ctx)).collect::<Option<Vec<_>>>();
strings
.map(|v| v.iter().map(AsRef::as_ref).collect::<Vec<_>>().join(separator.unwrap_or(",")))
}
Expand Down
42 changes: 19 additions & 23 deletions crates/oxc_ecmascript/src/constant_evaluation/is_int32_or_uint32.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use num_traits::ToPrimitive;
use oxc_ast::ast::*;

use crate::is_global_reference::IsGlobalReference;
use crate::GlobalContext;

use super::DetermineValueType;

Expand All @@ -13,70 +13,66 @@ pub trait IsInt32OrUint32<'a> {
/// - false means it is neither int32 nor uint32, or it is unknown.
///
/// Based on <https://github.com/evanw/esbuild/blob/v0.25.0/internal/js_ast/js_ast_helpers.go#L950>
fn is_int32_or_uint32(&self, is_global_reference: &impl IsGlobalReference<'a>) -> bool;
fn is_int32_or_uint32(&self, ctx: &impl GlobalContext<'a>) -> bool;
}

impl<'a> IsInt32OrUint32<'a> for Expression<'a> {
fn is_int32_or_uint32(&self, is_global_reference: &impl IsGlobalReference<'a>) -> bool {
fn is_int32_or_uint32(&self, ctx: &impl GlobalContext<'a>) -> bool {
match self {
Expression::NumericLiteral(n) => n.is_int32_or_uint32(is_global_reference),
Expression::UnaryExpression(e) => e.is_int32_or_uint32(is_global_reference),
Expression::BinaryExpression(e) => e.is_int32_or_uint32(is_global_reference),
Expression::LogicalExpression(e) => e.is_int32_or_uint32(is_global_reference),
Expression::NumericLiteral(n) => n.is_int32_or_uint32(ctx),
Expression::UnaryExpression(e) => e.is_int32_or_uint32(ctx),
Expression::BinaryExpression(e) => e.is_int32_or_uint32(ctx),
Expression::LogicalExpression(e) => e.is_int32_or_uint32(ctx),
Expression::ConditionalExpression(e) => {
e.consequent.is_int32_or_uint32(is_global_reference)
&& e.alternate.is_int32_or_uint32(is_global_reference)
e.consequent.is_int32_or_uint32(ctx) && e.alternate.is_int32_or_uint32(ctx)
}
Expression::SequenceExpression(e) => {
e.expressions.last().is_some_and(|e| e.is_int32_or_uint32(is_global_reference))
}
Expression::ParenthesizedExpression(e) => {
e.expression.is_int32_or_uint32(is_global_reference)
e.expressions.last().is_some_and(|e| e.is_int32_or_uint32(ctx))
}
Expression::ParenthesizedExpression(e) => e.expression.is_int32_or_uint32(ctx),
_ => false,
}
}
}

impl<'a> IsInt32OrUint32<'a> for NumericLiteral<'a> {
fn is_int32_or_uint32(&self, _is_global_reference: &impl IsGlobalReference<'a>) -> bool {
fn is_int32_or_uint32(&self, _ctx: &impl GlobalContext<'a>) -> bool {
self.value.fract() == 0.0
&& (self.value.to_i32().is_some() || self.value.to_u32().is_some())
}
}

impl<'a> IsInt32OrUint32<'a> for UnaryExpression<'a> {
fn is_int32_or_uint32(&self, is_global_reference: &impl IsGlobalReference<'a>) -> bool {
fn is_int32_or_uint32(&self, ctx: &impl GlobalContext<'a>) -> bool {
match self.operator {
UnaryOperator::BitwiseNot => self.value_type(is_global_reference).is_number(),
UnaryOperator::UnaryPlus => self.argument.is_int32_or_uint32(is_global_reference),
UnaryOperator::BitwiseNot => self.value_type(ctx).is_number(),
UnaryOperator::UnaryPlus => self.argument.is_int32_or_uint32(ctx),
_ => false,
}
}
}

impl<'a> IsInt32OrUint32<'a> for BinaryExpression<'a> {
fn is_int32_or_uint32(&self, is_global_reference: &impl IsGlobalReference<'a>) -> bool {
fn is_int32_or_uint32(&self, ctx: &impl GlobalContext<'a>) -> bool {
match self.operator {
BinaryOperator::ShiftLeft
| BinaryOperator::ShiftRight
| BinaryOperator::BitwiseAnd
| BinaryOperator::BitwiseOR
| BinaryOperator::BitwiseXOR => self.value_type(is_global_reference).is_number(),
| BinaryOperator::BitwiseXOR => self.value_type(ctx).is_number(),
BinaryOperator::ShiftRightZeroFill => true,
_ => false,
}
}
}

impl<'a> IsInt32OrUint32<'a> for LogicalExpression<'a> {
fn is_int32_or_uint32(&self, is_global_reference: &impl IsGlobalReference<'a>) -> bool {
fn is_int32_or_uint32(&self, ctx: &impl GlobalContext<'a>) -> bool {
match self.operator {
LogicalOperator::And | LogicalOperator::Or => {
self.left.is_int32_or_uint32(is_global_reference)
&& self.right.is_int32_or_uint32(is_global_reference)
self.left.is_int32_or_uint32(ctx) && self.right.is_int32_or_uint32(ctx)
}
LogicalOperator::Coalesce => self.left.is_int32_or_uint32(is_global_reference),
LogicalOperator::Coalesce => self.left.is_int32_or_uint32(ctx),
}
}
}
11 changes: 4 additions & 7 deletions crates/oxc_ecmascript/src/constant_evaluation/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::borrow::Cow;
use num_bigint::BigInt;
use num_traits::Zero;

use crate::{ToBoolean, ToJsString, ToNumber, is_global_reference::IsGlobalReference};
use crate::{GlobalContext, ToBoolean, ToJsString, ToNumber};

#[derive(Debug, PartialEq, Clone)]
pub enum ConstantValue<'a> {
Expand Down Expand Up @@ -70,10 +70,7 @@ impl<'a> ConstantValue<'a> {
}

impl<'a> ToJsString<'a> for ConstantValue<'a> {
fn to_js_string(
&self,
_is_global_reference: &impl IsGlobalReference<'a>,
) -> Option<Cow<'a, str>> {
fn to_js_string(&self, _ctx: &impl GlobalContext<'a>) -> Option<Cow<'a, str>> {
match self {
Self::Number(n) => {
use oxc_syntax::number::ToJsString;
Expand All @@ -90,7 +87,7 @@ impl<'a> ToJsString<'a> for ConstantValue<'a> {
}

impl<'a> ToNumber<'a> for ConstantValue<'a> {
fn to_number(&self, _is_global_reference: &impl IsGlobalReference<'a>) -> Option<f64> {
fn to_number(&self, _ctx: &impl GlobalContext<'a>) -> Option<f64> {
use crate::StringToNumber;
match self {
Self::Number(n) => Some(*n),
Expand All @@ -104,7 +101,7 @@ impl<'a> ToNumber<'a> for ConstantValue<'a> {
}

impl<'a> ToBoolean<'a> for ConstantValue<'a> {
fn to_boolean(&self, _is_global_reference: &impl IsGlobalReference<'a>) -> Option<bool> {
fn to_boolean(&self, _ctx: &impl GlobalContext<'a>) -> Option<bool> {
match self {
Self::Number(n) => Some(!n.is_nan() && *n != 0.0),
Self::BigInt(n) => Some(*n != BigInt::zero()),
Expand Down
Loading
Loading