mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Reodering of unary and arrow function expressions
Supports reordering of unary and arrow function expressions: * Supports a trivially safe subset of unary operators, rejects things like `void` just because we don't need it yet. * Supports arrow function expressions that are either an empty block statement or a single expression which is itself reorderable.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
import { NodePath, Scope } from "@babel/traverse";
|
||||
import * as t from "@babel/types";
|
||||
import { Expression } from "@babel/types";
|
||||
import invariant from "invariant";
|
||||
import {
|
||||
CompilerError,
|
||||
CompilerSuggestionOperation,
|
||||
@@ -2238,6 +2239,19 @@ function isReorderableExpression(
|
||||
case "BigIntLiteral": {
|
||||
return true;
|
||||
}
|
||||
case "UnaryExpression": {
|
||||
const unary = expr as NodePath<t.UnaryExpression>;
|
||||
switch (expr.node.operator) {
|
||||
case "!":
|
||||
case "+":
|
||||
case "-": {
|
||||
return isReorderableExpression(builder, unary.get("argument"));
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
case "TypeCastExpression": {
|
||||
return isReorderableExpression(
|
||||
builder,
|
||||
@@ -2293,6 +2307,17 @@ function isReorderableExpression(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case "ArrowFunctionExpression": {
|
||||
const fn = expr as NodePath<t.ArrowFunctionExpression>;
|
||||
const body = fn.get("body");
|
||||
if (body.node.type === "BlockStatement") {
|
||||
return body.node.body.length === 0;
|
||||
} else {
|
||||
// For TypeScript
|
||||
invariant(body.isExpression(), "Expected an expression");
|
||||
return isReorderableExpression(builder, body);
|
||||
}
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(x = [-1, 1]) {
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(t0) {
|
||||
const $ = useMemoCache(2);
|
||||
const c_0 = $[0] !== t0;
|
||||
let t1;
|
||||
if (c_0) {
|
||||
t1 = t0 === undefined ? [-1, 1] : t0;
|
||||
$[0] = t0;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const x = t1;
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
function Component(x = [-1, 1]) {
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(x = () => {}) {
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(t0) {
|
||||
const $ = useMemoCache(2);
|
||||
const c_0 = $[0] !== t0;
|
||||
let t1;
|
||||
if (c_0) {
|
||||
t1 = t0 === undefined ? () => {} : t0;
|
||||
$[0] = t0;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const x = t1;
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
function Component(x = () => {}) {
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(x = () => [-1, true, 42.0, "hello"]) {
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(t0) {
|
||||
const $ = useMemoCache(2);
|
||||
const c_0 = $[0] !== t0;
|
||||
let t1;
|
||||
if (c_0) {
|
||||
t1 = t0 === undefined ? () => [-1, true, 42, "hello"] : t0;
|
||||
$[0] = t0;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const x = t1;
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
function Component(x = () => [-1, true, 42.0, "hello"]) {
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [],
|
||||
};
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const [x = [-1, 1]] = props.value;
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ value: [] }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(2);
|
||||
const [t0] = props.value;
|
||||
const c_0 = $[0] !== t0;
|
||||
let t1;
|
||||
if (c_0) {
|
||||
t1 = t0 === undefined ? [-1, 1] : t0;
|
||||
$[0] = t0;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const x = t1;
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ value: [] }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
function Component(props) {
|
||||
const [x = [-1, 1]] = props.value;
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{ value: [] }],
|
||||
};
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Foo() {
|
||||
(function t() {
|
||||
let x = {};
|
||||
return function a(x = () => {}) {
|
||||
return x;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [],
|
||||
isComponent: false,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
[ReactForget] Todo: (BuildHIR::node.lowerReorderableExpression) Expression type 'ArrowFunctionExpression' cannot be safely reordered (4:4)
|
||||
```
|
||||
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function Foo() {
|
||||
return (function t() {
|
||||
let x = {};
|
||||
return function a(x = () => {}) {
|
||||
return x;
|
||||
};
|
||||
})();
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [],
|
||||
isComponent: false,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Foo() {
|
||||
const $ = useMemoCache(2);
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = function t() {
|
||||
return function a(t25) {
|
||||
const x_0 = t25 === undefined ? () => {} : t25;
|
||||
return x_0;
|
||||
};
|
||||
};
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
let t1;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = t0();
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [],
|
||||
isComponent: false,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
function Foo() {
|
||||
(function t() {
|
||||
return (function t() {
|
||||
let x = {};
|
||||
return function a(x = () => {}) {
|
||||
return x;
|
||||
@@ -412,6 +412,7 @@ const skipFilter = new Set([
|
||||
"fbt-call-complex-param-value",
|
||||
"fbt-template-string-same-scope",
|
||||
"component-declaration-basic.flow",
|
||||
"nested-function-with-param-as-captured-dep",
|
||||
|
||||
// TODO: 🌲
|
||||
"forest-basic",
|
||||
|
||||
Reference in New Issue
Block a user