Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(transformer): add transform literal for numeric literals. #2797

Merged
merged 18 commits into from Mar 26, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 45 additions & 0 deletions crates/oxc_transformer/src/es2015/literals.rs
@@ -0,0 +1,45 @@
use std::rc::Rc;

use oxc_ast::{ast::*, AstBuilder};

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

/// ES2015: Shorthand Properties
///
/// References:
/// * <https://babeljs.io/docs/babel-plugin-transform-literals>
/// * <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-literals/src/index.ts>
pub struct Literals<'a> {
_ast: Rc<AstBuilder<'a>>,
}

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

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

pub fn transform_number_literal(&mut self, lit: &mut NumericLiteral<'a>) {
// early return if number's raw value is empty or shorter than 2 characters,
// both `0bxxx` and `0oxxx` need at least 3 characters be defined.
if lit.raw.len() <= 2 {
return;
}

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.
lit.raw = "";
}
}

pub fn transform_string_literal(&mut self, _: &mut StringLiteral<'a>) {
// TODO: As of today oxc_lexer takes care of this, We have to rework it
// so it can be controlled via the transformer.
}
}
2 changes: 2 additions & 0 deletions crates/oxc_transformer/src/es2015/mod.rs
Expand Up @@ -2,6 +2,7 @@ mod arrow_functions;
mod duplicate_keys;
mod function_name;
mod instanceof;
mod literals;
mod new_target;
mod shorthand_properties;
mod template_literals;
Expand All @@ -10,6 +11,7 @@ pub use arrow_functions::{ArrowFunctions, ArrowFunctionsOptions};
pub use duplicate_keys::DuplicateKeys;
pub use function_name::FunctionName;
pub use instanceof::Instanceof;
pub use literals::Literals;
pub use new_target::NewTarget;
pub use shorthand_properties::ShorthandProperties;
pub use template_literals::TemplateLiterals;
9 changes: 8 additions & 1 deletion crates/oxc_transformer/src/lib.rs
Expand Up @@ -92,6 +92,7 @@ pub struct Transformer<'a> {
es2015_template_literals: Option<TemplateLiterals<'a>>,
es2015_duplicate_keys: Option<DuplicateKeys<'a>>,
es2015_instanceof: Option<Instanceof<'a>>,
es2015_literals: Option<Literals<'a>>,
es2015_new_target: Option<NewTarget<'a>>,
es3_property_literal: Option<PropertyLiteral<'a>>,
}
Expand Down Expand Up @@ -133,6 +134,7 @@ impl<'a> Transformer<'a> {
es2015_template_literals: TemplateLiterals::new(Rc::clone(&ast), &options),
es2015_duplicate_keys: DuplicateKeys::new(Rc::clone(&ast), &options),
es2015_instanceof: Instanceof::new(Rc::clone(&ast), ctx.clone(), &options),
es2015_literals: Literals::new(ctx.clone(), &options),
es2015_new_target: NewTarget::new(Rc::clone(&ast),ctx.clone(), &options),
// other
es3_property_literal: PropertyLiteral::new(Rc::clone(&ast), &options),
Expand Down Expand Up @@ -252,10 +254,15 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
// walk_directive_mut(self, directive);
}

fn visit_string_literal(&mut self, lit: &mut StringLiteral) {
fn visit_number_literal(&mut self, lit: &mut NumericLiteral<'a>) {
self.es2015_literals.as_mut().map(|t| t.transform_number_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.es2015_literals.as_mut().map(|t| t.transform_string_literal(lit));
}

fn visit_method_definition(&mut self, def: &mut MethodDefinition<'a>) {
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_transformer/src/options.rs
Expand Up @@ -30,6 +30,7 @@ pub struct TransformOptions {
pub function_name: bool,
pub arrow_functions: Option<ArrowFunctionsOptions>,
pub shorthand_properties: bool,
pub literals: bool,
pub sticky_regex: bool,
pub template_literals: bool,
pub property_literals: bool,
Expand Down
1 change: 1 addition & 0 deletions tasks/transform_conformance/src/test_case.rs
Expand Up @@ -101,6 +101,7 @@ pub trait TestCase {
assumptions: options.assumptions,
class_static_block: options.get_plugin("transform-class-static-block").is_some(),
instanceof: options.get_plugin("transform-instanceof").is_some(),
literals: options.get_plugin("transform-literals").is_some(),
function_name: options.get_plugin("transform-function-name").is_some(),
arrow_functions: options
.get_plugin("transform-arrow-functions")
Expand Down