From 526dd340b3e77193846fe5eed02b9bb89d7c2d15 Mon Sep 17 00:00:00 2001
From: mofeiZ <34200447+mofeiZ@users.noreply.github.com>
Date: Mon, 2 Jun 2025 11:43:45 -0400
Subject: [PATCH] [compiler][patch] Emit unary expressions instead of negative
numbers (#33383)
This is a babel bug + edge case.
Babel compact mode produces invalid JavaScript (i.e. parse error) when
given a `NumericLiteral` with a negative value.
See https://codesandbox.io/p/devbox/5d47fr for repro.
---
.../ReactiveScopes/CodegenReactiveFunction.ts | 13 ++++-
...el-repro-compact-negative-number.expect.md | 56 +++++++++++++++++++
.../babel-repro-compact-negative-number.js | 15 +++++
compiler/packages/snap/src/compiler.ts | 1 +
4 files changed, 83 insertions(+), 2 deletions(-)
create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/babel-repro-compact-negative-number.expect.md
create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/babel-repro-compact-negative-number.js
diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts
index 33a124dcec..17c62c02a6 100644
--- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts
+++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts
@@ -1726,7 +1726,7 @@ function codegenInstructionValue(
}
case 'UnaryExpression': {
value = t.unaryExpression(
- instrValue.operator as 'throw', // todo
+ instrValue.operator,
codegenPlaceToExpression(cx, instrValue.value),
);
break;
@@ -2582,7 +2582,16 @@ function codegenValue(
value: boolean | number | string | null | undefined,
): t.Expression {
if (typeof value === 'number') {
- return t.numericLiteral(value);
+ if (value < 0) {
+ /**
+ * Babel's code generator produces invalid JS for negative numbers when
+ * run with { compact: true }.
+ * See repro https://codesandbox.io/p/devbox/5d47fr
+ */
+ return t.unaryExpression('-', t.numericLiteral(-value), false);
+ } else {
+ return t.numericLiteral(value);
+ }
} else if (typeof value === 'boolean') {
return t.booleanLiteral(value);
} else if (typeof value === 'string') {
diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/babel-repro-compact-negative-number.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/babel-repro-compact-negative-number.expect.md
new file mode 100644
index 0000000000..70e19e0744
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/babel-repro-compact-negative-number.expect.md
@@ -0,0 +1,56 @@
+
+## Input
+
+```javascript
+import {Stringify} from 'shared-runtime';
+
+function Repro(props) {
+ const MY_CONST = -2;
+ return