Skip to content

Commit

Permalink
feat(transformer): numeric separator plugin. (#2795)
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa committed Mar 26, 2024
1 parent 56493bd commit 243131d
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 19 deletions.
6 changes: 1 addition & 5 deletions crates/oxc_codegen/src/gen.rs
Expand Up @@ -1167,11 +1167,7 @@ fn print_non_negative_float<const MINIFY: bool>(value: f64, _p: &Codegen<{ MINIF
impl<'a, const MINIFY: bool> Gen<MINIFY> for BigIntLiteral<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
p.add_source_mapping(self.span.start);
if self.raw.contains('_') {
p.print_str(self.raw.replace('_', "").as_bytes());
} else {
p.print_str(self.raw.as_bytes());
}
p.print_str(self.raw.as_bytes());
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_transformer/src/es2015/literals.rs
Expand Up @@ -33,7 +33,7 @@ impl<'a> Literals<'a> {

if let [b'0', b'b' | b'B' | b'o' | b'O'] = lit.raw[0..2].as_bytes() {
// Set binary and octal raw values to empty, It would force the codegen,
// to generate them from their value.
// go generate them from their value.
lit.raw = "";
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/oxc_transformer/src/es2021/mod.rs
@@ -1,3 +1,5 @@
mod logical_assignment_operators;
mod numeric_separator;

pub use logical_assignment_operators::LogicalAssignmentOperators;
pub use numeric_separator::NumericSeparator;
36 changes: 36 additions & 0 deletions crates/oxc_transformer/src/es2021/numeric_separator.rs
@@ -0,0 +1,36 @@
use oxc_ast::ast::*;
use oxc_span::Atom;

use crate::{
context::TransformerCtx,
options::{TransformOptions, TransformTarget},
};

/// ES2021: Numeric Separator
///
/// References:
/// * <https://babeljs.io/docs/babel-plugin-transform-numeric-separator>
pub struct NumericSeparator<'a> {
ctx: TransformerCtx<'a>,
}

impl<'a> NumericSeparator<'a> {
#![allow(clippy::unused_self)]

pub fn new(ctx: TransformerCtx<'a>, options: &TransformOptions) -> Option<Self> {
(options.target < TransformTarget::ES2021 || options.numeric_separator)
.then_some(Self { ctx })
}

pub fn transform_number_literal(&mut self, lit: &mut NumericLiteral<'a>) {
if !lit.raw.is_empty() {
lit.raw = self.ctx.ast.new_str(lit.raw.replace('_', "").as_str());
}
}

pub fn transform_bigint_literal(&mut self, lit: &mut BigIntLiteral<'a>) {
if !lit.raw.is_empty() {
lit.raw = Atom::from(self.ctx.ast.new_str(lit.raw.replace('_', "").as_str()));
}
}
}
19 changes: 10 additions & 9 deletions crates/oxc_transformer/src/lib.rs
Expand Up @@ -49,7 +49,7 @@ use crate::{
es2016::ExponentiationOperator,
es2019::{JsonStrings, OptionalCatchBinding},
es2020::NullishCoalescingOperator,
es2021::LogicalAssignmentOperators,
es2021::{LogicalAssignmentOperators, NumericSeparator},
es2022::ClassStaticBlock,
es3::PropertyLiteral,
react_jsx::ReactJsx,
Expand Down Expand Up @@ -78,6 +78,7 @@ pub struct Transformer<'a> {
es2022_class_static_block: Option<ClassStaticBlock<'a>>,
// es2021
es2021_logical_assignment_operators: Option<LogicalAssignmentOperators<'a>>,
es2021_numeric_separator: Option<NumericSeparator<'a>>,
// es2020
es2020_nullish_coalescing_operators: Option<NullishCoalescingOperator<'a>>,
// es2019
Expand Down Expand Up @@ -120,6 +121,7 @@ impl<'a> Transformer<'a> {
es2022_class_static_block: es2022::ClassStaticBlock::new(Rc::clone(&ast), &options),
// es2021
es2021_logical_assignment_operators: LogicalAssignmentOperators::new(Rc::clone(&ast), ctx.clone(), &options),
es2021_numeric_separator: NumericSeparator::new(ctx.clone(), &options),
// es2020
es2020_nullish_coalescing_operators: NullishCoalescingOperator::new(Rc::clone(&ast), ctx.clone(), &options),
// es2019
Expand Down Expand Up @@ -247,21 +249,20 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
}

fn visit_directive(&mut self, directive: &mut Directive<'a>) {
self.es2019_json_strings
.as_mut()
.map(|t: &mut JsonStrings| t.transform_directive(directive));
// TODO: we didn't walk this through, but maybe we should?
// walk_directive_mut(self, directive);
self.es2019_json_strings.as_mut().map(|t| t.transform_directive(directive));
}

fn visit_number_literal(&mut self, lit: &mut NumericLiteral<'a>) {
self.es2021_numeric_separator.as_mut().map(|t| t.transform_number_literal(lit));
self.es2015_literals.as_mut().map(|t| t.transform_number_literal(lit));
}

fn visit_bigint_literal(&mut self, lit: &mut BigIntLiteral<'a>) {
self.es2021_numeric_separator.as_mut().map(|t| t.transform_bigint_literal(lit));
}

fn visit_string_literal(&mut self, lit: &mut StringLiteral<'a>) {
self.es2019_json_strings
.as_mut()
.map(|t: &mut JsonStrings| t.transform_string_literal(lit));
self.es2019_json_strings.as_mut().map(|t| t.transform_string_literal(lit));
self.es2015_literals.as_mut().map(|t| t.transform_string_literal(lit));
}

Expand Down
1 change: 1 addition & 0 deletions crates/oxc_transformer/src/options.rs
Expand Up @@ -18,6 +18,7 @@ pub struct TransformOptions {
pub class_static_block: bool,
// es2021
pub logical_assignment_operators: bool,
pub numeric_separator: bool,
// es2020
pub nullish_coalescing_operator: Option<NullishCoalescingOperatorOptions>,
// es2019
Expand Down
6 changes: 2 additions & 4 deletions tasks/transform_conformance/babel.snap.md
@@ -1,6 +1,7 @@
Passed: 319/1415
Passed: 320/1415

# All Passed:
* babel-plugin-transform-numeric-separator
* babel-plugin-transform-optional-catch-binding
* babel-plugin-transform-json-strings
* babel-plugin-transform-shorthand-properties
Expand Down Expand Up @@ -519,9 +520,6 @@ Passed: 319/1415
# babel-plugin-transform-logical-assignment-operators (5/6)
* logical-assignment/null-coalescing/input.js

# babel-plugin-transform-numeric-separator (1/2)
* numeric-separator/used-with-transform-literals/input.js

# babel-plugin-transform-export-namespace-from (0/4)
* export-namespace/namespace-default/input.mjs
* export-namespace/namespace-es6/input.mjs
Expand Down
1 change: 1 addition & 0 deletions tasks/transform_conformance/src/test_case.rs
Expand Up @@ -109,6 +109,7 @@ pub trait TestCase {
logical_assignment_operators: options
.get_plugin("transform-logical-assignment-operators")
.is_some(),
numeric_separator: options.get_plugin("transform-numeric-separator").is_some(),
nullish_coalescing_operator: options
.get_plugin("transform-nullish-coalescing-operator")
.map(get_options::<NullishCoalescingOperatorOptions>),
Expand Down

0 comments on commit 243131d

Please sign in to comment.