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

fix(transformer): ensure last expression statement in arrow function expression is wrapped in return #8192

Merged
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
34 changes: 23 additions & 11 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,18 +482,30 @@ impl<'a, 'ctx> Traverse<'a> for TransformerImpl<'a, 'ctx> {
// which can cause issues with the `() => x;` case, as it only allows a single statement.
// To address this, we wrap the last statement in a return statement and set the expression to false.
// This transforms the arrow function into the form `() => { return x; };`.
if arrow.expression && arrow.body.statements.len() > 1 {
let Statement::ExpressionStatement(statement) = arrow.body.statements.pop().unwrap()
else {
unreachable!(
"The last statement in an ArrowFunctionExpression should always be an ExpressionStatement."
)
};
arrow
.body
.statements
.push(ctx.ast.statement_return(SPAN, Some(statement.unbox().expression)));
let statements = &mut arrow.body.statements;
if arrow.expression && statements.len() > 1 {
arrow.expression = false;

// Reverse looping to find the expression statement, because other plugins could
// insert new statements after the expression statement.
// `() => x;`
// ->
// ```
// () => {
// var new_insert_variable;
// return x;
// function new_insert_function() {}
// };
// ```
for stmt in statements.iter_mut().rev() {
let Statement::ExpressionStatement(expr_stmt) = stmt else {
continue;
};
let expression = Some(ctx.ast.move_expression(&mut expr_stmt.expression));
*stmt = ctx.ast.statement_return(SPAN, expression);
return;
}
unreachable!("At least one statement should be expression statement")
}
}

Expand Down
Loading