Skip to content

Commit

Permalink
feat(transformer): RegexpFlags
Browse files Browse the repository at this point in the history
  • Loading branch information
magic-akari committed Oct 10, 2023
1 parent b7dbbde commit 2f9a141
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 15 deletions.
2 changes: 0 additions & 2 deletions crates/oxc_transformer/src/es2015/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
mod shorthand_properties;
mod sticky_regex;

pub use shorthand_properties::ShorthandProperties;
pub use sticky_regex::StickyRegex;
11 changes: 8 additions & 3 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ mod es2021;
mod es2022;
mod options;
mod react_jsx;
mod regexp;
mod typescript;

use oxc_allocator::Allocator;
use oxc_ast::{ast::*, AstBuilder, VisitMut};
use oxc_span::SourceType;
use regexp::RegexpFlags;
use std::rc::Rc;

use es2015::ShorthandProperties;
Expand All @@ -35,6 +37,7 @@ pub use crate::options::{
#[derive(Default)]
pub struct Transformer<'a> {
typescript: Option<TypeScript<'a>>,
regexp_flags: Option<RegexpFlags<'a>>,
react_jsx: Option<ReactJsx<'a>>,
// es2022
es2022_class_static_block: Option<es2022::ClassStaticBlock<'a>>,
Expand All @@ -46,7 +49,6 @@ pub struct Transformer<'a> {
es2016_exponentiation_operator: Option<ExponentiationOperator<'a>>,
// es2015
es2015_shorthand_properties: Option<ShorthandProperties<'a>>,
es2015_sticky_regex: Option<es2015::StickyRegex<'a>>,
}

impl<'a> Transformer<'a> {
Expand All @@ -64,6 +66,9 @@ impl<'a> Transformer<'a> {
if let Some(react_options) = options.react {
t.react_jsx.replace(ReactJsx::new(Rc::clone(&ast), react_options));
}

t.regexp_flags = RegexpFlags::new_with_transform_target(Rc::clone(&ast), options.target);

if options.target < TransformTarget::ES2022 {
t.es2022_class_static_block.replace(es2022::ClassStaticBlock::new(Rc::clone(&ast)));
}
Expand All @@ -79,7 +84,6 @@ impl<'a> Transformer<'a> {
}
if options.target < TransformTarget::ES2015 {
t.es2015_shorthand_properties.replace(ShorthandProperties::new(Rc::clone(&ast)));
t.es2015_sticky_regex.replace(es2015::StickyRegex::new(Rc::clone(&ast)));
}
t
}
Expand All @@ -93,9 +97,10 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
fn visit_expression(&mut self, expr: &mut Expression<'a>) {
// self.typescript.as_mut().map(|t| t.transform_expression(expr));
// self.react_jsx.as_mut().map(|t| t.transform_expression(expr));
self.regexp_flags.as_mut().map(|t| t.transform_expression(expr));

self.es2021_logical_assignment_operators.as_mut().map(|t| t.transform_expression(expr));
self.es2016_exponentiation_operator.as_mut().map(|t| t.transform_expression(expr));
self.es2015_sticky_regex.as_mut().map(|t| t.transform_expression(expr));

self.visit_expression_match(expr);
}
Expand Down
2 changes: 2 additions & 0 deletions crates/oxc_transformer/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ pub enum TransformTarget {
ES5,
ES2015,
ES2016,
ES2018,
ES2019,
ES2021,
ES2022,
ES2024,
#[default]
ESNext,
}
Expand Down
3 changes: 3 additions & 0 deletions crates/oxc_transformer/src/regexp/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod regexp_flags;

pub use regexp_flags::RegexpFlags;
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,32 @@ use oxc_span::{Atom, Span};

use std::rc::Rc;

/// ES2015: Sticky Regex
///
/// References:
/// * <https://babel.dev/docs/babel-plugin-transform-sticky-regex>
/// * <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-sticky-regex>
pub struct StickyRegex<'a> {
use crate::TransformTarget;

/// Regexp
pub struct RegexpFlags<'a> {
ast: Rc<AstBuilder<'a>>,
transform_flags: RegExpFlags,
}

impl<'a> StickyRegex<'a> {
pub fn new(ast: Rc<AstBuilder<'a>>) -> Self {
Self { ast }
impl<'a> RegexpFlags<'a> {
pub fn new_with_transform_target(
ast: Rc<AstBuilder<'a>>,
transform_target: TransformTarget,
) -> Option<Self> {
let transform_flags = from_transform_target(transform_target);

if transform_flags.is_empty() {
None
} else {
Some(Self { ast, transform_flags })
}
}

pub fn transform_expression<'b>(&mut self, expr: &'b mut Expression<'a>) {
let Expression::RegExpLiteral(reg_literal) = expr else { return };
if !reg_literal.regex.flags.contains(RegExpFlags::Y) {

if reg_literal.regex.flags.intersection(self.transform_flags).is_empty() {
return;
}

Expand All @@ -41,3 +50,31 @@ impl<'a> StickyRegex<'a> {
*expr = self.ast.new_expression(Span::default(), callee, arguments, None);
}
}

fn from_transform_target(value: TransformTarget) -> RegExpFlags {
let mut flag = RegExpFlags::empty();

if value < TransformTarget::ESNext {
flag |= RegExpFlags::I;
flag |= RegExpFlags::M;
}

if value < TransformTarget::ES2024 {
flag |= RegExpFlags::V;
}

if value < TransformTarget::ES2022 {
flag |= RegExpFlags::D;
}

if value < TransformTarget::ES2018 {
flag |= RegExpFlags::S;
}

if value < TransformTarget::ES2015 {
flag |= RegExpFlags::Y;
flag |= RegExpFlags::U;
}

flag
}

0 comments on commit 2f9a141

Please sign in to comment.