Add enableOnlyOnUseForgetDirective flag

When this flag is enabled, Forget will only compile function declarations opted 
in via the `'use forget'` directive. By default this is false. 

Tested internally, see related diffs
This commit is contained in:
Lauren Tan
2023-02-06 16:47:35 -05:00
parent b009626431
commit cd108cd430
2 changed files with 47 additions and 3 deletions
+15 -1
View File
@@ -9,6 +9,7 @@
import type * as BabelCore from "@babel/core";
import jsx from "@babel/plugin-syntax-jsx";
import { parseCompilerFlags } from "../CompilerFlags";
import { compile } from "../CompilerPipeline";
/**
@@ -24,7 +25,20 @@ export default function ReactForgetBabelPlugin(
inherits: jsx,
visitor: {
FunctionDeclaration: {
enter(fn, _pass) {
enter(fn, pass) {
const flags = parseCompilerFlags(pass.opts);
if (flags.enableOnlyOnUseForgetDirective) {
let hasUseForgetDirective = false;
for (const directive of fn.node.body.directives) {
if (directive.value.value === "use forget") {
hasUseForgetDirective = true;
break;
}
}
if (!hasUseForgetDirective) {
return;
}
}
if (fn.scope.getProgramParent() !== fn.scope.parent) {
return;
}
+32 -2
View File
@@ -5,6 +5,36 @@
* LICENSE file in the root directory of this source tree.
*/
type Flags = {};
export type CompilerFlags = {
/**
* Enable to make Forget only compile functions containing the 'use forget' directive.
*/
enableOnlyOnUseForgetDirective: boolean;
};
export const flags: Flags = {};
export const defaultFlags: CompilerFlags = {
enableOnlyOnUseForgetDirective: false,
} as const;
export function parseCompilerFlags(obj: unknown): CompilerFlags {
if (obj == null || typeof obj !== "object") {
return defaultFlags;
}
const invalidFlags: Array<string> = [];
let parsedFlags: Partial<CompilerFlags> = Object.create(null);
for (const [key, value] of Object.entries(obj)) {
if (isCompilerFlag(key)) {
parsedFlags[key] = value;
} else {
invalidFlags.push(key);
}
}
if (invalidFlags.length > 0) {
throw new Error(`Unexpected React Forget compiler flags: ${invalidFlags}`);
}
return { ...defaultFlags, ...parsedFlags };
}
function isCompilerFlag(s: string): s is keyof typeof defaultFlags {
return Object.prototype.hasOwnProperty.call(defaultFlags, s);
}