@samitouri / QOS-React / commits / 2b417e2a52

Playground uses new pragma parser, shows config being used

The playground now uses the new pragma parser so it's guaranteed to use the right defaults and have consistent parsing with snap/sprout. In addition, we now emit a debug event from the compiler which contains pretty-printed environment config, making it easy to check which settings are being applied in playground. <img width="3008" alt="Screenshot 2023-10-05 at 11 05 58 AM" src="https://github.com/facebook/react-forget/assets/6425824/2417f40c-1320-4c39-a661-a4e34e3d69c4">

Joe Savona committed Oct 5, 2023 at 11:06 UTC 2b417e2a5203f108ab3a5248332e5cd8dd2f8700
3 files changed +17 -52
compiler/apps/playground/components/Editor/index.tsx
+3 -52
@@ -11,6 +11,7 @@ import * as t from "@babel/types";
11 import {
12 Effect,
13 Hook,
14 + parseConfigPragma,
15 printHIR,
16 printReactiveFunction,
17 run,
@@ -108,56 +109,6 @@ const COMMON_HOOKS: Array<[string, Hook]> = [
109 ],
110 ];
111
111 -function parsePragma(pragma: string) {
112 - let memoizeJsxElements = true;
113 - let enableAssumeHooksFollowRulesOfReact = false;
114 - let disableAllMemoization = false;
115 - let validateRefAccessDuringRender = true;
116 - let enableEmitFreeze = null;
117 - let validateHooksUsage = true;
118 - let validateFrozenLambdas = true;
119 - let assertValidMutableRanges = true;
120 -
121 - if (pragma.includes("@memoizeJsxElements false")) {
122 - memoizeJsxElements = false;
123 - }
124 - if (pragma.includes("@enableAssumeHooksFollowRulesOfReact true")) {
125 - enableAssumeHooksFollowRulesOfReact = true;
126 - }
127 - if (pragma.includes("@disableAllMemoization true")) {
128 - disableAllMemoization = true;
129 - }
130 - if (pragma.includes("@validateRefAccessDuringRender false")) {
131 - validateRefAccessDuringRender = false;
132 - }
133 - if (pragma.includes("@enableEmitFreeze")) {
134 - enableEmitFreeze = {
135 - source: "react-forget-runtime",
136 - importSpecifierName: "makeReadOnly",
137 - };
138 - }
139 - if (pragma.includes("@validateHooksUsage false")) {
140 - validateHooksUsage = false;
141 - }
142 - if (pragma.includes("@validateFrozenLambdas false")) {
143 - validateHooksUsage = false;
144 - }
145 - if (pragma.includes("@assertValidMutableRanges false")) {
146 - assertValidMutableRanges = false;
147 - }
148 -
149 - return {
150 - enableAssumeHooksFollowRulesOfReact,
151 - disableAllMemoization,
152 - memoizeJsxElements,
153 - validateHooksUsage,
154 - validateRefAccessDuringRender,
155 - validateFrozenLambdas,
156 - enableEmitFreeze,
157 - assertValidMutableRanges,
158 - };
159 -}
160 -
112 function compile(source: string): CompilerOutput {
113 const results = new Map<string, PrintedCompilerPipelineValue[]>();
114 const upsert = (result: PrintedCompilerPipelineValue) => {
@@ -171,12 +122,12 @@ function compile(source: string): CompilerOutput {
122 try {
123 // Extract the first line to quickly check for custom test directives
124 const pragma = source.substring(0, source.indexOf("\n"));
174 - const options = parsePragma(pragma);
125 + const config = parseConfigPragma(pragma);
126
127 for (const fn of parseFunctions(source)) {
128 for (const result of run(fn, {
129 + ...config,
130 customHooks: new Map([...COMMON_HOOKS]),
179 - ...options,
131 })) {
132 const fnName = fn.node.id?.name ?? null;
133 switch (result.kind) {
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Pipeline.ts
+8
@@ -7,6 +7,7 @@
7
8 import { NodePath } from "@babel/traverse";
9 import * as t from "@babel/types";
10 +import prettyFormat from "pretty-format";
11 import { lowerToForest } from "../Forest";
12 import {
13 HIRFunction,
@@ -60,6 +61,7 @@ import { eliminateRedundantPhi, enterSSA, leaveSSA } from "../SSA";
61 import { inferTypes } from "../TypeInference";
62 import {
63 logCodegenFunction,
64 + logDebug,
65 logHIRFunction,
66 logReactiveFunction,
67 } from "../Utils/logger";
@@ -86,6 +88,11 @@ export function* run(
88 ): Generator<CompilerPipelineValue, CodegenFunction> {
89 const contextIdentifiers = findContextIdentifiers(func);
90 const env = new Environment(config ?? null, contextIdentifiers);
91 + yield {
92 + kind: "debug",
93 + name: "EnvironmentConfig",
94 + value: prettyFormat(env.config),
95 + };
96 const ast = yield* runWithEnvironment(func, env);
97 return ast;
98 }
@@ -373,6 +380,7 @@ export function log(value: CompilerPipelineValue): CompilerPipelineValue {
380 break;
381 }
382 case "debug": {
383 + logDebug(value.name, value.value);
384 break;
385 }
386 default: {
compiler/packages/babel-plugin-react-forget/src/Utils/logger.ts
+6
@@ -21,6 +21,12 @@ export function toggleLogging(enabled: boolean): void {
21 ENABLED = enabled;
22 }
23
24 +export function logDebug(step: string, value: string): void {
25 + if (ENABLED) {
26 + process.stdout.write(`${chalk.gray(step)}:\n${value}\n\n`);
27 + }
28 +}
29 +
30 export function logHIR(step: string, ir: HIR): void {
31 if (ENABLED) {
32 const printed = printHIR(ir);