Add signal codegen for ReactiveScopes
Instead of emitting a memo block, emit a function expression and pass it as an argument to derived (which will then create a computed). The naming of 'derived' needs to be tweaked.
Sathya Gunasekaran committed
Sep 5, 2023 at 11:13 UTC
2d3507b0e19e6c001c861fcb067bb98fc84e4860
2 files changed
+51
-1
compiler/packages/babel-plugin-react-forget/src/HIR/Environment.ts
+2
@@ -185,6 +185,7 @@ export class Environment {
185
disableAllMemoization: boolean;
186
enableEmitFreeze: ExternalFunction | null;
187
assertValidMutableRanges: boolean;
188
+ enableForest: boolean;
189
190
#contextIdentifiers: Set<t.Identifier>;
191
@@ -233,6 +234,7 @@ export class Environment {
234
this.assertValidMutableRanges = config?.assertValidMutableRanges ?? false;
235
this.validateNoSetStateInRender =
236
config?.validateNoSetStateInRender ?? false;
237
+ this.enableForest = config?.enableForest ?? false;
238
239
this.#contextIdentifiers = contextIdentifiers;
240
}
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+49
-1
@@ -176,7 +176,7 @@ function wrapCacheDep(cx: Context, value: t.Expression): t.Expression {
176
}
177
}
178
179
-function codegenReactiveScope(
179
+function codegenMemoBlockForReactiveScope(
180
cx: Context,
181
statements: Array<t.Statement>,
182
scope: ReactiveScope,
@@ -319,6 +319,54 @@ function codegenReactiveScope(
319
statements.push(t.ifStatement(testCondition, computationBlock, memoBlock));
320
}
321
322
+function codegenSignalBlockForReactiveScope(
323
+ cx: Context,
324
+ statements: Array<t.Statement>,
325
+ scope: ReactiveScope,
326
+ block: ReactiveBlock
327
+): void {
328
+ CompilerError.invariant(scope.reassignments.size === 0, {
329
+ reason: "Add support for reassignments in a derived computation block",
330
+ loc: null,
331
+ suggestions: null,
332
+ });
333
+ CompilerError.invariant(scope.declarations.size === 1, {
334
+ reason:
335
+ "Add support for multiple declarations in a derived computation block",
336
+ loc: null,
337
+ suggestions: null,
338
+ });
339
+ const [_, { identifier }] = [...scope.declarations][0];
340
+ const name = convertIdentifier(identifier);
341
+
342
+ const derivedBlock = codegenBlock(cx, block);
343
+ derivedBlock.body.push(t.returnStatement(name));
344
+
345
+ const derivedLambda = t.functionExpression(null, [], derivedBlock, false);
346
+ const derivedComputationCall = t.callExpression(t.identifier("derived"), [
347
+ derivedLambda,
348
+ ]);
349
+
350
+ statements.push(
351
+ t.variableDeclaration("const", [
352
+ t.variableDeclarator(name, derivedComputationCall),
353
+ ])
354
+ );
355
+}
356
+
357
+function codegenReactiveScope(
358
+ cx: Context,
359
+ statements: Array<t.Statement>,
360
+ scope: ReactiveScope,
361
+ block: ReactiveBlock
362
+): void {
363
+ if (cx.env.enableForest) {
364
+ codegenSignalBlockForReactiveScope(cx, statements, scope, block);
365
+ } else {
366
+ codegenMemoBlockForReactiveScope(cx, statements, scope, block);
367
+ }
368
+}
369
+
370
function codegenTerminal(
371
cx: Context,
372
terminal: ReactiveTerminal