mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
[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:
parent
ee76351917
commit
526dd340b3
|
|
@ -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') {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -242,6 +242,7 @@ export async function transformFixtureInput(
|
|||
filename: virtualFilepath,
|
||||
highlightCode: false,
|
||||
retainLines: true,
|
||||
compact: true,
|
||||
plugins: [
|
||||
[plugin, options],
|
||||
'babel-plugin-fbt',
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user