[λ] 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
+}