diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index f6872da1117e..62e1d2877d7e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -2596,11 +2596,17 @@ function lowerExpression( // Store the previous value to a temporary const previousValuePlace = lowerValueToTemporary(builder, value); + const capturedPreviousValue = lowerValueToTemporary(builder, { + kind: 'LoadLocal', + place: {...previousValuePlace}, + loc: exprLoc, + }); + // Store the new value to a temporary const updatedValue = lowerValueToTemporary(builder, { kind: 'BinaryExpression', operator: binaryOperator, - left: {...previousValuePlace}, + left: {...capturedPreviousValue}, right: lowerValueToTemporary(builder, { kind: 'Primitive', value: 1, @@ -2633,7 +2639,7 @@ function lowerExpression( kind: 'LoadLocal', place: expr.node.prefix ? {...newValuePlace} - : {...previousValuePlace}, + : {...capturedPreviousValue}, loc: exprLoc, }; } @@ -2646,13 +2652,55 @@ function lowerExpression( }); return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc}; } else if (builder.isContextIdentifier(argument)) { - builder.errors.push({ - reason: `(BuildHIR::lowerExpression) Handle UpdateExpression to variables captured within lambdas.`, - category: ErrorCategory.Todo, - loc: exprPath.node.loc ?? null, - suggestions: null, + const binaryOperator = expr.node.operator === '++' ? '+' : '-'; + const lvalue = lowerIdentifierForAssignment( + builder, + argument.node.loc ?? GeneratedSource, + InstructionKind.Reassign, + argument, + ); + + if (lvalue === null) { + return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc}; + } else if (lvalue.kind === 'Global') { + builder.errors.push({ + reason: `(BuildHIR::lowerExpression) Expected Identifier to be a context variable`, + category: ErrorCategory.Invariant, + loc: exprLoc, + suggestions: null, + }); + return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc}; + } + + // Load the current value + const previousValue = lowerExpressionToTemporary(builder, argument); + + // Calculate the new value + const updatedValue = lowerValueToTemporary(builder, { + kind: 'BinaryExpression', + operator: binaryOperator, + left: {...previousValue}, + right: lowerValueToTemporary(builder, { + kind: 'Primitive', + value: 1, + loc: GeneratedSource, + }), + loc: exprLoc, }); - return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc}; + + // Store the new value + const newValuePlace = lowerValueToTemporary(builder, { + kind: 'StoreContext', + lvalue: {place: {...lvalue}, kind: InstructionKind.Reassign}, + value: {...updatedValue}, + loc: exprLoc, + }); + + return { + kind: 'LoadLocal', + place: expr.node.prefix ? {...newValuePlace} : {...previousValue}, + loc: exprLoc, + }; } const lvalue = lowerIdentifierForAssignment( builder, diff --git a/split_react_35305.sh b/split_react_35305.sh new file mode 100755 index 000000000000..961784993b78 --- /dev/null +++ b/split_react_35305.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -e + +# React +cd /Users/work/react_temp +git checkout main +git reset --hard origin/main +gh pr checkout 35305 -R facebook/react -b feature/original-35305 --force +git remote set-url origin https://github.com/tennisleng/react.git + +ORIGIN_BRANCH="feature/original-35305" + +# 1. Logic Branch +echo "Creating branch: feat/react-update-expr-logic" +git checkout main +git checkout -b feat/react-update-expr-logic + +# Checkout logic file +git checkout $ORIGIN_BRANCH -- compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts + +# Commit +git add . +git commit -m "fix(compiler): Support UpdateExpression on captured variables logic" + +# Push +git push origin feat/react-update-expr-logic +gh pr create --repo facebook/react --base main --head tennisleng:feat/react-update-expr-logic --title "fix(compiler): Support UpdateExpression on captured variables logic" --body "Splitting #35305: Core logical fix." + +# 2. Test Branch +echo "Creating branch: feat/react-update-expr-tests" +git checkout feat/react-update-expr-logic +git checkout -b feat/react-update-expr-tests + +# Checkout tests +git checkout $ORIGIN_BRANCH -- compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures + +# Commit +git add . +git commit -m "test(compiler): Add regression tests for UpdateExpression" + +# Push +git push origin feat/react-update-expr-tests +gh pr create --repo facebook/react --base main --head tennisleng:feat/react-update-expr-tests --title "test(compiler): Add regression tests for UpdateExpression" --body "Splitting #35305: Test fixtures. Depends on #logic-pr" + +echo "Done splitting #35305"