[be] Extract gating logic to its own module
Just moving code around to another module.
Lauren Tan committed
Aug 11, 2023 at 16:38 UTC
ebd8ed5c7148defb68ebe3b213e308f262577e51
3 files changed
+88
-81
compiler/forget/packages/babel-plugin-react-forget/src/Entrypoint/Gating.ts
new
+85
@@ -0,0 +1,85 @@
1
+import { NodePath } from "@babel/core";
2
+import * as t from "@babel/types";
3
+import { CompilerError } from "../CompilerError";
4
+import { GeneratedSource } from "../HIR";
5
+import { ExternalFunction, PluginOptions } from "./Options";
6
+
7
+type GatingTestOptions = {
8
+ originalFnDecl: NodePath<t.FunctionDeclaration>;
9
+ compiledIdent: t.Identifier;
10
+ originalIdent: t.Identifier;
11
+ gating: ExternalFunction;
12
+};
13
+function buildGatingTest({
14
+ originalFnDecl,
15
+ compiledIdent,
16
+ originalIdent,
17
+ gating,
18
+}: GatingTestOptions): t.Node | t.Node[] {
19
+ const testVarDecl = t.variableDeclaration("const", [
20
+ t.variableDeclarator(
21
+ originalIdent,
22
+ t.conditionalExpression(
23
+ t.callExpression(t.identifier(gating.importSpecifierName), []),
24
+ compiledIdent,
25
+ originalFnDecl.node.id!
26
+ )
27
+ ),
28
+ ]);
29
+
30
+ // Re-export new declaration
31
+ const parent = originalFnDecl.parentPath;
32
+ if (t.isExportDefaultDeclaration(parent)) {
33
+ // Re-add uncompiled function
34
+ parent.replaceWith(originalFnDecl)[0].skip();
35
+
36
+ // Add test and synthesize new export
37
+ return [testVarDecl, t.exportDefaultDeclaration(originalIdent)];
38
+ } else if (t.isExportNamedDeclaration(parent)) {
39
+ // Re-add uncompiled function
40
+ parent.replaceWith(originalFnDecl)[0].skip();
41
+
42
+ // Add and export test
43
+ return t.exportNamedDeclaration(testVarDecl);
44
+ }
45
+
46
+ // Just add the test, no need for re-export
47
+ return testVarDecl;
48
+}
49
+
50
+function addSuffix(id: t.Identifier, suffix: string): t.Identifier {
51
+ return t.identifier(`${id.name}${suffix}`);
52
+}
53
+
54
+export function insertGatedFunctionDeclaration(
55
+ fnPath: NodePath<t.FunctionDeclaration>,
56
+ compiled: t.FunctionDeclaration,
57
+ originalIdent: t.Identifier,
58
+ gating: NonNullable<PluginOptions["gating"]>
59
+): NodePath<t.FunctionDeclaration> {
60
+ // Rename existing function
61
+ fnPath.node.id = addSuffix(originalIdent, "_uncompiled");
62
+
63
+ // Rename and append compiled function
64
+ CompilerError.invariant(compiled.id != null, {
65
+ reason: "FunctionDeclaration must produce a name",
66
+ description: null,
67
+ loc: fnPath.node.loc ?? GeneratedSource,
68
+ suggestions: null,
69
+ });
70
+ compiled.id = addSuffix(compiled.id, "_forget");
71
+ const compiledFn = fnPath.insertAfter(compiled)[0];
72
+ compiledFn.skip();
73
+
74
+ // Build and append gating test
75
+ compiledFn.insertAfter(
76
+ buildGatingTest({
77
+ originalFnDecl: fnPath,
78
+ compiledIdent: compiled.id,
79
+ originalIdent,
80
+ gating,
81
+ })
82
+ );
83
+
84
+ return compiledFn;
85
+}
compiler/forget/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts
+1
-80
@@ -16,6 +16,7 @@ import {
16
import { GeneratedSource } from "../HIR";
17
import { isComponentDeclaration } from "../Utils/ComponentDeclaration";
18
import { getOrInsertDefault } from "../Utils/utils";
19
+import { insertGatedFunctionDeclaration } from "./Gating";
20
import { addInstrumentForget } from "./Instrumentation";
21
import { ExternalFunction, PluginOptions, parsePluginOptions } from "./Options";
22
import { compileFn } from "./Pipeline";
@@ -115,39 +116,6 @@ function compileAndInsertNewFunctionDeclaration(
116
return false;
117
}
118
118
-function insertGatedFunctionDeclaration(
119
- fnPath: NodePath<t.FunctionDeclaration>,
120
- compiled: t.FunctionDeclaration,
121
- originalIdent: t.Identifier,
122
- gating: NonNullable<PluginOptions["gating"]>
123
-): NodePath<t.FunctionDeclaration> {
124
- // Rename existing function
125
- fnPath.node.id = addSuffix(originalIdent, "_uncompiled");
126
-
127
- // Rename and append compiled function
128
- CompilerError.invariant(compiled.id != null, {
129
- reason: "FunctionDeclaration must produce a name",
130
- description: null,
131
- loc: fnPath.node.loc ?? GeneratedSource,
132
- suggestions: null,
133
- });
134
- compiled.id = addSuffix(compiled.id, "_forget");
135
- const compiledFn = fnPath.insertAfter(compiled)[0];
136
- compiledFn.skip();
137
-
138
- // Build and append gating test
139
- compiledFn.insertAfter(
140
- buildGatingTest({
141
- originalFnDecl: fnPath,
142
- compiledIdent: compiled.id,
143
- originalIdent,
144
- gating,
145
- })
146
- );
147
-
148
- return compiledFn;
149
-}
150
-
119
export function compileProgram(
120
program: NodePath<t.Program>,
121
pass: CompilerPass
@@ -508,53 +476,6 @@ function addImportsToProgram(
476
path.unshiftContainer("body", stmts);
477
}
478
511
-type GatingTestOptions = {
512
- originalFnDecl: NodePath<t.FunctionDeclaration>;
513
- compiledIdent: t.Identifier;
514
- originalIdent: t.Identifier;
515
- gating: ExternalFunction;
516
-};
517
-function buildGatingTest({
518
- originalFnDecl,
519
- compiledIdent,
520
- originalIdent,
521
- gating,
522
-}: GatingTestOptions): t.Node | t.Node[] {
523
- const testVarDecl = t.variableDeclaration("const", [
524
- t.variableDeclarator(
525
- originalIdent,
526
- t.conditionalExpression(
527
- t.callExpression(t.identifier(gating.importSpecifierName), []),
528
- compiledIdent,
529
- originalFnDecl.node.id!
530
- )
531
- ),
532
- ]);
533
-
534
- // Re-export new declaration
535
- const parent = originalFnDecl.parentPath;
536
- if (t.isExportDefaultDeclaration(parent)) {
537
- // Re-add uncompiled function
538
- parent.replaceWith(originalFnDecl)[0].skip();
539
-
540
- // Add test and synthesize new export
541
- return [testVarDecl, t.exportDefaultDeclaration(originalIdent)];
542
- } else if (t.isExportNamedDeclaration(parent)) {
543
- // Re-add uncompiled function
544
- parent.replaceWith(originalFnDecl)[0].skip();
545
-
546
- // Add and export test
547
- return t.exportNamedDeclaration(testVarDecl);
548
- }
549
-
550
- // Just add the test, no need for re-export
551
- return testVarDecl;
552
-}
553
-
554
-function addSuffix(id: t.Identifier, suffix: string): t.Identifier {
555
- return t.identifier(`${id.name}${suffix}`);
556
-}
557
-
479
/**
480
* Matches `import { ... } from 'react';`
481
* but not `import * as React from 'react';`
compiler/forget/packages/babel-plugin-react-forget/src/Entrypoint/index.ts
+2
-1
@@ -1,4 +1,5 @@
1
-export * from "./Program";
1
+export * from "./Gating";
2
export * from "./Instrumentation";
3
export * from "./Options";
4
export * from "./Pipeline";
5
+export * from "./Program";