From ea2957032101a30e56b855c03f9f4240b875a2c8 Mon Sep 17 00:00:00 2001 From: Boshen Date: Fri, 12 Apr 2024 12:38:00 +0800 Subject: [PATCH] feat(transformer): implement react-jsx-self --- crates/oxc_ast/src/ast/jsx.rs | 6 ++++ crates/oxc_transformer/src/lib.rs | 5 ++++ .../oxc_transformer/src/react/jsx_self/mod.rs | 29 +++++++++++++++++++ crates/oxc_transformer/src/react/mod.rs | 4 +++ tasks/transform_conformance/babel.snap.md | 6 +++- tasks/transform_conformance/src/lib.rs | 1 + 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/crates/oxc_ast/src/ast/jsx.rs b/crates/oxc_ast/src/ast/jsx.rs index 3d671111266e0d..d41e78c23024ee 100644 --- a/crates/oxc_ast/src/ast/jsx.rs +++ b/crates/oxc_ast/src/ast/jsx.rs @@ -227,6 +227,12 @@ pub struct JSXIdentifier<'a> { pub name: Atom<'a>, } +impl<'a> JSXIdentifier<'a> { + pub fn new(span: Span, name: Atom<'a>) -> Self { + Self { span, name } + } +} + // 1.4 JSX Children /// JSX Child diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index 2029c6ec4475ae..827f0afd126dac 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -122,4 +122,9 @@ impl<'a> VisitMut<'a> for Transformer<'a> { self.x1_react.transform_export_default_declaration(decl); walk_mut::walk_export_default_declaration_mut(self, decl); } + + fn visit_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) { + self.x1_react.transform_jsx_opening_element(elem); + walk_mut::walk_jsx_opening_element_mut(self, elem); + } } diff --git a/crates/oxc_transformer/src/react/jsx_self/mod.rs b/crates/oxc_transformer/src/react/jsx_self/mod.rs index d891216257eefe..bd77da418a12a1 100644 --- a/crates/oxc_transformer/src/react/jsx_self/mod.rs +++ b/crates/oxc_transformer/src/react/jsx_self/mod.rs @@ -1,5 +1,8 @@ use std::rc::Rc; +use oxc_ast::ast::*; +use oxc_span::SPAN; + use crate::context::Ctx; /// [plugin-transform-react-jsx-self](https://babeljs.io/docs/babel-plugin-transform-react-jsx-self) @@ -19,4 +22,30 @@ impl<'a> ReactJsxSelf<'a> { pub fn new(ctx: &Ctx<'a>) -> Self { Self { ctx: Rc::clone(ctx) } } + + pub fn transform_jsx_opening_element(&self, elem: &mut JSXOpeningElement<'a>) { + self.add_self_this_attribute(elem); + } +} + +impl<'a> ReactJsxSelf<'a> { + /// `
` + /// ^^^^^^^^^^^^^ + fn add_self_this_attribute(&self, elem: &mut JSXOpeningElement<'a>) { + let name = { + let name = self.ctx.ast.new_atom("__self"); + JSXAttributeName::Identifier(JSXIdentifier::new(SPAN, name)) + }; + let value = { + let this_expr = self.ctx.ast.this_expression(SPAN); + let jsx_expr = JSXExpression::Expression(this_expr); + let container = self.ctx.ast.jsx_expression_container(SPAN, jsx_expr); + JSXAttributeValue::ExpressionContainer(container) + }; + let attribute = { + let attribute = self.ctx.ast.jsx_attribute(SPAN, name, Some(value)); + JSXAttributeItem::Attribute(attribute) + }; + elem.attributes.push(attribute); + } } diff --git a/crates/oxc_transformer/src/react/mod.rs b/crates/oxc_transformer/src/react/mod.rs index b176ba9152ac19..bb484f69000dfb 100644 --- a/crates/oxc_transformer/src/react/mod.rs +++ b/crates/oxc_transformer/src/react/mod.rs @@ -76,4 +76,8 @@ impl<'a> React<'a> { ) { self.display_name.transform_export_default_declaration(decl); } + + pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) { + self.jsx_self.transform_jsx_opening_element(elem); + } } diff --git a/tasks/transform_conformance/babel.snap.md b/tasks/transform_conformance/babel.snap.md index 4a2f7375340129..8e51e47b9316ba 100644 --- a/tasks/transform_conformance/babel.snap.md +++ b/tasks/transform_conformance/babel.snap.md @@ -1,4 +1,4 @@ -Passed: 75/174 +Passed: 76/177 # All Passed: @@ -107,3 +107,7 @@ Passed: 75/174 # babel-plugin-transform-react-display-name (15/16) * display-name/nested/input.js +# babel-plugin-transform-react-jsx-self (1/3) +* react-source/arrow-function/input.js +* react-source/disable-with-super/input.js + diff --git a/tasks/transform_conformance/src/lib.rs b/tasks/transform_conformance/src/lib.rs index 8df21dfec601ed..4a1f8c9a7eb041 100644 --- a/tasks/transform_conformance/src/lib.rs +++ b/tasks/transform_conformance/src/lib.rs @@ -94,6 +94,7 @@ const CASES: &[&str] = &[ // React // "babel-plugin-transform-react-jsx", "babel-plugin-transform-react-display-name", + "babel-plugin-transform-react-jsx-self", // // Proposal // "babel-plugin-proposal-decorators", ];