Skip to content

Commit

Permalink
JSX Outlining
Browse files Browse the repository at this point in the history
Adds a new pass to outline nested jsx to a separate function.

For now, we only outline nested jsx inside callbacks, but this can be
extended in the future (for ex, to outline nested jsx inside loops).
  • Loading branch information
gsathya committed Oct 4, 2024
1 parent 1460d67 commit c55943e
Show file tree
Hide file tree
Showing 11 changed files with 961 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ import {lowerContextAccess} from '../Optimization/LowerContextAccess';
import {validateNoSetStateInPassiveEffects} from '../Validation/ValidateNoSetStateInPassiveEffects';
import {validateNoJSXInTryStatement} from '../Validation/ValidateNoJSXInTryStatement';
import {propagateScopeDependenciesHIR} from '../HIR/PropagateScopeDependenciesHIR';
import {outlineJSX} from '../Optimization/OutlineJsx';

export type CompilerPipelineValue =
| {kind: 'ast'; name: string; value: CodegenFunction}
Expand Down Expand Up @@ -278,6 +279,10 @@ function* runWithEnvironment(
value: hir,
});

if (env.config.enableJsxOutlining) {
outlineJSX(hir);
}

if (env.config.enableFunctionOutlining) {
outlineFunctions(hir, fbtOperands);
yield log({kind: 'hir', name: 'OutlineFunctions', value: hir});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ function insertNewOutlinedFunctionNode(
program: NodePath<t.Program>,
originalFn: BabelFn,
compiledFn: CodegenFunction,
): NodePath<t.Function> {
): BabelFn {
switch (originalFn.type) {
case 'FunctionDeclaration': {
return originalFn.insertAfter(
Expand Down Expand Up @@ -492,18 +492,11 @@ export function compileProgram(
fn.skip();
ALREADY_COMPILED.add(fn.node);
if (outlined.type !== null) {
CompilerError.throwTodo({
reason: `Implement support for outlining React functions (components/hooks)`,
loc: outlined.fn.loc,
queue.push({
kind: 'outlined',
fn,
fnType: outlined.type,
});
/*
* Above should be as simple as the following, but needs testing:
* queue.push({
* kind: "outlined",
* fn,
* fnType: outlined.type,
* });
*/
}
}
compiledFns.push({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,11 @@ const EnvironmentConfigSchema = z.object({
*/
enableFunctionOutlining: z.boolean().default(true),

/**
* TODO(gsn): Fill this out
*/
enableJsxOutlining: z.boolean().default(false),

/*
* Enables instrumentation codegen. This emits a dev-mode only call to an
* instrumentation function, for components and hooks that Forget compiles.
Expand Down
20 changes: 11 additions & 9 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -920,15 +920,7 @@ export type InstructionValue =
type: Type;
loc: SourceLocation;
}
| {
kind: 'JsxExpression';
tag: Place | BuiltinTag;
props: Array<JsxAttribute>;
children: Array<Place> | null; // null === no children
loc: SourceLocation;
openingLoc: SourceLocation;
closingLoc: SourceLocation;
}
| JsxExpression
| {
kind: 'ObjectExpression';
properties: Array<ObjectProperty | SpreadPattern>;
Expand Down Expand Up @@ -1074,6 +1066,16 @@ export type InstructionValue =
loc: SourceLocation;
};

export type JsxExpression = {
kind: 'JsxExpression';
tag: Place | BuiltinTag;
props: Array<JsxAttribute>;
children: Array<Place> | null; // null === no children
loc: SourceLocation;
openingLoc: SourceLocation;
closingLoc: SourceLocation;
};

export type JsxAttribute =
| {kind: 'JsxSpreadAttribute'; argument: Place}
| {kind: 'JsxAttribute'; name: string; place: Place};
Expand Down
Loading

0 comments on commit c55943e

Please sign in to comment.