@samitouri / QOS-React-2 / commits / ee3a88f20f

[λ] Parse and codegen arrow function exprs

Sathya Gunasekaran committed Jan 23, 2023 at 17:39 UTC ee3a88f20f773c91c538420a420ae2435277976f
6 files changed +64 -8
compiler/forget/src/HIR/BuildHIR.ts
+10 -5
@@ -1334,16 +1334,21 @@ function lowerExpression(
1334 loc: exprLoc,
1335 };
1336 }
1337 + case "ArrowFunctionExpression":
1338 case "FunctionExpression": {
1338 - const expr = exprPath as NodePath<t.FunctionExpression>;
1339 - const name: string | null = expr.get("id")?.node?.name ?? null;
1339 + const expr = exprPath as NodePath<
1340 + t.FunctionExpression | t.ArrowFunctionExpression
1341 + >;
1342 + let name: string | null = null;
1343 + if (expr.isFunctionExpression()) {
1344 + name = expr.get("id")?.node?.name ?? null;
1345 + }
1346 const componentScope: Scope = expr.scope.parent.getFunctionParent()!;
1347 const dependencies: Array<Place> = gatherCapturedDeps(
1348 builder,
1349 expr,
1350 componentScope
1351 );
1346 - const body = expr.get("body").node;
1352 const lowering = lower(expr);
1353 let loweredFunc: HIRFunction;
1354 if (lowering.isErr()) {
@@ -1375,11 +1380,11 @@ function lowerExpression(
1380 : {
1381 kind: "FunctionExpression",
1382 name,
1378 - body,
1383 params,
1384 loweredFunc,
1385 dependencies,
1386 mutatedDeps: [],
1387 + expr: expr.node,
1388 loc: exprLoc,
1389 };
1390 }
@@ -1901,7 +1906,7 @@ function captureScopes({ from, to }: { from: Scope; to: Scope }): Set<Scope> {
1906
1907 function gatherCapturedDeps(
1908 builder: HIRBuilder,
1904 - fn: NodePath<t.FunctionExpression>,
1909 + fn: NodePath<t.FunctionExpression | t.ArrowFunctionExpression>,
1910 componentScope: Scope
1911 ): Array<Place> {
1912 const captured: Set<Place> = new Set();
compiler/forget/src/HIR/HIR.ts
+1 -1
@@ -407,7 +407,7 @@ export type InstructionData =
407 // source of truth.
408 mutatedDeps: Array<Place>;
409 loweredFunc: HIRFunction;
410 - body: t.BlockStatement;
410 + expr: t.ArrowFunctionExpression | t.FunctionExpression;
411 }
412
413 /**
compiler/forget/src/HIR/PrintHIR.ts
+1 -1
@@ -312,7 +312,7 @@ export function printInstructionValue(instrValue: InstructionValue): string {
312 }
313 case "FunctionExpression": {
314 const params = instrValue.params.join(",");
315 - const body = generate(instrValue.body).code;
315 + const body = generate(instrValue.expr).code;
316 const deps = instrValue.dependencies
317 .map((i) => printIdentifier(i.identifier))
318 .join(",");
compiler/forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+1 -1
@@ -662,7 +662,7 @@ function codegenInstructionValue(
662 const id =
663 instrValue.name !== null ? t.identifier(instrValue.name) : null;
664 const params = instrValue.params.map((p) => t.identifier(p));
665 - value = t.functionExpression(id, params, instrValue.body);
665 + value = instrValue.expr;
666 break;
667 }
668 default: {
compiler/forget/src/__tests__/fixtures/hir/capturing-arrow-function-1.expect.md new
+44
@@ -0,0 +1,44 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function component(a) {
6 + let z = { a };
7 + let x = () => {
8 + z;
9 + };
10 + return x;
11 +}
12 +
13 +```
14 +
15 +## Code
16 +
17 +```javascript
18 +function component(a) {
19 + const $ = React.useMemoCache();
20 + const c_0 = $[0] !== a;
21 + let z;
22 + if (c_0) {
23 + z = { a: a };
24 + $[0] = a;
25 + $[1] = z;
26 + } else {
27 + z = $[1];
28 + }
29 + const c_2 = $[2] !== z;
30 + let x;
31 + if (c_2) {
32 + x = () => {
33 + z;
34 + };
35 + $[2] = z;
36 + $[3] = x;
37 + } else {
38 + x = $[3];
39 + }
40 + return x;
41 +}
42 +
43 +```
44 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/capturing-arrow-function-1.js new
+7
@@ -0,0 +1,7 @@
1 +function component(a) {
2 + let z = { a };
3 + let x = () => {
4 + z;
5 + };
6 + return x;
7 +}