mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
perf(transformer): call transform_jsx in exit_expression rather than enter_expression (#5751)
### Difference In `enter_expression`: Recursive transform JSX In `exit_expression`: Deep first transform After the change, `transform_jsx` still has a lot of room for improvement.
This commit is contained in:
parent
aac83168b3
commit
36e698b411
7 changed files with 84 additions and 31 deletions
|
|
@ -131,17 +131,37 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
|
|||
self.insert_this_var_statement_at_the_top_of_statements(&mut body.statements);
|
||||
}
|
||||
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
match expr {
|
||||
Expression::ArrowFunctionExpression(_) => {
|
||||
self.stacks.push(true);
|
||||
fn enter_jsx_element_name(
|
||||
&mut self,
|
||||
element_name: &mut JSXElementName<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if let JSXElementName::ThisExpression(this) = element_name {
|
||||
if !self.is_inside_arrow_function() {
|
||||
return;
|
||||
}
|
||||
Expression::FunctionExpression(_) => self.stacks.push(false),
|
||||
_ => {}
|
||||
|
||||
let ident = self.get_this_name(ctx).create_spanned_read_reference(this.span, ctx);
|
||||
*element_name = self.ctx.ast.jsx_element_name_from_identifier_reference(ident);
|
||||
};
|
||||
}
|
||||
|
||||
fn enter_jsx_member_expression_object(
|
||||
&mut self,
|
||||
object: &mut JSXMemberExpressionObject<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if let JSXMemberExpressionObject::ThisExpression(this) = object {
|
||||
if !self.is_inside_arrow_function() {
|
||||
return;
|
||||
}
|
||||
|
||||
let ident = self.get_this_name(ctx).create_spanned_read_reference(this.span, ctx);
|
||||
*object = self.ctx.ast.jsx_member_expression_object_from_identifier_reference(ident);
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
match expr {
|
||||
Expression::ThisExpression(this_expr) => {
|
||||
if !self.is_inside_arrow_function() {
|
||||
|
|
@ -152,6 +172,16 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
|
|||
self.get_this_name(ctx).create_spanned_read_reference(this_expr.span, ctx);
|
||||
*expr = self.ctx.ast.expression_from_identifier_reference(ident);
|
||||
}
|
||||
Expression::ArrowFunctionExpression(_) => {
|
||||
self.stacks.push(true);
|
||||
}
|
||||
Expression::FunctionExpression(_) => self.stacks.push(false),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
match expr {
|
||||
Expression::ArrowFunctionExpression(arrow_function_expr) => {
|
||||
*expr = self.transform_arrow_function_expression(arrow_function_expr, ctx);
|
||||
self.stacks.pop();
|
||||
|
|
|
|||
|
|
@ -96,4 +96,20 @@ impl<'a> Traverse<'a> for ES2015<'a> {
|
|||
self.arrow_functions.enter_variable_declarator(node, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_jsx_element_name(&mut self, node: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.enter_jsx_element_name(node, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_jsx_member_expression_object(
|
||||
&mut self,
|
||||
node: &mut JSXMemberExpressionObject<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.enter_jsx_member_expression_object(node, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,6 +228,18 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
self.x0_typescript.enter_jsx_element(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_element_name(&mut self, node: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x3_es2015.enter_jsx_element_name(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_member_expression_object(
|
||||
&mut self,
|
||||
node: &mut JSXMemberExpressionObject<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.x3_es2015.enter_jsx_member_expression_object(node, ctx);
|
||||
}
|
||||
|
||||
fn enter_jsx_fragment(&mut self, node: &mut JSXFragment<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.enter_jsx_fragment(node, ctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ impl<'a> Traverse<'a> for ReactJsx<'a> {
|
|||
self.add_runtime_imports(program, ctx);
|
||||
}
|
||||
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
*expr = match expr {
|
||||
Expression::JSXElement(e) => self.transform_jsx(&JSXElementOrFragment::Element(e), ctx),
|
||||
Expression::JSXFragment(e) => {
|
||||
|
|
|
|||
|
|
@ -96,12 +96,6 @@ impl<'a> Traverse<'a> for React<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.jsx_plugin {
|
||||
self.jsx.enter_expression(expr, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_call_expression(
|
||||
&mut self,
|
||||
call_expr: &mut CallExpression<'a>,
|
||||
|
|
@ -121,15 +115,20 @@ impl<'a> Traverse<'a> for React<'a> {
|
|||
elem: &mut JSXOpeningElement<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if self.jsx_self_plugin && self.jsx.jsx_self.can_add_self_attribute(ctx) {
|
||||
self.jsx.jsx_self.enter_jsx_opening_element(elem, ctx);
|
||||
}
|
||||
if self.jsx_source_plugin {
|
||||
self.jsx.jsx_source.enter_jsx_opening_element(elem, ctx);
|
||||
if !self.jsx_plugin {
|
||||
if self.jsx_self_plugin && self.jsx.jsx_self.can_add_self_attribute(ctx) {
|
||||
self.jsx.jsx_self.enter_jsx_opening_element(elem, ctx);
|
||||
}
|
||||
if self.jsx_source_plugin {
|
||||
self.jsx.jsx_source.enter_jsx_opening_element(elem, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.jsx_plugin {
|
||||
self.jsx.exit_expression(expr, ctx);
|
||||
}
|
||||
if self.refresh_plugin {
|
||||
self.refresh.exit_expression(expr, ctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5487,7 +5487,7 @@ Scope children mismatch:
|
|||
after transform: ScopeId(0): [ScopeId(1), ScopeId(8), ScopeId(9)]
|
||||
rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2)]
|
||||
Symbol reference IDs mismatch:
|
||||
after transform: SymbolId(0): [ReferenceId(6), ReferenceId(14), ReferenceId(17), ReferenceId(18), ReferenceId(20), ReferenceId(23), ReferenceId(24)]
|
||||
after transform: SymbolId(0): [ReferenceId(6), ReferenceId(15), ReferenceId(16), ReferenceId(18), ReferenceId(21), ReferenceId(22), ReferenceId(24)]
|
||||
rebuilt : SymbolId(1): [ReferenceId(0), ReferenceId(3), ReferenceId(5), ReferenceId(8), ReferenceId(10), ReferenceId(12)]
|
||||
Reference symbol mismatch:
|
||||
after transform: ReferenceId(8): Some("DropdownMenu")
|
||||
|
|
@ -21130,10 +21130,13 @@ rebuilt : ["undefined"]
|
|||
tasks/coverage/typescript/tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx
|
||||
semantic error: Bindings mismatch:
|
||||
after transform: ScopeId(0): ["Props", "React", "Wrapper", "_jsx", "_jsxFileName", "element"]
|
||||
rebuilt : ScopeId(0): ["Wrapper", "_jsx", "_jsxFileName", "element"]
|
||||
rebuilt : ScopeId(0): ["React", "Wrapper", "_jsx", "_jsxFileName", "element"]
|
||||
Scope children mismatch:
|
||||
after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
|
||||
rebuilt : ScopeId(0): [ScopeId(1)]
|
||||
Symbol reference IDs mismatch:
|
||||
after transform: SymbolId(0): [ReferenceId(0)]
|
||||
rebuilt : SymbolId(0): []
|
||||
|
||||
tasks/coverage/typescript/tests/cases/compiler/jsxFactoryAndJsxFragmentFactory.tsx
|
||||
semantic error: Bindings mismatch:
|
||||
|
|
@ -21371,10 +21374,7 @@ after transform: ["Function"]
|
|||
rebuilt : []
|
||||
|
||||
tasks/coverage/typescript/tests/cases/compiler/jsxPartialSpread.tsx
|
||||
semantic error: Bindings mismatch:
|
||||
after transform: ScopeId(0): ["React", "Repro", "Select", "_jsx", "_jsxFileName"]
|
||||
rebuilt : ScopeId(0): ["Repro", "Select", "_jsx", "_jsxFileName"]
|
||||
Symbol reference IDs mismatch:
|
||||
semantic error: Symbol reference IDs mismatch:
|
||||
after transform: SymbolId(0): [ReferenceId(2), ReferenceId(3)]
|
||||
rebuilt : SymbolId(0): [ReferenceId(3)]
|
||||
Unresolved references mismatch:
|
||||
|
|
|
|||
|
|
@ -1,19 +1,15 @@
|
|||
commit: 3bcfee23
|
||||
|
||||
Passed: 42/53
|
||||
Passed: 43/53
|
||||
|
||||
# All Passed:
|
||||
* babel-plugin-transform-nullish-coalescing-operator
|
||||
* babel-plugin-transform-optional-catch-binding
|
||||
* babel-plugin-transform-arrow-functions
|
||||
* babel-preset-typescript
|
||||
* regexp
|
||||
|
||||
|
||||
# babel-plugin-transform-arrow-functions (1/2)
|
||||
* with-this-member-expression/input.jsx
|
||||
x Output mismatch
|
||||
|
||||
|
||||
# babel-plugin-transform-typescript (1/8)
|
||||
* class-property-definition/input.ts
|
||||
Unresolved references mismatch:
|
||||
|
|
|
|||
Loading…
Reference in a new issue