[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.
This commit is contained in:
mofeiZ 2025-06-02 11:43:45 -04:00 committed by GitHub
parent ee76351917
commit 526dd340b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 83 additions and 2 deletions

View File

@ -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') {
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') {

View File

@ -0,0 +1,56 @@
## Input
```javascript
import {Stringify} from 'shared-runtime';
function Repro(props) {
const MY_CONST = -2;
return <Stringify>{props.arg - MY_CONST}</Stringify>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Repro,
params: [
{
arg: 3,
},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";
function Repro(props) {
const $ = _c(2);
const t0 = props.arg - -2;
let t1;
if ($[0] !== t0) {
t1 = <Stringify>{t0}</Stringify>;
$[0] = t0;
$[1] = t1;
} else {
t1 = $[1];
}
return t1;
}
export const FIXTURE_ENTRYPOINT = {
fn: Repro,
params: [
{
arg: 3,
},
],
};
```
### Eval output
(kind: ok) <div>{"children":5}</div>

View File

@ -0,0 +1,15 @@
import {Stringify} from 'shared-runtime';
function Repro(props) {
const MY_CONST = -2;
return <Stringify>{props.arg - MY_CONST}</Stringify>;
}
export const FIXTURE_ENTRYPOINT = {
fn: Repro,
params: [
{
arg: 3,
},
],
};

View File

@ -242,6 +242,7 @@ export async function transformFixtureInput(
filename: virtualFilepath,
highlightCode: false,
retainLines: true,
compact: true,
plugins: [
[plugin, options],
'babel-plugin-fbt',