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

[es2015 transform
literals](https://babeljs.io/docs/babel-plugin-transform-literals)

---------

Co-authored-by: Dunqing <dengqing0821@gmail.com>
This commit is contained in:
Ali Rezvani 2024-03-26 11:57:32 +03:30 committed by GitHub
parent 3d0ea545ca
commit 56493bd02b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 57 additions and 1 deletions

View file

@ -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.
}
}

View file

@ -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;
@ -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;

View file

@ -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>>,
}
@ -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),
@ -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>) {

View file

@ -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,

View file

@ -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")