mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Reorder InlineUseMemo after type inference
The goal of this stack is to generalize `InlineUseMemo` into a pass that inlines all immediately invoked function expressions (IIFEs). Rather than specialize just useMemo calls, we'll rely on DropManualMemoization running first and turning useMemo calls into IIFEs. Then the generalized inlining pass can handle those IIFEs as well as others present in the source. For now, moving the order of the pass makes the output closer to what it will eventually be after this stack is complete.
This commit is contained in:
@@ -113,9 +113,6 @@ function* runWithEnvironment(
|
||||
pruneMaybeThrows(hir);
|
||||
yield log({ kind: "hir", name: "PruneMaybeThrows", value: hir });
|
||||
|
||||
inlineUseMemo(hir);
|
||||
yield log({ kind: "hir", name: "RewriteUseMemo", value: hir });
|
||||
|
||||
mergeConsecutiveBlocks(hir);
|
||||
yield log({ kind: "hir", name: "MergeConsecutiveBlocks", value: hir });
|
||||
|
||||
@@ -146,6 +143,9 @@ function* runWithEnvironment(
|
||||
});
|
||||
}
|
||||
|
||||
inlineUseMemo(hir);
|
||||
yield log({ kind: "hir", name: "InlineUseMemo", value: hir });
|
||||
|
||||
dropManualMemoization(hir);
|
||||
yield log({ kind: "hir", name: "DropManualMemoization", value: hir });
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
InstructionKind,
|
||||
LabelTerminal,
|
||||
Place,
|
||||
getHookKind,
|
||||
makeInstructionId,
|
||||
makeType,
|
||||
reversePostorderBlocks,
|
||||
@@ -61,8 +62,6 @@ import { retainWhere } from "../Utils/utils";
|
||||
export function inlineUseMemo(fn: HIRFunction): void {
|
||||
// Track all function expressions in case they appear as the argument to a useMemo
|
||||
const functions = new Map<IdentifierId, FunctionExpression>();
|
||||
// Track all references to `useMemo`
|
||||
const useMemoGlobals = new Set<IdentifierId>();
|
||||
// Identifiers (lvalues) for known useMemo functions, so that we can prune them
|
||||
// at the end of the pass
|
||||
const useMemoFunctions = new Set<IdentifierId>();
|
||||
@@ -77,103 +76,100 @@ export function inlineUseMemo(fn: HIRFunction): void {
|
||||
for (let ii = 0; ii < block.instructions.length; ii++) {
|
||||
const instr = block.instructions[ii]!;
|
||||
switch (instr.value.kind) {
|
||||
case "LoadGlobal": {
|
||||
if (instr.value.name === "useMemo") {
|
||||
useMemoGlobals.add(instr.lvalue.identifier.id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "FunctionExpression": {
|
||||
functions.set(instr.lvalue.identifier.id, instr.value);
|
||||
break;
|
||||
}
|
||||
case "MethodCall":
|
||||
case "CallExpression": {
|
||||
if (useMemoGlobals.has(instr.value.callee.identifier.id)) {
|
||||
const [lambda] = instr.value.args;
|
||||
if (lambda.kind === "Spread") {
|
||||
continue;
|
||||
}
|
||||
const body = functions.get(lambda.identifier.id);
|
||||
if (body === undefined) {
|
||||
// Allow passing a named function to useMemo, eg `useMemo(someImportedFunction, [])`
|
||||
continue;
|
||||
}
|
||||
|
||||
if (body.loweredFunc.func.params.length > 0) {
|
||||
CompilerError.invalidReact({
|
||||
reason: "useMemo callbacks may not accept any arguments",
|
||||
description: null,
|
||||
loc: body.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
body.loweredFunc.func.async ||
|
||||
body.loweredFunc.func.generator
|
||||
) {
|
||||
CompilerError.invalidReact({
|
||||
reason:
|
||||
"useMemo callbacks may not be async or generator functions",
|
||||
description: null,
|
||||
loc: body.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
|
||||
// We know this function is used for useMemo and can prune it later
|
||||
useMemoFunctions.add(lambda.identifier.id);
|
||||
|
||||
// Create a new block which will contain code following the useMemo call
|
||||
const continuationBlockId = fn.env.nextBlockId;
|
||||
const continuationBlock: BasicBlock = {
|
||||
id: continuationBlockId,
|
||||
instructions: block.instructions.slice(ii + 1),
|
||||
kind: block.kind,
|
||||
phis: new Set(),
|
||||
preds: new Set(),
|
||||
terminal: block.terminal,
|
||||
};
|
||||
fn.body.blocks.set(continuationBlockId, continuationBlock);
|
||||
|
||||
// Trim the original block to contain instructions up to (but not including)
|
||||
// the useMemo
|
||||
block.instructions.length = ii;
|
||||
|
||||
// To account for complex control flow within the lambda, we treat the lambda
|
||||
// as if it were a single labeled statement, and replace all returns with gotos
|
||||
// to the label fallthrough.
|
||||
const newTerminal: LabelTerminal = {
|
||||
block: body.loweredFunc.func.body.entry,
|
||||
id: makeInstructionId(0),
|
||||
kind: "label",
|
||||
fallthrough: continuationBlockId,
|
||||
loc: block.terminal.loc,
|
||||
};
|
||||
block.terminal = newTerminal;
|
||||
|
||||
// We store the result in the useMemo temporary
|
||||
const result = instr.lvalue;
|
||||
|
||||
// Declare the useMemo temporary
|
||||
declareTemporary(fn.env, block, result);
|
||||
|
||||
// Promote the temporary with a name as we require this to persist
|
||||
promoteTemporary(result.identifier);
|
||||
|
||||
// Rewrite blocks from the lambda to replace any `return` with a
|
||||
// store to the result and `goto` the continuation block
|
||||
for (const [id, block] of body.loweredFunc.func.body.blocks) {
|
||||
block.preds.clear();
|
||||
rewriteBlock(fn.env, block, continuationBlockId, result);
|
||||
fn.body.blocks.set(id, block);
|
||||
}
|
||||
|
||||
// Ensure we visit the continuation block, since there may have been
|
||||
// sequential useMemos that need to be visited.
|
||||
queue.push(continuationBlock);
|
||||
continue queue;
|
||||
const hookKind =
|
||||
instr.value.kind === "CallExpression"
|
||||
? getHookKind(fn.env, instr.value.callee.identifier)
|
||||
: getHookKind(fn.env, instr.value.property.identifier);
|
||||
if (hookKind !== "useMemo") {
|
||||
continue;
|
||||
}
|
||||
const [lambda] = instr.value.args;
|
||||
if (lambda.kind === "Spread") {
|
||||
continue;
|
||||
}
|
||||
const body = functions.get(lambda.identifier.id);
|
||||
if (body === undefined) {
|
||||
// Allow passing a named function to useMemo, eg `useMemo(someImportedFunction, [])`
|
||||
continue;
|
||||
}
|
||||
|
||||
if (body.loweredFunc.func.params.length > 0) {
|
||||
CompilerError.invalidReact({
|
||||
reason: "useMemo callbacks may not accept any arguments",
|
||||
description: null,
|
||||
loc: body.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
|
||||
if (body.loweredFunc.func.async || body.loweredFunc.func.generator) {
|
||||
CompilerError.invalidReact({
|
||||
reason:
|
||||
"useMemo callbacks may not be async or generator functions",
|
||||
description: null,
|
||||
loc: body.loc,
|
||||
suggestions: null,
|
||||
});
|
||||
}
|
||||
|
||||
// We know this function is used for useMemo and can prune it later
|
||||
useMemoFunctions.add(lambda.identifier.id);
|
||||
|
||||
// Create a new block which will contain code following the useMemo call
|
||||
const continuationBlockId = fn.env.nextBlockId;
|
||||
const continuationBlock: BasicBlock = {
|
||||
id: continuationBlockId,
|
||||
instructions: block.instructions.slice(ii + 1),
|
||||
kind: block.kind,
|
||||
phis: new Set(),
|
||||
preds: new Set(),
|
||||
terminal: block.terminal,
|
||||
};
|
||||
fn.body.blocks.set(continuationBlockId, continuationBlock);
|
||||
|
||||
// Trim the original block to contain instructions up to (but not including)
|
||||
// the useMemo
|
||||
block.instructions.length = ii;
|
||||
|
||||
// To account for complex control flow within the lambda, we treat the lambda
|
||||
// as if it were a single labeled statement, and replace all returns with gotos
|
||||
// to the label fallthrough.
|
||||
const newTerminal: LabelTerminal = {
|
||||
block: body.loweredFunc.func.body.entry,
|
||||
id: makeInstructionId(0),
|
||||
kind: "label",
|
||||
fallthrough: continuationBlockId,
|
||||
loc: block.terminal.loc,
|
||||
};
|
||||
block.terminal = newTerminal;
|
||||
|
||||
// We store the result in the useMemo temporary
|
||||
const result = instr.lvalue;
|
||||
|
||||
// Declare the useMemo temporary
|
||||
declareTemporary(fn.env, block, result);
|
||||
|
||||
// Promote the temporary with a name as we require this to persist
|
||||
promoteTemporary(result.identifier);
|
||||
|
||||
// Rewrite blocks from the lambda to replace any `return` with a
|
||||
// store to the result and `goto` the continuation block
|
||||
for (const [id, block] of body.loweredFunc.func.body.blocks) {
|
||||
block.preds.clear();
|
||||
rewriteBlock(fn.env, block, continuationBlockId, result);
|
||||
fn.body.blocks.set(id, block);
|
||||
}
|
||||
|
||||
// Ensure we visit the continuation block, since there may have been
|
||||
// sequential useMemos that need to be visited.
|
||||
queue.push(continuationBlock);
|
||||
continue queue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -32,6 +32,7 @@ import {
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(4);
|
||||
const [x] = useState(0);
|
||||
let t35;
|
||||
const c_0 = $[0] !== x;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
@@ -41,8 +42,8 @@ function Component(props) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const t15 = t0;
|
||||
const expensiveNumber = t15;
|
||||
t35 = t0;
|
||||
const expensiveNumber = t35;
|
||||
const c_2 = $[2] !== expensiveNumber;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
@@ -58,6 +59,7 @@ function Component(props) {
|
||||
function Component2(props) {
|
||||
const $ = useMemoCache(4);
|
||||
const [x] = useState(0);
|
||||
let t35;
|
||||
const c_0 = $[0] !== x;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
@@ -67,8 +69,8 @@ function Component2(props) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const t15 = t0;
|
||||
const expensiveNumber = t15;
|
||||
t35 = t0;
|
||||
const expensiveNumber = t35;
|
||||
const c_2 = $[2] !== expensiveNumber;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
|
||||
+6
-4
@@ -34,6 +34,7 @@ import {
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(4);
|
||||
const [x] = useState(0);
|
||||
let t35;
|
||||
const c_0 = $[0] !== x;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
@@ -43,8 +44,8 @@ function Component(props) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const t15 = t0;
|
||||
const expensiveNumber = t15;
|
||||
t35 = t0;
|
||||
const expensiveNumber = t35;
|
||||
const c_2 = $[2] !== expensiveNumber;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
@@ -60,6 +61,7 @@ function Component(props) {
|
||||
function Component2(props) {
|
||||
const $ = useMemoCache(4);
|
||||
const [x] = useState(0);
|
||||
let t35;
|
||||
const c_0 = $[0] !== x;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
@@ -69,8 +71,8 @@ function Component2(props) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const t15 = t0;
|
||||
const expensiveNumber = t15;
|
||||
t35 = t0;
|
||||
const expensiveNumber = t35;
|
||||
const c_2 = $[2] !== expensiveNumber;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
|
||||
+3
-1
@@ -29,7 +29,9 @@ import { calculateExpensiveNumber } from "shared-runtime";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(2);
|
||||
const [x] = React.useState(0);
|
||||
const expensiveNumber = (() => calculateExpensiveNumber(x))();
|
||||
let t39;
|
||||
t39 = calculateExpensiveNumber(x);
|
||||
const expensiveNumber = t39;
|
||||
const c_0 = $[0] !== expensiveNumber;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
|
||||
+5
-4
@@ -24,11 +24,12 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function App(t25) {
|
||||
function App(t23) {
|
||||
const $ = useMemoCache(2);
|
||||
const { text, hasDeps } = t25;
|
||||
const { text, hasDeps } = t23;
|
||||
|
||||
hasDeps ? null : [text];
|
||||
let t44;
|
||||
const c_0 = $[0] !== text;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
@@ -38,8 +39,8 @@ function App(t25) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const t18 = t0;
|
||||
const resolvedText = t18;
|
||||
t44 = t0;
|
||||
const resolvedText = t44;
|
||||
return resolvedText;
|
||||
}
|
||||
|
||||
|
||||
+9
-19
@@ -27,30 +27,20 @@ import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
import * as React from "react";
|
||||
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(4);
|
||||
const $ = useMemoCache(2);
|
||||
let t42;
|
||||
const c_0 = $[0] !== props.value;
|
||||
let t0;
|
||||
let x;
|
||||
if (c_0) {
|
||||
t0 = () => {
|
||||
const x = [];
|
||||
x.push(props.value);
|
||||
return x;
|
||||
};
|
||||
x = [];
|
||||
x.push(props.value);
|
||||
$[0] = props.value;
|
||||
$[1] = t0;
|
||||
$[1] = x;
|
||||
} else {
|
||||
t0 = $[1];
|
||||
x = $[1];
|
||||
}
|
||||
const c_2 = $[2] !== t0;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
t1 = t0();
|
||||
$[2] = t0;
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t1 = $[3];
|
||||
}
|
||||
const x_0 = t1;
|
||||
t42 = x;
|
||||
const x_0 = t42;
|
||||
return x_0;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -28,10 +28,11 @@ function Component(props) {
|
||||
};
|
||||
|
||||
const object = { x, onChange };
|
||||
let t86;
|
||||
|
||||
const { x: x_0, onChange: onChange_0 } = object;
|
||||
const t43 = <input value={x_0} onChange={onChange_0} />;
|
||||
return t43;
|
||||
t86 = <input value={x_0} onChange={onChange_0} />;
|
||||
return t86;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+6
-6
@@ -20,8 +20,8 @@ function Component(props) {
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(4);
|
||||
let t20 = undefined;
|
||||
bb7: {
|
||||
let t44;
|
||||
bb8: {
|
||||
if (props.cond) {
|
||||
const c_0 = $[0] !== props.a;
|
||||
let t0;
|
||||
@@ -32,8 +32,8 @@ function Component(props) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
t20 = t0;
|
||||
break bb7;
|
||||
t44 = t0;
|
||||
break bb8;
|
||||
}
|
||||
const c_2 = $[2] !== props.b;
|
||||
let t1;
|
||||
@@ -44,9 +44,9 @@ function Component(props) {
|
||||
} else {
|
||||
t1 = $[3];
|
||||
}
|
||||
t20 = t1;
|
||||
t44 = t1;
|
||||
}
|
||||
const x = t20;
|
||||
const x = t44;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -20,6 +20,7 @@ function Component(props) {
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(10);
|
||||
let t59;
|
||||
const c_0 = $[0] !== props.a;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
@@ -51,8 +52,8 @@ function Component(props) {
|
||||
} else {
|
||||
t2 = $[6];
|
||||
}
|
||||
const t26 = t2;
|
||||
const [a_0, b_0] = t26;
|
||||
t59 = t2;
|
||||
const [a_0, b_0] = t59;
|
||||
const c_7 = $[7] !== a_0;
|
||||
const c_8 = $[8] !== b_0;
|
||||
let t3;
|
||||
|
||||
+6
-6
@@ -25,8 +25,8 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function component(a, b) {
|
||||
const $ = useMemoCache(2);
|
||||
let t13 = undefined;
|
||||
bb6: {
|
||||
let t31;
|
||||
bb7: {
|
||||
if (a) {
|
||||
const c_0 = $[0] !== b;
|
||||
let t0;
|
||||
@@ -37,12 +37,12 @@ function component(a, b) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
t13 = t0;
|
||||
break bb6;
|
||||
t31 = t0;
|
||||
break bb7;
|
||||
}
|
||||
t13 = undefined;
|
||||
t31 = undefined;
|
||||
}
|
||||
const x = t13;
|
||||
const x = t31;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -27,20 +27,20 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
let t16 = undefined;
|
||||
bb10: {
|
||||
let t36;
|
||||
bb11: {
|
||||
bb5: {
|
||||
if (props.cond) {
|
||||
break bb5;
|
||||
}
|
||||
|
||||
t16 = props.a;
|
||||
break bb10;
|
||||
t36 = props.a;
|
||||
break bb11;
|
||||
}
|
||||
|
||||
t16 = props.b;
|
||||
t36 = props.b;
|
||||
}
|
||||
const x = t16;
|
||||
const x = t36;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -23,8 +23,10 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const t8 = props.value;
|
||||
const x = t8;
|
||||
let t20;
|
||||
|
||||
t20 = props.value;
|
||||
const x = t20;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -19,8 +19,9 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
const t16 = props.a && props.b;
|
||||
const x = t16;
|
||||
let t38;
|
||||
t38 = props.a && props.b;
|
||||
const x = t38;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -33,8 +33,8 @@ import { useMemo, unstable_useMemoCache as useMemoCache } from "react";
|
||||
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(3);
|
||||
let t31 = undefined;
|
||||
bb9: {
|
||||
let t68;
|
||||
bb10: {
|
||||
const c_0 = $[0] !== props;
|
||||
let y;
|
||||
if (c_0) {
|
||||
@@ -43,21 +43,21 @@ function Component(props) {
|
||||
y.push(props.a);
|
||||
}
|
||||
if (props.cond2) {
|
||||
t31 = y;
|
||||
break bb9;
|
||||
t68 = y;
|
||||
break bb10;
|
||||
}
|
||||
|
||||
y.push(props.b);
|
||||
$[0] = props;
|
||||
$[1] = y;
|
||||
$[2] = t31;
|
||||
$[2] = t68;
|
||||
} else {
|
||||
y = $[1];
|
||||
t31 = $[2];
|
||||
t68 = $[2];
|
||||
}
|
||||
t31 = y;
|
||||
t68 = y;
|
||||
}
|
||||
const x = t31;
|
||||
const x = t68;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -24,10 +24,14 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
let t31;
|
||||
if (props.cond) {
|
||||
if (props.cond) {
|
||||
}
|
||||
}
|
||||
t31 = undefined;
|
||||
const x = t31;
|
||||
return x;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
+5
@@ -15,7 +15,12 @@ function component(a) {
|
||||
|
||||
```javascript
|
||||
function component(a) {
|
||||
let t23;
|
||||
|
||||
mutate(a);
|
||||
t23 = undefined;
|
||||
const x = t23;
|
||||
return x;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+3
-2
@@ -15,6 +15,7 @@ function component(a) {
|
||||
import { unstable_useMemoCache as useMemoCache } from "react";
|
||||
function component(a) {
|
||||
const $ = useMemoCache(4);
|
||||
let t24;
|
||||
const c_0 = $[0] !== a;
|
||||
let t0;
|
||||
if (c_0) {
|
||||
@@ -24,8 +25,8 @@ function component(a) {
|
||||
} else {
|
||||
t0 = $[1];
|
||||
}
|
||||
const t9 = t0;
|
||||
const x = t9;
|
||||
t24 = t0;
|
||||
const x = t24;
|
||||
const c_2 = $[2] !== x;
|
||||
let t1;
|
||||
if (c_2) {
|
||||
|
||||
+6
-6
@@ -28,17 +28,17 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
let t17 = undefined;
|
||||
bb8: switch (props.key) {
|
||||
let t38;
|
||||
bb9: switch (props.key) {
|
||||
case "key": {
|
||||
t17 = props.value;
|
||||
break bb8;
|
||||
t38 = props.value;
|
||||
break bb9;
|
||||
}
|
||||
default: {
|
||||
t17 = props.defaultValue;
|
||||
t38 = props.defaultValue;
|
||||
}
|
||||
}
|
||||
const x = t17;
|
||||
const x = t38;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -34,13 +34,13 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
|
||||
```javascript
|
||||
function Component(props) {
|
||||
let t21 = undefined;
|
||||
bb10: {
|
||||
let t49;
|
||||
bb11: {
|
||||
let y = undefined;
|
||||
bb2: switch (props.switch) {
|
||||
case "foo": {
|
||||
t21 = "foo";
|
||||
break bb10;
|
||||
t49 = "foo";
|
||||
break bb11;
|
||||
}
|
||||
case "bar": {
|
||||
y = "bar";
|
||||
@@ -51,9 +51,9 @@ function Component(props) {
|
||||
}
|
||||
}
|
||||
|
||||
t21 = y;
|
||||
t49 = y;
|
||||
}
|
||||
const x = t21;
|
||||
const x = t49;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user