mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
refactor(transformer): remove returning None from transform functions (#1079)
This commit is contained in:
parent
d411258be4
commit
c7a04f42e7
3 changed files with 60 additions and 58 deletions
|
|
@ -89,6 +89,12 @@ pub struct JSXNamespacedName {
|
||||||
pub property: JSXIdentifier,
|
pub property: JSXIdentifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for JSXNamespacedName {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}:{}", self.namespace.name, self.property.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// JSX Member Expression
|
/// JSX Member Expression
|
||||||
#[derive(Debug, Hash)]
|
#[derive(Debug, Hash)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
||||||
|
|
|
||||||
|
|
@ -77,14 +77,10 @@ impl<'a> ReactJsx<'a> {
|
||||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::JSXElement(e) => {
|
Expression::JSXElement(e) => {
|
||||||
if let Some(e) = self.transform_jsx(&JSXElementOrFragment::Element(e)) {
|
*expr = self.transform_jsx(&JSXElementOrFragment::Element(e));
|
||||||
*expr = e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Expression::JSXFragment(e) => {
|
Expression::JSXFragment(e) => {
|
||||||
if let Some(e) = self.transform_jsx(&JSXElementOrFragment::Fragment(e)) {
|
*expr = self.transform_jsx(&JSXElementOrFragment::Fragment(e));
|
||||||
*expr = e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +154,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
self.imports.push(decl);
|
self.imports.push(decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_jsx<'b>(&mut self, e: &JSXElementOrFragment<'a, 'b>) -> Option<Expression<'a>> {
|
fn transform_jsx<'b>(&mut self, e: &JSXElementOrFragment<'a, 'b>) -> Expression<'a> {
|
||||||
let is_classic = self.options.runtime.is_classic();
|
let is_classic = self.options.runtime.is_classic();
|
||||||
let is_automatic = self.options.runtime.is_automatic();
|
let is_automatic = self.options.runtime.is_automatic();
|
||||||
let has_key_after_props_spread = e.has_key_after_props_spread();
|
let has_key_after_props_spread = e.has_key_after_props_spread();
|
||||||
|
|
@ -170,7 +166,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
|
|
||||||
arguments.push(Argument::Expression(match e {
|
arguments.push(Argument::Expression(match e {
|
||||||
JSXElementOrFragment::Element(e) => {
|
JSXElementOrFragment::Element(e) => {
|
||||||
self.transform_element_name(&e.opening_element.name)?
|
self.transform_element_name(&e.opening_element.name)
|
||||||
}
|
}
|
||||||
JSXElementOrFragment::Fragment(_) => self.get_fragment(),
|
JSXElementOrFragment::Fragment(_) => self.get_fragment(),
|
||||||
}));
|
}));
|
||||||
|
|
@ -188,7 +184,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let key = self.get_attribute_name(&attr.name);
|
let key = self.get_attribute_name(&attr.name);
|
||||||
let value = self.transform_jsx_attribute_value(attr.value.as_ref())?;
|
let value = self.transform_jsx_attribute_value(attr.value.as_ref());
|
||||||
let object_property = self
|
let object_property = self
|
||||||
.ast
|
.ast
|
||||||
.object_property(SPAN, kind, key, value, None, false, false, false);
|
.object_property(SPAN, kind, key, value, None, false, false, false);
|
||||||
|
|
@ -220,7 +216,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
let key =
|
let key =
|
||||||
self.ast.property_key_identifier(IdentifierName::new(SPAN, "children".into()));
|
self.ast.property_key_identifier(IdentifierName::new(SPAN, "children".into()));
|
||||||
let value = if children.len() == 1 {
|
let value = if children.len() == 1 {
|
||||||
self.transform_jsx_child(&children[0])?
|
self.transform_jsx_child(&children[0])
|
||||||
} else {
|
} else {
|
||||||
let mut elements = self.ast.new_vec_with_capacity(children.len());
|
let mut elements = self.ast.new_vec_with_capacity(children.len());
|
||||||
for child in children {
|
for child in children {
|
||||||
|
|
@ -228,19 +224,21 @@ impl<'a> ReactJsx<'a> {
|
||||||
elements.push(ArrayExpressionElement::Expression(e));
|
elements.push(ArrayExpressionElement::Expression(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.ast.array_expression(SPAN, elements, None)
|
Some(self.ast.array_expression(SPAN, elements, None))
|
||||||
};
|
};
|
||||||
let object_property = self.ast.object_property(
|
if let Some(value) = value {
|
||||||
SPAN,
|
let object_property = self.ast.object_property(
|
||||||
PropertyKind::Init,
|
SPAN,
|
||||||
key,
|
PropertyKind::Init,
|
||||||
value,
|
key,
|
||||||
None,
|
value,
|
||||||
false,
|
None,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
);
|
false,
|
||||||
properties.push(ObjectPropertyKind::ObjectProperty(object_property));
|
);
|
||||||
|
properties.push(ObjectPropertyKind::ObjectProperty(object_property));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !properties.is_empty() || is_automatic {
|
if !properties.is_empty() || is_automatic {
|
||||||
|
|
@ -249,7 +247,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_automatic && key.is_some() {
|
if is_automatic && key.is_some() {
|
||||||
arguments.push(Argument::Expression(self.transform_jsx_attribute_value(key)?));
|
arguments.push(Argument::Expression(self.transform_jsx_attribute_value(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_classic && !children.is_empty() {
|
if is_classic && !children.is_empty() {
|
||||||
|
|
@ -263,7 +261,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
|
|
||||||
self.add_import(e, has_key_after_props_spread);
|
self.add_import(e, has_key_after_props_spread);
|
||||||
|
|
||||||
Some(self.ast.call_expression(SPAN, callee, arguments, false, None))
|
self.ast.call_expression(SPAN, callee, arguments, false, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_react_references(&mut self) -> Expression<'a> {
|
fn get_react_references(&mut self) -> Expression<'a> {
|
||||||
|
|
@ -312,42 +310,34 @@ impl<'a> ReactJsx<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JSXAttributeName::NamespacedName(name) => {
|
JSXAttributeName::NamespacedName(name) => {
|
||||||
let name = format!("{}:{}", name.namespace.name, name.property.name);
|
let name = Atom::from(name.to_string());
|
||||||
let expr =
|
let expr = self.ast.literal_string_expression(StringLiteral::new(SPAN, name));
|
||||||
self.ast.literal_string_expression(StringLiteral::new(SPAN, name.into()));
|
|
||||||
self.ast.property_key_expression(expr)
|
self.ast.property_key_expression(expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_element_name(&self, name: &JSXElementName<'a>) -> Option<Expression<'a>> {
|
fn transform_element_name(&self, name: &JSXElementName<'a>) -> Expression<'a> {
|
||||||
match name {
|
match name {
|
||||||
JSXElementName::Identifier(ident) => {
|
JSXElementName::Identifier(ident) => {
|
||||||
let name = ident.name.clone();
|
let name = ident.name.clone();
|
||||||
Some(if ident.name.chars().next().is_some_and(|c| c.is_ascii_lowercase()) {
|
if ident.name.chars().next().is_some_and(|c| c.is_ascii_lowercase()) {
|
||||||
self.ast.literal_string_expression(StringLiteral::new(SPAN, name))
|
self.ast.literal_string_expression(StringLiteral::new(SPAN, name))
|
||||||
} else {
|
} else {
|
||||||
self.ast.identifier_reference_expression(IdentifierReference::new(SPAN, name))
|
self.ast.identifier_reference_expression(IdentifierReference::new(SPAN, name))
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
JSXElementName::MemberExpression(member_expr) => {
|
JSXElementName::MemberExpression(member_expr) => {
|
||||||
Some(self.transform_jsx_member_expression(member_expr))
|
self.transform_jsx_member_expression(member_expr)
|
||||||
}
|
}
|
||||||
JSXElementName::NamespacedName(namespaced_name) => {
|
JSXElementName::NamespacedName(name) => {
|
||||||
if self.options.throw_if_namespace.is_some_and(|v| !v) {
|
// TODO
|
||||||
// If the flag "throwIfNamespace" is false
|
// If the flag "throwIfNamespace" is false
|
||||||
// print XMLNamespace like string literal
|
// print XMLNamespace like string literal
|
||||||
let string_literal = StringLiteral::new(
|
// if self.options.throw_if_namespace.is_some_and(|v| !v) {
|
||||||
SPAN,
|
// }
|
||||||
Atom::from(format!(
|
let string_literal = StringLiteral::new(SPAN, Atom::from(name.to_string()));
|
||||||
"{}:{}",
|
self.ast.literal_string_expression(string_literal)
|
||||||
namespaced_name.namespace.name, namespaced_name.property.name
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
|
|
||||||
return Some(self.ast.literal_string_expression(string_literal));
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -355,10 +345,10 @@ impl<'a> ReactJsx<'a> {
|
||||||
fn transform_jsx_attribute_value(
|
fn transform_jsx_attribute_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: Option<&JSXAttributeValue<'a>>,
|
value: Option<&JSXAttributeValue<'a>>,
|
||||||
) -> Option<Expression<'a>> {
|
) -> Expression<'a> {
|
||||||
match value {
|
match value {
|
||||||
Some(JSXAttributeValue::StringLiteral(s)) => {
|
Some(JSXAttributeValue::StringLiteral(s)) => {
|
||||||
Some(self.ast.literal_string_expression(s.clone()))
|
self.ast.literal_string_expression(s.clone())
|
||||||
}
|
}
|
||||||
Some(JSXAttributeValue::Element(e)) => {
|
Some(JSXAttributeValue::Element(e)) => {
|
||||||
self.transform_jsx(&JSXElementOrFragment::Element(e))
|
self.transform_jsx(&JSXElementOrFragment::Element(e))
|
||||||
|
|
@ -367,12 +357,12 @@ impl<'a> ReactJsx<'a> {
|
||||||
self.transform_jsx(&JSXElementOrFragment::Fragment(e))
|
self.transform_jsx(&JSXElementOrFragment::Fragment(e))
|
||||||
}
|
}
|
||||||
Some(JSXAttributeValue::ExpressionContainer(c)) => match &c.expression {
|
Some(JSXAttributeValue::ExpressionContainer(c)) => match &c.expression {
|
||||||
JSXExpression::Expression(e) => Some(self.ast.copy(e)),
|
JSXExpression::Expression(e) => self.ast.copy(e),
|
||||||
JSXExpression::EmptyExpression(_e) => {
|
JSXExpression::EmptyExpression(_e) => {
|
||||||
Some(self.ast.literal_boolean_expression(BooleanLiteral::new(SPAN, true)))
|
self.ast.literal_boolean_expression(BooleanLiteral::new(SPAN, true))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Some(self.ast.literal_boolean_expression(BooleanLiteral::new(SPAN, true))),
|
None => self.ast.literal_boolean_expression(BooleanLiteral::new(SPAN, true)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,9 +401,12 @@ impl<'a> ReactJsx<'a> {
|
||||||
JSXExpression::Expression(e) => Some(self.ast.copy(e)),
|
JSXExpression::Expression(e) => Some(self.ast.copy(e)),
|
||||||
JSXExpression::EmptyExpression(_) => None,
|
JSXExpression::EmptyExpression(_) => None,
|
||||||
},
|
},
|
||||||
JSXChild::Element(e) => self.transform_jsx(&JSXElementOrFragment::Element(e)),
|
JSXChild::Element(e) => Some(self.transform_jsx(&JSXElementOrFragment::Element(e))),
|
||||||
JSXChild::Fragment(e) => self.transform_jsx(&JSXElementOrFragment::Fragment(e)),
|
JSXChild::Fragment(e) => Some(self.transform_jsx(&JSXElementOrFragment::Fragment(e))),
|
||||||
JSXChild::Spread(_) => None,
|
JSXChild::Spread(_) => {
|
||||||
|
// Babel: Spread children are not supported in React.
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Passed: 217/1083
|
Passed: 214/1083
|
||||||
|
|
||||||
# All Passed:
|
# All Passed:
|
||||||
* babel-plugin-transform-numeric-separator
|
* babel-plugin-transform-numeric-separator
|
||||||
|
|
@ -804,7 +804,7 @@ Passed: 217/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 (68/172)
|
# babel-plugin-transform-react-jsx (65/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
|
||||||
|
|
@ -851,6 +851,7 @@ Passed: 217/1083
|
||||||
* react/should-allow-pragmafrag-and-frag/input.js
|
* react/should-allow-pragmafrag-and-frag/input.js
|
||||||
* react/should-disallow-spread-children/input.js
|
* react/should-disallow-spread-children/input.js
|
||||||
* react/should-disallow-valueless-key/input.js
|
* react/should-disallow-valueless-key/input.js
|
||||||
|
* react/should-disallow-xml-namespacing/input.js
|
||||||
* react/should-escape-xhtml-jsxattribute/input.js
|
* react/should-escape-xhtml-jsxattribute/input.js
|
||||||
* react/should-escape-xhtml-jsxattribute-babel-7/input.js
|
* react/should-escape-xhtml-jsxattribute-babel-7/input.js
|
||||||
* react/should-escape-xhtml-jsxtext/input.js
|
* react/should-escape-xhtml-jsxtext/input.js
|
||||||
|
|
@ -859,6 +860,7 @@ Passed: 217/1083
|
||||||
* react/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
* react/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
||||||
* react/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
* react/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
||||||
* react/should-support-xml-namespaces-if-flag/input.js
|
* react/should-support-xml-namespaces-if-flag/input.js
|
||||||
|
* react/should-throw-error-namespaces-if-not-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/weird-symbols/input.js
|
* react/weird-symbols/input.js
|
||||||
|
|
@ -879,19 +881,20 @@ Passed: 217/1083
|
||||||
* react-automatic/should-add-quotes-es3/input.js
|
* react-automatic/should-add-quotes-es3/input.js
|
||||||
* react-automatic/should-allow-nested-fragments/input.js
|
* react-automatic/should-allow-nested-fragments/input.js
|
||||||
* react-automatic/should-avoid-wrapping-in-extra-parens-if-not-needed/input.js
|
* react-automatic/should-avoid-wrapping-in-extra-parens-if-not-needed/input.js
|
||||||
|
* react-automatic/should-disallow-spread-children/input.js
|
||||||
* react-automatic/should-disallow-valueless-key/input.js
|
* react-automatic/should-disallow-valueless-key/input.js
|
||||||
|
* react-automatic/should-disallow-xml-namespacing/input.js
|
||||||
* react-automatic/should-escape-xhtml-jsxattribute/input.js
|
* react-automatic/should-escape-xhtml-jsxattribute/input.js
|
||||||
* react-automatic/should-escape-xhtml-jsxattribute-babel-7/input.js
|
* react-automatic/should-escape-xhtml-jsxattribute-babel-7/input.js
|
||||||
* react-automatic/should-escape-xhtml-jsxtext/input.js
|
* react-automatic/should-escape-xhtml-jsxtext/input.js
|
||||||
* react-automatic/should-escape-xhtml-jsxtext-babel-7/input.js
|
* react-automatic/should-escape-xhtml-jsxtext-babel-7/input.js
|
||||||
* react-automatic/should-handle-attributed-elements/input.js
|
* react-automatic/should-handle-attributed-elements/input.js
|
||||||
* react-automatic/should-have-correct-comma-in-nested-children/input.js
|
* react-automatic/should-have-correct-comma-in-nested-children/input.js
|
||||||
* react-automatic/should-insert-commas-after-expressions-before-whitespace/input.js
|
|
||||||
* react-automatic/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
* react-automatic/should-not-strip-nbsp-even-coupled-with-other-whitespace/input.js
|
||||||
* react-automatic/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
* react-automatic/should-not-strip-tags-with-a-single-child-of-nbsp/input.js
|
||||||
* react-automatic/should-properly-handle-comments-between-props/input.js
|
* react-automatic/should-properly-handle-comments-between-props/input.js
|
||||||
* react-automatic/should-properly-handle-keys/input.js
|
* react-automatic/should-properly-handle-keys/input.js
|
||||||
* react-automatic/should-support-xml-namespaces-if-flag/input.js
|
* react-automatic/should-throw-error-namespaces-if-not-flag/input.js
|
||||||
* react-automatic/should-throw-when-filter-is-specified/input.js
|
* react-automatic/should-throw-when-filter-is-specified/input.js
|
||||||
* react-automatic/should-warn-when-pragma-or-pragmaFrag-is-set/input.js
|
* react-automatic/should-warn-when-pragma-or-pragmaFrag-is-set/input.js
|
||||||
* react-automatic/weird-symbols/input.js
|
* react-automatic/weird-symbols/input.js
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue