[babel] Re-export compiled functions
Sathya Gunasekaran committed
Mar 7, 2023 at 16:08 UTC
8477195c74079071657ba409c59eeb5e10d0c6bb
7 files changed
+281
-9
compiler/forget/src/Babel/BabelPlugin.ts
+30
-9
@@ -72,14 +72,35 @@ export default function ReactForgetBabelPlugin(
72
const compiledFn = fn.insertAfter(ast)[0];
73
compiledFn.skip();
74
75
- // Build and append gating test
76
- compiledFn.insertAfter(
77
- buildTest({
78
- compiled: ast.id,
79
- uncompiled: fn.node.id,
80
- original,
81
- })
82
- );
75
+ // Build gating test
76
+ const test = buildTest({
77
+ compiled: ast.id,
78
+ uncompiled: fn.node.id,
79
+ original,
80
+ });
81
+
82
+ // Re-export new declaration
83
+ const parent = fn.parent;
84
+ if (t.isExportDefaultDeclaration(parent)) {
85
+ // Re-add uncompiled function
86
+ fn.insertAfter(fn.node)[0].skip();
87
+
88
+ // Add test
89
+ compiledFn.insertAfter(test);
90
+
91
+ // Update declartion to original id
92
+ parent.declaration = original;
93
+ } else if (t.isExportNamedDeclaration(parent)) {
94
+ invariant(parent.declaration !== null, "");
95
+ // Re-add uncompiled function
96
+ fn.insertAfter(fn.node)[0].skip();
97
+
98
+ // Update declartion to test
99
+ parent.declaration = test;
100
+ } else {
101
+ // Just add the test, no need for re-export
102
+ compiledFn.insertAfter(test);
103
+ }
104
} else {
105
fn.replaceWith(ast);
106
}
@@ -147,7 +168,7 @@ function buildTest(ids: {
168
]);
169
}
170
150
-function buildImportForGatingModule(gatingModule: string) {
171
+function buildImportForGatingModule(gatingModule: string): t.ImportDeclaration {
172
const importDefaultSpecifier = t.importDefaultSpecifier(testId);
173
return t.importDeclaration(
174
[importDefaultSpecifier],
compiler/forget/src/__tests__/fixtures/hir/gating-test-export-default-function.expect.md
new
+70
@@ -0,0 +1,70 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @gatingModule @forgetDirective
6
+export default function Bar(props) {
7
+ "use forget";
8
+ return <div>{props.bar}</div>;
9
+}
10
+
11
+function NoForget(props) {
12
+ return <Bar>{props.noForget}</Bar>;
13
+}
14
+
15
+function Foo(props) {
16
+ "use forget";
17
+ return <Foo>{props.bar}</Foo>;
18
+}
19
+
20
+```
21
+
22
+## Code
23
+
24
+```javascript
25
+import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule @forgetDirective
26
+export default Bar;
27
+function Bar_uncompiled(props) {
28
+ "use forget";
29
+ return <div>{props.bar}</div>;
30
+}
31
+function Bar_forget(props) {
32
+ const $ = React.unstable_useMemoCache(2);
33
+ const c_0 = $[0] !== props.bar;
34
+ let t0;
35
+ if (c_0) {
36
+ t0 = <div>{props.bar}</div>;
37
+ $[0] = props.bar;
38
+ $[1] = t0;
39
+ } else {
40
+ t0 = $[1];
41
+ }
42
+ return t0;
43
+}
44
+var Bar = isForgetEnabled ? Bar_forget : Bar_uncompiled;
45
+
46
+function NoForget(props) {
47
+ return <Bar>{props.noForget}</Bar>;
48
+}
49
+
50
+function Foo_uncompiled(props) {
51
+ "use forget";
52
+ return <Foo>{props.bar}</Foo>;
53
+}
54
+function Foo_forget(props) {
55
+ const $ = React.unstable_useMemoCache(2);
56
+ const c_0 = $[0] !== props.bar;
57
+ let t0;
58
+ if (c_0) {
59
+ t0 = <Foo>{props.bar}</Foo>;
60
+ $[0] = props.bar;
61
+ $[1] = t0;
62
+ } else {
63
+ t0 = $[1];
64
+ }
65
+ return t0;
66
+}
67
+var Foo = isForgetEnabled ? Foo_forget : Foo_uncompiled;
68
+
69
+```
70
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/gating-test-export-default-function.js
new
+14
@@ -0,0 +1,14 @@
1
+// @gatingModule @forgetDirective
2
+export default function Bar(props) {
3
+ "use forget";
4
+ return <div>{props.bar}</div>;
5
+}
6
+
7
+function NoForget(props) {
8
+ return <Bar>{props.noForget}</Bar>;
9
+}
10
+
11
+function Foo(props) {
12
+ "use forget";
13
+ return <Foo>{props.bar}</Foo>;
14
+}
compiler/forget/src/__tests__/fixtures/hir/gating-test-export-function-and-default.expect.md
new
+70
@@ -0,0 +1,70 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @gatingModule @forgetDirective
6
+export default function Bar(props) {
7
+ "use forget";
8
+ return <div>{props.bar}</div>;
9
+}
10
+
11
+function NoForget(props) {
12
+ return <Bar>{props.noForget}</Bar>;
13
+}
14
+
15
+export function Foo(props) {
16
+ "use forget";
17
+ return <Foo>{props.bar}</Foo>;
18
+}
19
+
20
+```
21
+
22
+## Code
23
+
24
+```javascript
25
+import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule @forgetDirective
26
+export default Bar;
27
+function Bar_uncompiled(props) {
28
+ "use forget";
29
+ return <div>{props.bar}</div>;
30
+}
31
+function Bar_forget(props) {
32
+ const $ = React.unstable_useMemoCache(2);
33
+ const c_0 = $[0] !== props.bar;
34
+ let t0;
35
+ if (c_0) {
36
+ t0 = <div>{props.bar}</div>;
37
+ $[0] = props.bar;
38
+ $[1] = t0;
39
+ } else {
40
+ t0 = $[1];
41
+ }
42
+ return t0;
43
+}
44
+var Bar = isForgetEnabled ? Bar_forget : Bar_uncompiled;
45
+
46
+function NoForget(props) {
47
+ return <Bar>{props.noForget}</Bar>;
48
+}
49
+
50
+export var Foo = isForgetEnabled ? Foo_forget : Foo_uncompiled;
51
+function Foo_uncompiled(props) {
52
+ "use forget";
53
+ return <Foo>{props.bar}</Foo>;
54
+}
55
+function Foo_forget(props) {
56
+ const $ = React.unstable_useMemoCache(2);
57
+ const c_0 = $[0] !== props.bar;
58
+ let t0;
59
+ if (c_0) {
60
+ t0 = <Foo>{props.bar}</Foo>;
61
+ $[0] = props.bar;
62
+ $[1] = t0;
63
+ } else {
64
+ t0 = $[1];
65
+ }
66
+ return t0;
67
+}
68
+
69
+```
70
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/gating-test-export-function-and-default.js
new
+14
@@ -0,0 +1,14 @@
1
+// @gatingModule @forgetDirective
2
+export default function Bar(props) {
3
+ "use forget";
4
+ return <div>{props.bar}</div>;
5
+}
6
+
7
+function NoForget(props) {
8
+ return <Bar>{props.noForget}</Bar>;
9
+}
10
+
11
+export function Foo(props) {
12
+ "use forget";
13
+ return <Foo>{props.bar}</Foo>;
14
+}
compiler/forget/src/__tests__/fixtures/hir/gating-test-export-function.expect.md
new
+69
@@ -0,0 +1,69 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @gatingModule @forgetDirective
6
+export function Bar(props) {
7
+ "use forget";
8
+ return <div>{props.bar}</div>;
9
+}
10
+
11
+export function NoForget(props) {
12
+ return <Bar>{props.noForget}</Bar>;
13
+}
14
+
15
+export function Foo(props) {
16
+ "use forget";
17
+ return <Foo>{props.bar}</Foo>;
18
+}
19
+
20
+```
21
+
22
+## Code
23
+
24
+```javascript
25
+import isForgetEnabled from "ReactForgetFeatureFlag"; // @gatingModule @forgetDirective
26
+export var Bar = isForgetEnabled ? Bar_forget : Bar_uncompiled;
27
+function Bar_uncompiled(props) {
28
+ "use forget";
29
+ return <div>{props.bar}</div>;
30
+}
31
+function Bar_forget(props) {
32
+ const $ = React.unstable_useMemoCache(2);
33
+ const c_0 = $[0] !== props.bar;
34
+ let t0;
35
+ if (c_0) {
36
+ t0 = <div>{props.bar}</div>;
37
+ $[0] = props.bar;
38
+ $[1] = t0;
39
+ } else {
40
+ t0 = $[1];
41
+ }
42
+ return t0;
43
+}
44
+
45
+export function NoForget(props) {
46
+ return <Bar>{props.noForget}</Bar>;
47
+}
48
+
49
+export var Foo = isForgetEnabled ? Foo_forget : Foo_uncompiled;
50
+function Foo_uncompiled(props) {
51
+ "use forget";
52
+ return <Foo>{props.bar}</Foo>;
53
+}
54
+function Foo_forget(props) {
55
+ const $ = React.unstable_useMemoCache(2);
56
+ const c_0 = $[0] !== props.bar;
57
+ let t0;
58
+ if (c_0) {
59
+ t0 = <Foo>{props.bar}</Foo>;
60
+ $[0] = props.bar;
61
+ $[1] = t0;
62
+ } else {
63
+ t0 = $[1];
64
+ }
65
+ return t0;
66
+}
67
+
68
+```
69
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/gating-test-export-function.js
new
+14
@@ -0,0 +1,14 @@
1
+// @gatingModule @forgetDirective
2
+export function Bar(props) {
3
+ "use forget";
4
+ return <div>{props.bar}</div>;
5
+}
6
+
7
+export function NoForget(props) {
8
+ return <Bar>{props.noForget}</Bar>;
9
+}
10
+
11
+export function Foo(props) {
12
+ "use forget";
13
+ return <Foo>{props.bar}</Foo>;
14
+}