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

refactor(transformer): pass options via context. #2794

Merged
merged 4 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
15 changes: 12 additions & 3 deletions crates/oxc_transformer/src/context.rs
@@ -1,4 +1,5 @@
use std::{
borrow::Cow,
cell::{Ref, RefCell, RefMut},
mem,
rc::Rc,
Expand All @@ -9,16 +10,24 @@ use oxc_diagnostics::Error;
use oxc_semantic::{ScopeId, ScopeTree, Semantic, SymbolId, SymbolTable};
use oxc_span::{CompactStr, SourceType};

use crate::TransformOptions;

#[derive(Clone)]
pub struct TransformerCtx<'a> {
pub ast: Rc<AstBuilder<'a>>,
pub options: Cow<'a, TransformOptions>,
semantic: Rc<RefCell<Semantic<'a>>>,
errors: Rc<RefCell<Vec<Error>>>,
}

impl<'a> TransformerCtx<'a> {
pub fn new(ast: Rc<AstBuilder<'a>>, semantic: Rc<RefCell<Semantic<'a>>>) -> Self {
Self { ast, semantic, errors: Rc::new(RefCell::new(vec![])) }
pub fn new(ast: Rc<AstBuilder<'a>>, semantic: Semantic<'a>, options: TransformOptions) -> Self {
Self {
ast,
semantic: Rc::new(RefCell::new(semantic)),
options: Cow::Owned(options),
errors: Rc::new(RefCell::new(vec![])),
}
}

pub fn semantic(&self) -> Ref<'_, Semantic<'a>> {
Expand Down Expand Up @@ -51,7 +60,7 @@ impl<'a> TransformerCtx<'a> {
}

/// Push a Transform Error
pub fn error<T: Into<Error>>(&mut self, error: T) {
pub fn error<T: Into<Error>>(&self, error: T) {
self.errors.borrow_mut().push(error.into());
}
}
16 changes: 6 additions & 10 deletions crates/oxc_transformer/src/es2015/arrow_functions.rs
Expand Up @@ -7,7 +7,6 @@ use oxc_span::{Atom, SPAN};
use serde::Deserialize;

use crate::context::TransformerCtx;
use crate::options::TransformOptions;
use crate::TransformTarget;

/// ES2015 Arrow Functions
Expand Down Expand Up @@ -61,15 +60,12 @@ impl<'a> VisitMut<'a> for ArrowFunctions<'a> {
}

impl<'a> ArrowFunctions<'a> {
pub fn new(
ast: Rc<AstBuilder<'a>>,
_: TransformerCtx<'a>,
options: &TransformOptions,
) -> Option<Self> {
(options.target < TransformTarget::ES2015 || options.arrow_functions.is_some()).then(|| {
let nodes = ast.new_vec();
Self { ast, uid: 0, nodes, has_this: false, insert: false }
})
pub fn new(ctx: TransformerCtx<'a>) -> Option<Self> {
(ctx.options.target < TransformTarget::ES2015 || ctx.options.arrow_functions.is_some())
.then(|| {
let nodes = ctx.ast.new_vec();
Self { ast: ctx.ast, uid: 0, nodes, has_this: false, insert: false }
})
}

fn get_this_name(&self) -> Atom<'a> {
Expand Down
7 changes: 4 additions & 3 deletions crates/oxc_transformer/src/es2015/duplicate_keys.rs
Expand Up @@ -5,7 +5,7 @@ use std::{collections::HashSet, rc::Rc};
use oxc_ast::{ast::*, AstBuilder};
use oxc_span::{CompactStr, SPAN};

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

/// ES2015: Duplicate Keys
///
Expand All @@ -17,8 +17,9 @@ pub struct DuplicateKeys<'a> {
}

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

pub fn transform_object_expression<'b>(&mut self, obj_expr: &'b mut ObjectExpression<'a>) {
Expand Down
31 changes: 12 additions & 19 deletions crates/oxc_transformer/src/es2015/function_name.rs
@@ -1,15 +1,12 @@
use std::rc::Rc;

// use lazy_static::lazy_static;
use oxc_ast::{ast::*, AstBuilder};
use oxc_ast::ast::*;
use oxc_semantic::ScopeId;
use oxc_span::{Atom, Span};
use oxc_syntax::identifier::is_identifier_part;
use oxc_syntax::operator::AssignmentOperator;
// use regex::Regex;

use crate::context::TransformerCtx;
use crate::options::TransformOptions;
use crate::utils::is_valid_identifier;
use crate::TransformTarget;

Expand All @@ -19,23 +16,19 @@ use crate::TransformTarget;
/// * <https://babel.dev/docs/babel-plugin-transform-function-name>
/// * <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-function-name>
pub struct FunctionName<'a> {
ast: Rc<AstBuilder<'a>>,
ctx: TransformerCtx<'a>,
unicode_escapes: bool,
}

impl<'a> FunctionName<'a> {
pub fn new(
ast: Rc<AstBuilder<'a>>,
ctx: TransformerCtx<'a>,
options: &TransformOptions,
) -> Option<Self> {
(options.target < TransformTarget::ES2015 || options.function_name).then_some(Self {
ast,
ctx,
// TODO hook up the plugin
unicode_escapes: true,
})
pub fn new(ctx: TransformerCtx<'a>) -> Option<Self> {
(ctx.options.target < TransformTarget::ES2015 || ctx.options.function_name).then_some(
Self {
ctx,
// TODO hook up the plugin
unicode_escapes: true,
},
)
}

pub fn transform_assignment_expression(&mut self, expr: &mut AssignmentExpression<'a>) {
Expand Down Expand Up @@ -125,7 +118,7 @@ impl<'a> FunctionName<'a> {

// If we're shadowing, change the name
if count > 0 {
id.name = self.ast.new_atom(&format!("{}{}", id.name, count));
id.name = self.ctx.ast.new_atom(&format!("{}{}", id.name, count));
}

if func.id.is_none() {
Expand Down Expand Up @@ -157,13 +150,13 @@ impl<'a> FunctionName<'a> {
atom.chars().map(|c| if is_identifier_part(c) { c } else { '_' }).collect::<String>();

let id = if id.is_empty() {
self.ast.new_atom("_")
self.ctx.ast.new_atom("_")
} else if id == "eval"
|| id == "arguments"
|| id == "null"
|| !is_valid_identifier(&id, true)
{
self.ast.new_atom(&format!("_{id}"))
self.ctx.ast.new_atom(&format!("_{id}"))
} else {
atom.clone()
};
Expand Down
37 changes: 15 additions & 22 deletions crates/oxc_transformer/src/es2015/instanceof.rs
@@ -1,12 +1,10 @@
use oxc_ast::{ast::*, AstBuilder, AstKind};
use oxc_ast::{ast::*, AstKind};
use oxc_semantic::AstNodeId;
use oxc_span::SPAN;
use std::rc::Rc;

use oxc_syntax::operator::BinaryOperator;

use crate::context::TransformerCtx;
use crate::options::TransformOptions;
use crate::TransformTarget;

/// ES2015: instanceof
Expand All @@ -15,18 +13,13 @@ use crate::TransformTarget;
/// * <https://babel.dev/docs/babel-plugin-transform-instanceof>
/// * <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-instanceof>
pub struct Instanceof<'a> {
ast: Rc<AstBuilder<'a>>,
ctx: TransformerCtx<'a>,
}

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

pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
Expand Down Expand Up @@ -54,23 +47,23 @@ impl<'a> Instanceof<'a> {
return;
}

let object = self.ast.identifier_reference_expression(IdentifierReference::new(
SPAN,
"babelHelpers".into(),
));
let object = self.ctx.ast.identifier_reference_expression(
IdentifierReference::new(SPAN, "babelHelpers".into()),
);

let property = IdentifierName::new(SPAN, "instanceof".into());
let helper = self.ast.member_expression(MemberExpression::StaticMemberExpression(
StaticMemberExpression { span: SPAN, object, property, optional: false },
));
let helper =
self.ctx.ast.member_expression(MemberExpression::StaticMemberExpression(
StaticMemberExpression { span: SPAN, object, property, optional: false },
));

let left = self.ast.copy(left);
let right = self.ast.copy(right);
let mut args = self.ast.new_vec_with_capacity(2);
let left = self.ctx.ast.copy(left);
let right = self.ctx.ast.copy(right);
let mut args = self.ctx.ast.new_vec_with_capacity(2);
args.push(Argument::Expression(left));
args.push(Argument::Expression(right));

*expr = self.ast.call_expression(SPAN, helper, args, false, None);
*expr = self.ctx.ast.call_expression(SPAN, helper, args, false, None);
}
}
}
Expand Down
13 changes: 5 additions & 8 deletions crates/oxc_transformer/src/es2015/literals.rs
Expand Up @@ -2,12 +2,9 @@ use std::rc::Rc;

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

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

/// ES2015: Shorthand Properties
/// ES2015: Literals
///
/// References:
/// * <https://babeljs.io/docs/babel-plugin-transform-literals>
Expand All @@ -19,8 +16,8 @@ pub struct Literals<'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)
pub fn new(ctx: TransformerCtx<'a>) -> Option<Self> {
(ctx.options.target < TransformTarget::ES2015 || ctx.options.literals)
.then_some(Self { _ast: ctx.ast })
}

Expand All @@ -33,7 +30,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,
// go generate them from their value.
// to generate them from their value.
lit.raw = "";
}
}
Expand Down
49 changes: 21 additions & 28 deletions crates/oxc_transformer/src/es2015/new_target.rs
@@ -1,18 +1,16 @@
use crate::{context::TransformerCtx, TransformOptions, TransformTarget};
use crate::{context::TransformerCtx, TransformTarget};
use oxc_allocator::Vec;
use oxc_ast::{ast::*, AstBuilder};
use oxc_ast::ast::*;
use oxc_diagnostics::miette;
use oxc_span::{Atom, Span, SPAN};
use oxc_syntax::operator::BinaryOperator;
use std::rc::Rc;

/// ES2015: New Target
///
/// References:
/// * <https://babel.dev/docs/babel-plugin-transform-template-new-target>
/// * <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-new-target>
pub struct NewTarget<'a> {
ast: Rc<AstBuilder<'a>>,
ctx: TransformerCtx<'a>,
kinds: Vec<'a, NewTargetKind<'a>>,
}
Expand Down Expand Up @@ -75,17 +73,10 @@ impl<'a> NewTarget<'a> {
}

impl<'a> NewTarget<'a> {
pub fn new(
ast: Rc<AstBuilder<'a>>,
ctx: TransformerCtx<'a>,
options: &TransformOptions,
) -> Option<Self> {
let kinds = ast.new_vec();
(options.target < TransformTarget::ES2015 || options.new_target).then_some(Self {
ast,
ctx,
kinds,
})
pub fn new(ctx: TransformerCtx<'a>) -> Option<Self> {
let kinds = ctx.ast.new_vec();
(ctx.options.target < TransformTarget::ES2015 || ctx.options.new_target)
.then_some(Self { ctx, kinds })
}

fn push(&mut self, kind: NewTargetKind<'a>) {
Expand All @@ -97,9 +88,9 @@ impl<'a> NewTarget<'a> {
}

fn create_constructor_expr(&self, span: Span) -> Expression<'a> {
self.ast.static_member_expression(
self.ctx.ast.static_member_expression(
span,
self.ast.this_expression(span),
self.ctx.ast.this_expression(span),
IdentifierName { span, name: "constructor".into() },
false,
)
Expand All @@ -114,33 +105,35 @@ impl<'a> NewTarget<'a> {
*expr = self.create_constructor_expr(meta.span);
}
NewTargetKind::Method => {
*expr = self.ast.void_0();
*expr = self.ctx.ast.void_0();
}
NewTargetKind::Function(name) => {
// TODO packages/babel-helper-create-class-features-plugin/src/fields.ts#L192 unshadow
// It will mutate previous ast node, it is difficult at now.
let id = name.clone().unwrap_or_else(|| {
self.ast.new_atom(self.ctx.scopes().generate_uid("target").as_str())
self.ctx
.ast
.new_atom(self.ctx.scopes().generate_uid("target").as_str())
});
let test = self.ast.binary_expression(
let test = self.ctx.ast.binary_expression(
SPAN,
self.ast.this_expression(SPAN),
self.ctx.ast.this_expression(SPAN),
BinaryOperator::Instanceof,
self.ast.identifier_reference_expression(IdentifierReference::new(
SPAN, id,
)),
self.ctx.ast.identifier_reference_expression(
IdentifierReference::new(SPAN, id),
),
);
let consequent = self.ast.static_member_expression(
let consequent = self.ctx.ast.static_member_expression(
SPAN,
self.ast.this_expression(SPAN),
self.ctx.ast.this_expression(SPAN),
IdentifierName { span: SPAN, name: "constructor".into() },
false,
);
*expr = self.ast.conditional_expression(
*expr = self.ctx.ast.conditional_expression(
meta.span,
test,
consequent,
self.ast.void_0(),
self.ctx.ast.void_0(),
);
}
}
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_transformer/src/es2015/shorthand_properties.rs
Expand Up @@ -3,7 +3,7 @@ use std::rc::Rc;
use oxc_ast::{ast::*, AstBuilder};
use oxc_span::GetSpan;

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

/// ES2015: Shorthand Properties
///
Expand All @@ -15,9 +15,9 @@ pub struct ShorthandProperties<'a> {
}

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

pub fn transform_object_property<'b>(&mut self, obj_prop: &'b mut ObjectProperty<'a>) {
Expand Down