@samitouri / QOS-React / commits / 1c53385db5
Fork 0

The library for web and native user interfaces.

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 +}