[λ] Support member expressions in lambdas

Lower member expression if the receiver is in scope. Skip the remaining path 
before capturing so we don't recurse down the identifiers in the member 
expression.
This commit is contained in:
Sathya Gunasekaran
2023-01-19 12:13:35 +00:00
parent ef5636c25d
commit f42c51b971
9 changed files with 281 additions and 3 deletions
+8 -3
View File
@@ -1665,16 +1665,21 @@ function gatherCapturedDeps(
fn.get("body").traverse({
Expression(path) {
// TODO(gsn): Handle member expressions
if (!path.isIdentifier()) {
let obj = path;
while (obj.isMemberExpression()) {
obj = obj.get("object");
}
if (!obj.isIdentifier()) {
return;
}
const binding = path.scope.getBinding(path.node.name);
const binding = obj.scope.getBinding(obj.node.name);
if (binding === undefined || !pureScopes.has(binding.scope)) {
return;
}
path.skip();
captured.add(lowerExpressionToPlace(builder, path));
},
});
@@ -0,0 +1,50 @@
## Input
```javascript
function component(a) {
let z = { a };
let x = function () {
z.a;
};
return x;
}
```
## Code
```javascript
function component(a) {
const $ = React.useMemoCache();
const c_0 = $[0] !== a;
let z;
if (c_0) {
z = {
a: a,
};
$[0] = a;
$[1] = z;
} else {
z = $[1];
}
const c_2 = $[2] !== z.a;
let x;
if (c_2) {
x = function () {
z.a;
};
$[2] = z.a;
$[3] = x;
} else {
x = $[3];
}
return x;
}
```
@@ -0,0 +1,7 @@
function component(a) {
let z = { a };
let x = function () {
z.a;
};
return x;
}
@@ -0,0 +1,63 @@
## Input
```javascript
function component(a) {
let z = { a: { a } };
let x = function () {
z.a.a();
};
return x;
}
```
## Code
```javascript
function component(a) {
const $ = React.useMemoCache();
const c_0 = $[0] !== a;
let t1;
if (c_0) {
t1 = {
a: a,
};
$[0] = a;
$[1] = t1;
} else {
t1 = $[1];
}
const c_2 = $[2] !== t1;
let z;
if (c_2) {
z = {
a: t1,
};
$[2] = t1;
$[3] = z;
} else {
z = $[3];
}
const c_4 = $[4] !== z.a.a;
let x;
if (c_4) {
x = function () {
z.a.a();
};
$[4] = z.a.a;
$[5] = x;
} else {
x = $[5];
}
return x;
}
```
@@ -0,0 +1,7 @@
function component(a) {
let z = { a: { a } };
let x = function () {
z.a.a();
};
return x;
}
@@ -0,0 +1,67 @@
## Input
```javascript
function component(a) {
let z = { a: { a } };
let x = function () {
(function () {
z.a.a;
})();
};
return x;
}
```
## Code
```javascript
function component(a) {
const $ = React.useMemoCache();
const c_0 = $[0] !== a;
let t1;
if (c_0) {
t1 = {
a: a,
};
$[0] = a;
$[1] = t1;
} else {
t1 = $[1];
}
const c_2 = $[2] !== t1;
let z;
if (c_2) {
z = {
a: t1,
};
$[2] = t1;
$[3] = z;
} else {
z = $[3];
}
const c_4 = $[4] !== z.a.a;
let x;
if (c_4) {
x = function () {
(function () {
z.a.a;
})();
};
$[4] = z.a.a;
$[5] = x;
} else {
x = $[5];
}
return x;
}
```
@@ -0,0 +1,9 @@
function component(a) {
let z = { a: { a } };
let x = function () {
(function () {
z.a.a;
})();
};
return x;
}
@@ -0,0 +1,63 @@
## Input
```javascript
function component(a) {
let z = { a: { a } };
let x = function () {
z.a.a;
};
return x;
}
```
## Code
```javascript
function component(a) {
const $ = React.useMemoCache();
const c_0 = $[0] !== a;
let t1;
if (c_0) {
t1 = {
a: a,
};
$[0] = a;
$[1] = t1;
} else {
t1 = $[1];
}
const c_2 = $[2] !== t1;
let z;
if (c_2) {
z = {
a: t1,
};
$[2] = t1;
$[3] = z;
} else {
z = $[3];
}
const c_4 = $[4] !== z.a.a;
let x;
if (c_4) {
x = function () {
z.a.a;
};
$[4] = z.a.a;
$[5] = x;
} else {
x = $[5];
}
return x;
}
```
@@ -0,0 +1,7 @@
function component(a) {
let z = { a: { a } };
let x = function () {
z.a.a;
};
return x;
}