diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts index fb9ef190eb..2b396e425f 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts @@ -212,7 +212,7 @@ export type EnvironmentConfig = { bailoutOnHoleyArrays: boolean; }; -const DEFAULT_ENVIRONMENT_CONFIG: Readonly = { +export const DEFAULT_ENVIRONMENT_CONFIG: Readonly = { customHooks: null, memoizeJsxElements: true, @@ -231,6 +231,29 @@ const DEFAULT_ENVIRONMENT_CONFIG: Readonly = { validateRefAccessDuringRender: false, }; +export function parseConfigPragma(pragma: string): EnvironmentConfig { + const config = { ...DEFAULT_ENVIRONMENT_CONFIG }; + for (const key of Object.keys(DEFAULT_ENVIRONMENT_CONFIG)) { + if (!isEnvironmentConfigKey(key)) { + continue; + } + const value = config[key]; + if (typeof value !== "boolean") { + // We only support setting boolean flags via pragma strings + continue; + } + if (pragma.includes(`@${key}:true`)) { + config[key] = true as any; + } else if (pragma.includes(`@${key}:false`)) { + config[key] = false as any; + } else if (pragma.includes(`@${key}`)) { + config[key] = true as any; + } + } + + return config; +} + function isEnvironmentConfigKey(key: string): key is keyof EnvironmentConfig { return Object.prototype.hasOwnProperty.call(DEFAULT_ENVIRONMENT_CONFIG, key); } diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/index.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/index.ts index b6f3ad631f..8de88e686c 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/index.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/index.ts @@ -10,7 +10,12 @@ export { assertTerminalSuccessorsExist } from "./AssertTerminalSuccessorsExist"; export { assertValidMutableRanges } from "./AssertValidMutableRanges"; export { lower } from "./BuildHIR"; export { computeDominatorTree, computePostDominatorTree } from "./Dominator"; -export { Environment, Hook } from "./Environment"; +export { + DEFAULT_ENVIRONMENT_CONFIG, + Environment, + Hook, + parseConfigPragma, +} from "./Environment"; export * from "./HIR"; export { markInstructionIds, diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/parseConfigPragma-test.ts b/compiler/packages/babel-plugin-react-forget/src/__tests__/parseConfigPragma-test.ts new file mode 100644 index 0000000000..efba667c40 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/parseConfigPragma-test.ts @@ -0,0 +1,28 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { DEFAULT_ENVIRONMENT_CONFIG, parseConfigPragma } from ".."; + +describe("parseConfigPragma()", () => { + it("parses flags in various forms", () => { + const config = parseConfigPragma( + "@enableForest @validateFrozenLambdas:true @memoizeJsxElements:false" + ); + // Validate defaults first to make sure that the parser is getting the value from the pragma, + // and not just missing it and getting the default value + expect(DEFAULT_ENVIRONMENT_CONFIG.enableForest).toBe(false); + expect(DEFAULT_ENVIRONMENT_CONFIG.validateFrozenLambdas).toBe(false); + expect(DEFAULT_ENVIRONMENT_CONFIG.memoizeJsxElements).toBe(true); + + expect(config).toEqual({ + ...DEFAULT_ENVIRONMENT_CONFIG, + enableForest: true, + validateFrozenLambdas: true, + memoizeJsxElements: false, + }); + }); +}); diff --git a/compiler/packages/babel-plugin-react-forget/src/index.ts b/compiler/packages/babel-plugin-react-forget/src/index.ts index f2d79b9b4c..489ea48fb0 100644 --- a/compiler/packages/babel-plugin-react-forget/src/index.ts +++ b/compiler/packages/babel-plugin-react-forget/src/index.ts @@ -19,7 +19,15 @@ export { parsePluginOptions, run, } from "./Entrypoint"; -export { Effect, Hook, SourceLocation, ValueKind, printHIR } from "./HIR"; +export { + DEFAULT_ENVIRONMENT_CONFIG, + Effect, + Hook, + SourceLocation, + ValueKind, + parseConfigPragma, + printHIR, +} from "./HIR"; export { printReactiveFunction } from "./ReactiveScopes"; declare global {