mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[hir] Bailout when reading from React namespace
Forget doesn't understand the React namespace object and generates incorrect code when compiling code that loads props from this namespace object. This PR makes Forget bailout when we see a property load from React namespace object.
This commit is contained in:
@@ -2215,6 +2215,20 @@ function lowerMemberExpression(
|
||||
const object =
|
||||
loweredObject ?? lowerExpressionToTemporary(builder, objectNode);
|
||||
|
||||
if (objectNode.isIdentifier() && objectNode.node.name === "React") {
|
||||
builder.errors.push({
|
||||
reason: `(BuildHIR::lowerMemberExpression) Handle loading properties from React namespace`,
|
||||
severity: ErrorSeverity.Todo,
|
||||
loc: propertyNode.node.loc ?? null,
|
||||
suggestions: null,
|
||||
});
|
||||
return {
|
||||
object,
|
||||
property: propertyNode.toString(),
|
||||
value: { kind: "UnsupportedNode", node: exprNode, loc: exprLoc },
|
||||
};
|
||||
}
|
||||
|
||||
if (!expr.node.computed) {
|
||||
if (!propertyNode.isIdentifier()) {
|
||||
builder.errors.push({
|
||||
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Foo() {
|
||||
const [x, setX] = React.useState(1);
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Foo() {
|
||||
const $ = useMemoCache(1);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = React.useState(1);
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const [x] = t0;
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+38
-50
@@ -3,18 +3,18 @@
|
||||
|
||||
```javascript
|
||||
import * as React from "react";
|
||||
import { useState } from "react";
|
||||
import { useState, useMemo } from "react";
|
||||
|
||||
function Component(props) {
|
||||
const [x] = useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
|
||||
function Component2(props) {
|
||||
const [x] = useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
@@ -25,74 +25,62 @@ function Component2(props) {
|
||||
|
||||
```javascript
|
||||
import * as React from "react";
|
||||
import { useState, unstable_useMemoCache as useMemoCache } from "react";
|
||||
import {
|
||||
useState,
|
||||
useMemo,
|
||||
unstable_useMemoCache as useMemoCache,
|
||||
} from "react";
|
||||
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(6);
|
||||
const $ = useMemoCache(4);
|
||||
const [x] = useState(0);
|
||||
const c_0 = $[0] !== x;
|
||||
let t1;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
const c_2 = $[2] !== x;
|
||||
let t0;
|
||||
if (c_2) {
|
||||
t0 = () => calculateExpensiveNumber(x);
|
||||
$[2] = x;
|
||||
$[3] = t0;
|
||||
} else {
|
||||
t0 = $[3];
|
||||
}
|
||||
t1 = React.useMemo(t0, [x]);
|
||||
t0 = calculateExpensiveNumber(x);
|
||||
$[0] = x;
|
||||
$[1] = t1;
|
||||
$[1] = t0;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
t0 = $[1];
|
||||
}
|
||||
const expensiveNumber = t1;
|
||||
const c_4 = $[4] !== expensiveNumber;
|
||||
let t2;
|
||||
if (c_4) {
|
||||
t2 = <div>{expensiveNumber}</div>;
|
||||
$[4] = expensiveNumber;
|
||||
$[5] = t2;
|
||||
const t15 = t0;
|
||||
const expensiveNumber = t15;
|
||||
const c_2 = $[2] !== expensiveNumber;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
t1 = <div>{expensiveNumber}</div>;
|
||||
$[2] = expensiveNumber;
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t2 = $[5];
|
||||
t1 = $[3];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
function Component2(props) {
|
||||
const $ = useMemoCache(6);
|
||||
const $ = useMemoCache(4);
|
||||
const [x] = useState(0);
|
||||
const c_0 = $[0] !== x;
|
||||
let t1;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
const c_2 = $[2] !== x;
|
||||
let t0;
|
||||
if (c_2) {
|
||||
t0 = () => calculateExpensiveNumber(x);
|
||||
$[2] = x;
|
||||
$[3] = t0;
|
||||
} else {
|
||||
t0 = $[3];
|
||||
}
|
||||
t1 = React.useMemo(t0, [x]);
|
||||
t0 = calculateExpensiveNumber(x);
|
||||
$[0] = x;
|
||||
$[1] = t1;
|
||||
$[1] = t0;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
t0 = $[1];
|
||||
}
|
||||
const expensiveNumber = t1;
|
||||
const c_4 = $[4] !== expensiveNumber;
|
||||
let t2;
|
||||
if (c_4) {
|
||||
t2 = <div>{expensiveNumber}</div>;
|
||||
$[4] = expensiveNumber;
|
||||
$[5] = t2;
|
||||
const t15 = t0;
|
||||
const expensiveNumber = t15;
|
||||
const c_2 = $[2] !== expensiveNumber;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
t1 = <div>{expensiveNumber}</div>;
|
||||
$[2] = expensiveNumber;
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t2 = $[5];
|
||||
t1 = $[3];
|
||||
}
|
||||
return t2;
|
||||
return t1;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+3
-3
@@ -1,16 +1,16 @@
|
||||
import * as React from "react";
|
||||
import { useState } from "react";
|
||||
import { useState, useMemo } from "react";
|
||||
|
||||
function Component(props) {
|
||||
const [x] = useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
|
||||
function Component2(props) {
|
||||
const [x] = useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
const expensiveNumber = useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import * as React from "react";
|
||||
|
||||
function Component(props) {
|
||||
const [x] = React.useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
|
||||
function Component2(props) {
|
||||
const [x] = React.useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
import * as React from "react";
|
||||
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
const [x] = React.useState(0);
|
||||
t0 = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const expensiveNumber = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = <div>{expensiveNumber}</div>;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
function Component2(props) {
|
||||
const $ = useMemoCache(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
const [x] = React.useState(0);
|
||||
t0 = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
const expensiveNumber = t0;
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = <div>{expensiveNumber}</div>;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import * as React from "react";
|
||||
|
||||
function Component(props) {
|
||||
const [x] = React.useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
|
||||
function Component2(props) {
|
||||
const [x] = React.useState(0);
|
||||
const expensiveNumber = React.useMemo(() => calculateExpensiveNumber(x), [x]);
|
||||
|
||||
return <div>{expensiveNumber}</div>;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: (BuildHIR::lowerMemberExpression) Handle loading properties from React namespace (4:4)
|
||||
|
||||
[ReactForget] Todo: (BuildHIR::lowerMemberExpression) Handle loading properties from React namespace (5:5)
|
||||
```
|
||||
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Foo() {
|
||||
const [x, setX] = React.useState(1);
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: (BuildHIR::lowerMemberExpression) Handle loading properties from React namespace (2:2)
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user