diff --git a/crates/oxc_ast/src/ast/literal.rs b/crates/oxc_ast/src/ast/literal.rs index 3a582d38d..5e1d44c29 100644 --- a/crates/oxc_ast/src/ast/literal.rs +++ b/crates/oxc_ast/src/ast/literal.rs @@ -8,7 +8,7 @@ use std::{ use bitflags::bitflags; use num_bigint::BigInt; use oxc_span::{Atom, Span}; -use oxc_syntax::NumberBase; +use oxc_syntax::{BigintBase, NumberBase}; #[cfg(feature = "serde")] use serde::Serialize; @@ -111,6 +111,8 @@ pub struct BigintLiteral { pub span: Span, #[cfg_attr(feature = "serde", serde(serialize_with = "crate::serialize::serialize_bigint"))] pub value: BigInt, + #[cfg_attr(feature = "serde", serde(skip))] + pub base: BigintBase, } #[derive(Debug, Clone, Hash)] diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index f014ac01e..884784f2f 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -14,7 +14,7 @@ use oxc_syntax::{ operator::{ AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator, }, - NumberBase, + BigintBase, NumberBase, }; #[allow(clippy::wildcard_imports)] @@ -126,8 +126,8 @@ impl<'a> AstBuilder<'a> { BooleanLiteral { span, value } } - pub fn bigint_literal(&self, span: Span, value: BigInt) -> BigintLiteral { - BigintLiteral { span, value } + pub fn bigint_literal(&self, span: Span, value: BigInt, base: BigintBase) -> BigintLiteral { + BigintLiteral { span, value, base } } pub fn template_literal( diff --git a/crates/oxc_minifier/src/compressor/fold.rs b/crates/oxc_minifier/src/compressor/fold.rs index c8b60feb2..3a4e1646c 100644 --- a/crates/oxc_minifier/src/compressor/fold.rs +++ b/crates/oxc_minifier/src/compressor/fold.rs @@ -678,7 +678,8 @@ impl<'a> Compressor<'a> { use std::ops::Neg; let value = big_int_literal.value.clone().neg(); - let literal = self.ast.bigint_literal(unary_expr.span, value); + let literal = + self.ast.bigint_literal(unary_expr.span, value, big_int_literal.base); return Some(self.ast.literal_bigint_expression(literal)); } Expression::Identifier(ident) => { @@ -706,7 +707,8 @@ impl<'a> Compressor<'a> { } Expression::BigintLiteral(big_int_literal) => { let value = big_int_literal.value.clone().not(); - let leteral = self.ast.bigint_literal(unary_expr.span, value); + let leteral = + self.ast.bigint_literal(unary_expr.span, value, big_int_literal.base); return Some(self.ast.literal_bigint_expression(leteral)); } Expression::Identifier(ident) => { diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index e3040d0c6..4a54ed5c2 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -4,7 +4,7 @@ use oxc_allocator::Box; use oxc_ast::ast::*; use oxc_diagnostics::Result; use oxc_span::{Atom, Span}; -use oxc_syntax::{operator::BinaryOperator, precedence::Precedence, NumberBase}; +use oxc_syntax::{operator::BinaryOperator, precedence::Precedence, BigintBase, NumberBase}; use super::{ function::IsParenthesizedArrowFunction, @@ -294,12 +294,19 @@ impl<'a> Parser<'a> { pub(crate) fn parse_literal_bigint(&mut self) -> Result { let span = self.start_span(); + let base = match self.cur_kind() { + Kind::Decimal => BigintBase::Decimal, + Kind::Binary => BigintBase::Binary, + Kind::Octal => BigintBase::Octal, + Kind::Hex => BigintBase::Hex, + _ => return Err(self.unexpected()), + }; let value = match self.cur_kind() { kind if kind.is_number() => self.cur_token().value.as_bigint(), _ => return Err(self.unexpected()), }; self.bump_any(); - Ok(BigintLiteral { span: self.end_span(span), value }) + Ok(BigintLiteral { span: self.end_span(span), value, base }) } pub(crate) fn parse_literal_regexp(&mut self) -> Result { diff --git a/crates/oxc_syntax/src/lib.rs b/crates/oxc_syntax/src/lib.rs index 5b8fe4ec3..4da245d54 100644 --- a/crates/oxc_syntax/src/lib.rs +++ b/crates/oxc_syntax/src/lib.rs @@ -26,3 +26,17 @@ impl NumberBase { matches!(self, Self::Float | Self::Decimal) } } + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +pub enum BigintBase { + Decimal, + Binary, + Octal, + Hex, +} + +impl BigintBase { + pub fn is_base_10(&self) -> bool { + self == &Self::Decimal + } +}