@samitouri / QOS-React-2 / commits / ebd8ed5c71

[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";