Skip to content

Commit

Permalink
[rfc] Desugar FunctionDeclaration to a FunctionExpression
Browse files Browse the repository at this point in the history
  • Loading branch information
gsathya committed Mar 30, 2023
1 parent 05f48e2 commit e81063e
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 10 deletions.
37 changes: 36 additions & 1 deletion compiler/forget/src/HIR/BuildHIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,42 @@ function lowerStatement(
builder.terminateWithContinuation(terminal, continuationBlock);
return;
}
case "FunctionDeclaration": {
const stmt = stmtPath as NodePath<t.FunctionDeclaration>;
stmt.skip();
invariant(
stmt.get("id").type === "Identifier",
"function declarations must have a name"
);
const id = stmt.get("id") as NodePath<t.Identifier>;

// Desugar FunctionDeclaration to FunctionExpression.
//
// For example:
// function foo() {};
// becomes
// let foo = function foo() {};
const desugared = stmt.replaceWith(
t.variableDeclaration("let", [
t.variableDeclarator(
id.node,
t.functionExpression(
id.node,
stmt.node.params,
stmt.node.body,
stmt.node.generator,
stmt.node.async
)
),
])
);
invariant(
desugared.length === 1,
"only one declaration is created from desugaring function declaration"
);
lowerStatement(builder, desugared.at(0)!);
return;
}
case "ForOfStatement":
case "ForInStatement":
case "ClassDeclaration":
Expand All @@ -697,7 +733,6 @@ function lowerStatement(
case "ExportAllDeclaration":
case "ExportDefaultDeclaration":
case "ExportNamedDeclaration":
case "FunctionDeclaration":
case "ImportDeclaration":
case "InterfaceDeclaration":
case "OpaqueType":
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

## Input

```javascript
function component(a) {
let t = { a };
function x() {
t.foo();
}
x(t);
return t;
}

```

## Code

```javascript
function component(a) {
const $ = React.unstable_useMemoCache(2);
const c_0 = $[0] !== a;
let t;
if (c_0) {
t = { a };
const x = function x() {
t.foo();
};
x(t);
$[0] = a;
$[1] = t;
} else {
t = $[1];
}
return t;
}

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function component(a) {
let t = { a };
function x() {
t.foo();
}
x(t);
return t;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

## Input

```javascript
function component(a) {
let t = { a };
x(t); // hoisted call
function x(p) {
p.foo();
}
return t;
}

```


## Error

```
[ReactForget] Invariant: identifier x$6 should have been defined before use (4:4)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function component(a) {
let t = { a };
x(t); // hoisted call
function x(p) {
p.foo();
}
return t;
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,15 +292,6 @@ let moduleLocal = false;
62 |
63 | function component(a) {
64 | // Add support for function declarations once we support `var` hoisting.
[ReactForget] TodoError: (BuildHIR::lowerStatement) Handle FunctionDeclaration statements
61 | moduleLocal = true;
62 |
> 63 | function component(a) {
| ^
64 | // Add support for function declarations once we support `var` hoisting.
65 | function t() {}
66 | t();
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

## Input

```javascript
function component() {
function x(a) {
a.foo();
}
x = {};
return x;
}

```

## Code

```javascript
function component() {
const $ = React.unstable_useMemoCache(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = {};
$[0] = t0;
} else {
t0 = $[0];
}
const x = t0;
return x;
}

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function component() {
function x(a) {
a.foo();
}
x = {};
return x;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

## Input

```javascript
function component() {
function x(a) {
a.foo();
}
function x() {}
return x;
}

```

## Code

```javascript
function component() {
const $ = React.unstable_useMemoCache(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = function x() {};
$[0] = t0;
} else {
t0 = $[0];
}
const x = t0;
return x;
}

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function component() {
function x(a) {
a.foo();
}
function x() {}
return x;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

## Input

```javascript
function component(a) {
let t = { a };
function x(p) {
p.foo();
}
x(t);
return t;
}

```

## Code

```javascript
function component(a) {
const $ = React.unstable_useMemoCache(2);
const c_0 = $[0] !== a;
let t;
if (c_0) {
t = { a };
const x = function x(p) {
p.foo();
};
x(t);
$[0] = a;
$[1] = t;
} else {
t = $[1];
}
return t;
}

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function component(a) {
let t = { a };
function x(p) {
p.foo();
}
x(t);
return t;
}

0 comments on commit e81063e

Please sign in to comment.