@samitouri / QOS-React-2 / commits / 1c53385db5

Don't plumb PartialEnvironmentConfig

Let's do validation at the API level and pass around the fully parsed config inside the plugin.

Sathya Gunasekaran committed Nov 7, 2023 at 11:04 UTC 1c53385db59536165e7b7468652ab962c4cfe769
4 files changed +30 -21
compiler/packages/babel-plugin-react-forget/scripts/jest/makeTransform.ts
+4 -3
@@ -7,14 +7,14 @@
7
8 import { jsx } from "@babel/plugin-syntax-jsx";
9 import babelJest from "babel-jest";
10 -import { compile } from "babel-plugin-react-forget";
10 +import { DEFAULT_ENVIRONMENT_CONFIG, compile } from "babel-plugin-react-forget";
11 import { execSync } from "child_process";
12
13 import type { NodePath, Visitor } from "@babel/traverse";
14 import type { CallExpression, FunctionDeclaration } from "@babel/types";
15 import * as t from "@babel/types";
16 -import type { PluginOptions } from "babel-plugin-react-forget";
16 import { basename } from "path";
17 +import { EnvironmentConfig } from "../../src/HIR/Environment";
18
19 /**
20 * -- IMPORTANT --
@@ -23,7 +23,8 @@ import { basename } from "path";
23 * as our script files are currently not used for babel cache breaking!!
24 */
25 const e2eTransformerCacheKey = 1;
26 -const forgetOptions: Partial<PluginOptions["environment"]> = {
26 +const forgetOptions: EnvironmentConfig = {
27 + ...DEFAULT_ENVIRONMENT_CONFIG,
28 enableAssumeHooksFollowRulesOfReact: true,
29 };
30 const debugMode = process.env["DEBUG_FORGET_COMPILER"] != null;
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Pipeline.ts
+5 -5
@@ -18,7 +18,7 @@ import {
18 lower,
19 mergeConsecutiveBlocks,
20 } from "../HIR";
21 -import { Environment, PartialEnvironmentConfig } from "../HIR/Environment";
21 +import { Environment, EnvironmentConfig } from "../HIR/Environment";
22 import { findContextIdentifiers } from "../HIR/FindContextIdentifiers";
23 import {
24 analyseFunctions,
@@ -87,10 +87,10 @@ export function* run(
87 func: NodePath<
88 t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
89 >,
90 - config?: PartialEnvironmentConfig | null
90 + config: EnvironmentConfig
91 ): Generator<CompilerPipelineValue, CodegenFunction> {
92 const contextIdentifiers = findContextIdentifiers(func);
93 - const env = new Environment(config ?? null, contextIdentifiers);
93 + const env = new Environment(config, contextIdentifiers);
94 yield {
95 kind: "debug",
96 name: "EnvironmentConfig",
@@ -368,9 +368,9 @@ export function compileFn(
368 func: NodePath<
369 t.FunctionDeclaration | t.ArrowFunctionExpression | t.FunctionExpression
370 >,
371 - options?: Partial<PartialEnvironmentConfig> | null
371 + config: EnvironmentConfig
372 ): CodegenFunction {
373 - let generator = run(func, options);
373 + let generator = run(func, config);
374 while (true) {
375 const next = generator.next();
376 if (next.done) {
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Program.ts
+3 -1
@@ -13,6 +13,7 @@ import {
13 CompilerSuggestionOperation,
14 ErrorSeverity,
15 } from "../CompilerError";
16 +import { validateEnvironmentConfig } from "../HIR/Environment";
17 import { CodegenFunction } from "../ReactiveScopes";
18 import { isComponentDeclaration } from "../Utils/ComponentDeclaration";
19 import { assertExhaustive } from "../Utils/utils";
@@ -247,7 +248,8 @@ export function compileProgram(
248
249 let compiledFn: CodegenFunction;
250 try {
250 - compiledFn = compileFn(fn, pass.opts.environment);
251 + const config = validateEnvironmentConfig(pass.opts.environment);
252 + compiledFn = compileFn(fn, config);
253 pass.opts.logger?.logEvent(pass.filename, {
254 kind: "CompileSuccess",
255 fnLoc: fn.node.loc ?? null,
compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts
+18 -12
@@ -328,21 +328,10 @@ export class Environment {
328 #hoistedIdentifiers: Set<t.Identifier>;
329
330 constructor(
331 - partialConfig: PartialEnvironmentConfig | null,
331 + config: EnvironmentConfig,
332 contextIdentifiers: Set<t.Identifier>
333 ) {
334 this.#shapes = new Map(DEFAULT_SHAPES);
335 - const config: EnvironmentConfig = { ...DEFAULT_ENVIRONMENT_CONFIG };
336 - if (partialConfig != null) {
337 - for (const key of Object.keys(DEFAULT_ENVIRONMENT_CONFIG)) {
338 - if (!isEnvironmentConfigKey(key)) {
339 - continue;
340 - }
341 - if (Object.prototype.hasOwnProperty.call(partialConfig, key)) {
342 - config[key] = partialConfig[key] as any; // we know the key is present from hasOwnProperty
343 - }
344 - }
345 - }
335 this.config = config;
336
337 if (this.config.customHooks != null && this.config.customHooks.size > 0) {
@@ -473,3 +462,20 @@ function isHookName(name: string): boolean {
462 // }
463 return /^use[A-Z0-9]/.test(name);
464 }
465 +
466 +export function validateEnvironmentConfig(
467 + partialConfig: PartialEnvironmentConfig | null
468 +): EnvironmentConfig {
469 + const config: EnvironmentConfig = { ...DEFAULT_ENVIRONMENT_CONFIG };
470 + if (partialConfig != null) {
471 + for (const key of Object.keys(DEFAULT_ENVIRONMENT_CONFIG)) {
472 + if (!isEnvironmentConfigKey(key)) {
473 + continue;
474 + }
475 + if (Object.prototype.hasOwnProperty.call(partialConfig, key)) {
476 + config[key] = partialConfig[key] as any; // we know the key is present from hasOwnProperty
477 + }
478 + }
479 + }
480 + return config;
481 +}