feat(transform): transform jsx element name (#1070)

This commit is contained in:
Wenzhe Wang 2023-10-27 08:13:40 +08:00 committed by GitHub
parent d9ba532ca6
commit b5bfc361fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 8 deletions

View file

@ -4,7 +4,7 @@ use std::rc::Rc;
use oxc_allocator::Vec; use oxc_allocator::Vec;
use oxc_ast::{ast::*, AstBuilder}; use oxc_ast::{ast::*, AstBuilder};
use oxc_span::SPAN; use oxc_span::{Atom, SPAN};
pub use self::options::{ReactJsxOptions, ReactJsxRuntime}; pub use self::options::{ReactJsxOptions, ReactJsxRuntime};
@ -105,13 +105,44 @@ impl<'a> ReactJsx<'a> {
self.ast.identifier_reference_expression(IdentifierReference::new(SPAN, name)) self.ast.identifier_reference_expression(IdentifierReference::new(SPAN, name))
}) })
} }
_ => { JSXElementName::MemberExpression(member_expr) => {
/* TODO */ Some(self.transform_jsx_member_expression(member_expr))
}
JSXElementName::NamespacedName(namespaced_name) => {
if self.options.throw_if_namespace.is_some_and(|v| !v) {
// If the flag "throwIfNamespace" is false
// print XMLNamespace like string literal
let string_literal = StringLiteral::new(
SPAN,
Atom::from(format!(
"{}:{}",
namespaced_name.namespace.name, namespaced_name.property.name
)),
);
return Some(self.ast.literal_string_expression(string_literal));
}
None None
} }
} }
} }
fn transform_jsx_member_expression(&self, expr: &JSXMemberExpression<'a>) -> Expression<'a> {
let object = match &expr.object {
JSXMemberExpressionObject::Identifier(ident) => {
self.ast.identifier_reference_expression(IdentifierReference::new(
SPAN,
ident.name.clone(),
))
}
JSXMemberExpressionObject::MemberExpression(expr) => {
self.transform_jsx_member_expression(expr)
}
};
let property = IdentifierName::new(SPAN, expr.property.name.clone());
self.ast.static_member_expression(SPAN, object, property, false)
}
fn transform_jsx_attributes( fn transform_jsx_attributes(
&self, &self,
attributes: &Vec<'a, JSXAttributeItem<'a>>, attributes: &Vec<'a, JSXAttributeItem<'a>>,

View file

@ -4,6 +4,9 @@ use serde::Deserialize;
pub struct ReactJsxOptions { pub struct ReactJsxOptions {
/// Decides which runtime to use. /// Decides which runtime to use.
pub runtime: ReactJsxRuntime, pub runtime: ReactJsxRuntime,
/// Toggles whether or not to throw an error if an XML namespaced tag name is used. e.g. `<f:image />`
/// Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it.
pub throw_if_namespace: Option<bool>,
} }
#[derive(Debug, Default, Clone, Copy, Deserialize)] #[derive(Debug, Default, Clone, Copy, Deserialize)]

View file

@ -1,4 +1,4 @@
Passed: 187/1083 Passed: 190/1083
# All Passed: # All Passed:
* babel-plugin-transform-numeric-separator * babel-plugin-transform-numeric-separator
@ -804,7 +804,7 @@ Passed: 187/1083
* regression/11061/input.mjs * regression/11061/input.mjs
* variable-declaration/non-null-in-optional-chain/input.ts * variable-declaration/non-null-in-optional-chain/input.ts
# babel-plugin-transform-react-jsx (38/172) # babel-plugin-transform-react-jsx (41/172)
* autoImport/after-polyfills/input.mjs * autoImport/after-polyfills/input.mjs
* autoImport/after-polyfills-2/input.mjs * autoImport/after-polyfills-2/input.mjs
* autoImport/after-polyfills-compiled-to-cjs/input.mjs * autoImport/after-polyfills-compiled-to-cjs/input.mjs
@ -847,9 +847,7 @@ Passed: 187/1083
* react/optimisation.react.constant-elements/input.js * react/optimisation.react.constant-elements/input.js
* react/pragma-works-with-no-space-at-the-end/input.js * react/pragma-works-with-no-space-at-the-end/input.js
* react/should-add-quotes-es3/input.js * react/should-add-quotes-es3/input.js
* react/should-allow-deeper-js-namespacing/input.js
* react/should-allow-elements-as-attributes/input.js * react/should-allow-elements-as-attributes/input.js
* react/should-allow-js-namespacing/input.js
* react/should-allow-jsx-docs-comment-with-pragma/input.js * react/should-allow-jsx-docs-comment-with-pragma/input.js
* react/should-allow-nested-fragments/input.js * react/should-allow-nested-fragments/input.js
* react/should-allow-no-pragmafrag-if-frag-unused/input.js * react/should-allow-no-pragmafrag-if-frag-unused/input.js
@ -869,7 +867,6 @@ Passed: 187/1083
* react/should-support-xml-namespaces-if-flag/input.js * react/should-support-xml-namespaces-if-flag/input.js
* react/should-warn-when-importSource-is-set/input.js * react/should-warn-when-importSource-is-set/input.js
* react/should-warn-when-importSource-pragma-is-set/input.js * react/should-warn-when-importSource-pragma-is-set/input.js
* react/this-tag-name/input.js
* react/weird-symbols/input.js * react/weird-symbols/input.js
* react/wraps-props-in-react-spread-for-first-spread-attributes-babel-7/input.js * react/wraps-props-in-react-spread-for-first-spread-attributes-babel-7/input.js
* react/wraps-props-in-react-spread-for-last-spread-attributes-babel-7/input.js * react/wraps-props-in-react-spread-for-last-spread-attributes-babel-7/input.js

View file

@ -210,6 +210,8 @@ impl TestCase for ConformanceTestCase {
if filtered { if filtered {
println!("Input:\n"); println!("Input:\n");
println!("{input}\n"); println!("{input}\n");
println!("Options:");
println!("{:?}\n", self.transform_options());
println!("Output:\n"); println!("Output:\n");
println!("{output}\n"); println!("{output}\n");
println!("Transformed:\n"); println!("Transformed:\n");