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);