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): implement @babel/plugin-transform-react-jsx-self #2846

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/oxc_transformer/examples/test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function App() {
return (
<sometag />
)
}
1 change: 1 addition & 0 deletions crates/oxc_transformer/examples/transformer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ fn main() {
target: TransformTarget::ES5,
react_jsx: Some(ReactJsxOptions {
runtime: Some(ReactJsxRuntimeOption::Valid(ReactJsxRuntime::Classic)),
development: Some(true),
..ReactJsxOptions::default()
}),
..TransformOptions::default()
Expand Down
8 changes: 7 additions & 1 deletion crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use crate::{
es2021::{LogicalAssignmentOperators, NumericSeparator},
es2022::ClassStaticBlock,
es3::PropertyLiteral,
react_jsx::ReactJsx,
react_jsx::{JsxSelf, ReactJsx},
regexp::RegexpFlags,
typescript::TypeScript,
utils::CreateVars,
Expand All @@ -72,6 +72,7 @@ pub struct Transformer<'a> {
decorators: Option<Decorators<'a>>,
#[allow(unused)]
typescript: Option<TypeScript<'a>>,
jsx_self: Option<JsxSelf<'a>>,
react_jsx: Option<ReactJsx<'a>>,
regexp_flags: Option<RegexpFlags<'a>>,
// es2022
Expand Down Expand Up @@ -140,6 +141,7 @@ impl<'a> Transformer<'a> {
es2015_new_target: NewTarget::new(ctx.clone()),
// other
es3_property_literal: PropertyLiteral::new(ctx.clone()),
jsx_self: JsxSelf::new(ctx.clone()),
react_jsx: ReactJsx::new(ctx.clone()),
// original context
ctx,
Expand Down Expand Up @@ -202,6 +204,10 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
self.decorators.as_mut().map(|t| t.transform_declaration(decl));
}

fn visit_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that visit_jsx_opening_element will execute after visit_expression, so the jsx_self transformer will execute after react_jsx transformer, maybe i need to move self.jsx_self.as_mut().map(|t| t.transform_jsx_opening_element(elem)); into visit_expression ?

self.jsx_self.as_mut().map(|t| t.transform_jsx_opening_element(elem));
}

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));
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,6 +10,8 @@ pub struct TransformOptions {
pub target: TransformTarget,
pub assumptions: CompilerAssumptions,

pub jsx_self: Option<ReactJsxOptions>,

pub react_jsx: Option<ReactJsxOptions>,

pub typescript: Option<TypescriptOptions>,
Expand Down
35 changes: 35 additions & 0 deletions crates/oxc_transformer/src/react_jsx/jsx_self.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::{context::TransformerCtx, ReactJsxOptions};
use oxc_ast::ast::*;
use oxc_span::SPAN;

/// @babel/plugin-transform-react-jsx-self
///
/// References:
/// * <https://babeljs.io/docs/babel-plugin-transform-react-jsx-self>
/// * <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-react-jsx-self>
///
pub struct JsxSelf<'a> {
ctx: TransformerCtx<'a>,
options: ReactJsxOptions,
}

impl<'a> JsxSelf<'a> {
pub fn new(ctx: TransformerCtx<'a>) -> Option<Self> {
let jsx_options = ctx.options.react_jsx.clone()?;
Some(Self { ctx, options: jsx_options })
}
pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
if self.options.development != Some(true) {
return;
}

elem.attributes.push(JSXAttributeItem::Attribute(self.ctx.ast.jsx_attribute(
SPAN,
JSXAttributeName::Identifier(self.ctx.ast.jsx_identifier(SPAN, "__self".into())),
Some(JSXAttributeValue::ExpressionContainer(self.ctx.ast.jsx_expression_container(
SPAN,
JSXExpression::Expression(self.ctx.ast.this_expression(SPAN)),
))),
)));
}
}
2 changes: 2 additions & 0 deletions crates/oxc_transformer/src/react_jsx/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod jsx_self;
mod options;

use oxc_allocator::Vec;
Expand All @@ -12,6 +13,7 @@ use oxc_syntax::{
xml_entities::XML_ENTITIES,
};

pub use self::jsx_self::JsxSelf;
pub use self::options::{ReactJsxOptions, ReactJsxRuntime, ReactJsxRuntimeOption};
use crate::context::TransformerCtx;

Expand Down
5 changes: 5 additions & 0 deletions crates/oxc_transformer/src/react_jsx/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ pub struct ReactJsxOptions {
/// Use `Some<T>` instead of `bool` because we want to know if user set this field explicitly,
/// which used for creating warning, <https://github.com/oxc-project/oxc/blob/c3e2098c04d8916cb812bdd16d2026bb430ac25f/crates/oxc_transformer/src/react_jsx/mod.rs#L111-L114>
pub use_spread: Option<bool>,

/// enable development transform for jsx transform
#[serde(default)]
pub development: Option<bool>,
}

fn default_throw_if_namespace() -> bool {
Expand Down Expand Up @@ -62,6 +66,7 @@ impl Default for ReactJsxOptions {
pragma_frag: default_pragma_frag(),
use_built_ins: None,
use_spread: None,
development: None,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions tasks/transform_conformance/src/test_case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ pub trait TestCase {
decorators: options
.get_plugin("proposal-decorators")
.map(get_options::<DecoratorsOptions>),
jsx_self: options
.get_plugin("transform-react-jsx-self")
.map(get_options::<ReactJsxOptions>),
react_jsx: options
.get_plugin("transform-react-jsx")
.map(get_options::<ReactJsxOptions>),
Expand Down
Loading