Skip to content

Commit

Permalink
[compiler] Refactor Program to use queue of functions to compile
Browse files Browse the repository at this point in the history
Refactors Program.ts to first traverse the `Program` node and build up a queue of functions to visit, then iterate that queue and compile the functions. This doesn't change behavior, but allows the next diff to add additional items to the queue during compilation (for function outlining).

ghstack-source-id: 858527c30ccc26b3aa6fe75a4746fce0820b316f
Pull Request resolved: #30330
  • Loading branch information
josephsavona committed Jul 15, 2024
1 parent 39f6b3d commit 0b230f9
Showing 1 changed file with 63 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ export function compileProgram(
);
const lintError = suppressionsToCompilerError(suppressions);
let hasCriticalError = lintError != null;
const queue: Array<{
fn: BabelFn;
fnType: ReactFunctionType;
}> = [];
const compiledFns: Array<CompileResult> = [];

const traverseFunction = (fn: BabelFn, pass: CompilerPass): void => {
Expand All @@ -281,6 +285,47 @@ export function compileProgram(
ALREADY_COMPILED.add(fn.node);
fn.skip();

queue.push({ fn, fnType });
};

// Main traversal to compile with Forget
program.traverse(
{
ClassDeclaration(node: NodePath<t.ClassDeclaration>) {
/*
* Don't visit functions defined inside classes, because they
* can reference `this` which is unsafe for compilation
*/
node.skip();
return;
},

ClassExpression(node: NodePath<t.ClassExpression>) {
/*
* Don't visit functions defined inside classes, because they
* can reference `this` which is unsafe for compilation
*/
node.skip();
return;
},

FunctionDeclaration: traverseFunction,

FunctionExpression: traverseFunction,

ArrowFunctionExpression: traverseFunction,
},
{
...pass,
opts: { ...pass.opts, ...pass.opts },
filename: pass.filename ?? null,
}
);

const processFn = (
fn: BabelFn,
fnType: ReactFunctionType
): null | CodegenFunction => {
if (lintError != null) {
/**
* Note that Babel does not attach comment nodes to nodes; they are dangling off of the
Expand Down Expand Up @@ -335,52 +380,33 @@ export function compileProgram(
} catch (err) {
hasCriticalError ||= isCriticalError(err);
handleError(err, pass, fn.node.loc ?? null);
return;
return null;
}

if (!pass.opts.noEmit && !hasCriticalError) {
compiledFns.push({ originalFn: fn, compiledFn });
return compiledFn;
}
return null;
};

// Main traversal to compile with Forget
program.traverse(
{
ClassDeclaration(node: NodePath<t.ClassDeclaration>) {
/*
* Don't visit functions defined inside classes, because they
* can reference `this` which is unsafe for compilation
*/
node.skip();
return;
},

ClassExpression(node: NodePath<t.ClassExpression>) {
/*
* Don't visit functions defined inside classes, because they
* can reference `this` which is unsafe for compilation
*/
node.skip();
return;
},

FunctionDeclaration: traverseFunction,

FunctionExpression: traverseFunction,

ArrowFunctionExpression: traverseFunction,
},
{
...pass,
opts: { ...pass.opts, ...pass.opts },
filename: pass.filename ?? null,
while (queue.length !== 0) {
const current = queue.shift()!;
const compiled = processFn(current.fn, current.fnType);
if (compiled === null) {
continue;
}
);
compiledFns.push({
compiledFn: compiled,
originalFn: current.fn,
});
}

if (pass.opts.gating != null) {
const error = checkFunctionReferencedBeforeDeclarationAtTopLevel(
program,
compiledFns.map(({ originalFn }) => originalFn)
compiledFns.map((result) => {
return result.originalFn;
})
);
if (error) {
handleError(error, pass, null);
Expand Down Expand Up @@ -439,7 +465,8 @@ export function compileProgram(
* Only insert Forget-ified functions if we have not encountered a critical
* error elsewhere in the file, regardless of bailout mode.
*/
for (const { originalFn, compiledFn } of compiledFns) {
for (const result of compiledFns) {
const { originalFn, compiledFn } = result;
const transformedFn = createNewFunctionNode(originalFn, compiledFn);

if (gating != null) {
Expand Down

0 comments on commit 0b230f9

Please sign in to comment.