feat(compiler): Compiler Logical Negation Constant Propagation (#29623)
## Summary Resolves #29622 ## How did you test this change? I verified the implementation using the test. Note: This PR was done without waiting for approval in #29622, so feel free to just close it.
Niklas Mollenhauer committed
May 29, 2024 at 18:17 UTC
320da675705e8700bc1377a5fa22b4cdf1e52704
3 files changed
+140
compiler/packages/babel-plugin-react-compiler/src/Optimization/ConstantPropagation.ts
+19
@@ -311,6 +311,25 @@ function evaluateInstruction(
311
}
312
return null;
313
}
314
+ case "UnaryExpression": {
315
+ switch (value.operator) {
316
+ case "!": {
317
+ const operand = read(constants, value.value);
318
+ if (operand !== null && operand.kind === "Primitive") {
319
+ const result: Primitive = {
320
+ kind: "Primitive",
321
+ value: !operand.value,
322
+ loc: value.loc,
323
+ };
324
+ instr.value = result;
325
+ return result;
326
+ }
327
+ return null;
328
+ }
329
+ default:
330
+ return null;
331
+ }
332
+ }
333
case "BinaryExpression": {
334
const lhsValue = read(constants, value.left);
335
const rhsValue = read(constants, value.right);
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/constant-propagation-unary.expect.md
new
+86
@@ -0,0 +1,86 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+import { Stringify } from "shared-runtime";
6
+
7
+function foo() {
8
+ let _b;
9
+ const b = true;
10
+ if (!b) {
11
+ _b = "bar";
12
+ } else {
13
+ _b = "baz";
14
+ }
15
+
16
+ return (
17
+ <Stringify
18
+ value={{
19
+ _b,
20
+ b0: !true,
21
+ n0: !0,
22
+ n1: !1,
23
+ n2: !2,
24
+ n3: !-1,
25
+ s0: !"",
26
+ s1: !"a",
27
+ s2: !"ab",
28
+ u: !undefined,
29
+ n: !null,
30
+ }}
31
+ />
32
+ );
33
+}
34
+
35
+export const FIXTURE_ENTRYPOINT = {
36
+ fn: foo,
37
+ params: [],
38
+ isComponent: false,
39
+};
40
+
41
+```
42
+
43
+## Code
44
+
45
+```javascript
46
+import { c as _c } from "react/compiler-runtime";
47
+import { Stringify } from "shared-runtime";
48
+
49
+function foo() {
50
+ const $ = _c(1);
51
+ let t0;
52
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
53
+ t0 = (
54
+ <Stringify
55
+ value={{
56
+ _b: "baz",
57
+ b0: false,
58
+ n0: true,
59
+ n1: false,
60
+ n2: false,
61
+ n3: !-1,
62
+ s0: true,
63
+ s1: false,
64
+ s2: false,
65
+ u: !undefined,
66
+ n: true,
67
+ }}
68
+ />
69
+ );
70
+ $[0] = t0;
71
+ } else {
72
+ t0 = $[0];
73
+ }
74
+ return t0;
75
+}
76
+
77
+export const FIXTURE_ENTRYPOINT = {
78
+ fn: foo,
79
+ params: [],
80
+ isComponent: false,
81
+};
82
+
83
+```
84
+
85
+### Eval output
86
+(kind: ok) <div>{"value":{"_b":"baz","b0":false,"n0":true,"n1":false,"n2":false,"n3":false,"s0":true,"s1":false,"s2":false,"u":true,"n":true}}</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/constant-propagation-unary.js
new
+35
@@ -0,0 +1,35 @@
1
+import { Stringify } from "shared-runtime";
2
+
3
+function foo() {
4
+ let _b;
5
+ const b = true;
6
+ if (!b) {
7
+ _b = "bar";
8
+ } else {
9
+ _b = "baz";
10
+ }
11
+
12
+ return (
13
+ <Stringify
14
+ value={{
15
+ _b,
16
+ b0: !true,
17
+ n0: !0,
18
+ n1: !1,
19
+ n2: !2,
20
+ n3: !-1,
21
+ s0: !"",
22
+ s1: !"a",
23
+ s2: !"ab",
24
+ u: !undefined,
25
+ n: !null,
26
+ }}
27
+ />
28
+ );
29
+}
30
+
31
+export const FIXTURE_ENTRYPOINT = {
32
+ fn: foo,
33
+ params: [],
34
+ isComponent: false,
35
+};