Consistently use new lowering for OptionalMemberExpression

Earlier PRs in the stack change the way we lower OptionalMemberExpression, but 
only when they ultimately appear inside some OptionalCallExpression. This PR 
ensures that _all_ OptionalMemberExpressions get the new lowering. Note that one 
test case has what is arguably a regression, but the new behavior is also 
reasonable: if we see both `a.b?.c` and `a.b.c.` as dependencies of a scope, we 
previously inferred `a.b.c` as the dependency, but we now infer `a.b` as the 
dependency. This isn't as optimal as what we had before, but it also seems good 
enough for now. Also note that some cases are improved: `foo(a.b?.c)` would 
previously have taken `a.b` as a dependency, we now take the full value of 
`a.b?.c` as a dependency - more precise. 

So overall i'm inclined to land and follow-up on the one regression, since the 
overall model is more cohesive.
This commit is contained in:
Joe Savona
2023-05-03 17:10:26 -07:00
parent e5c07ad3e1
commit a43fc2bcf3
4 changed files with 28 additions and 11 deletions
+5 -1
View File
@@ -1425,7 +1425,11 @@ function lowerExpression(
}
}
}
case "OptionalMemberExpression":
case "OptionalMemberExpression": {
const expr = exprPath as NodePath<t.OptionalMemberExpression>;
const { value } = lowerOptionalMemberExpression(builder, expr, null);
return { kind: "LoadLocal", place: value, loc: value.loc };
}
case "MemberExpression": {
const expr = exprPath as NodePath<
t.MemberExpression | t.OptionalMemberExpression
@@ -525,7 +525,19 @@ function computeMemoizationInputs(
rvalues: [value.value],
};
}
case "OptionalExpression":
case "OptionalExpression": {
// Indirection for the inner value, memoized if the value is
const lvalues = [];
if (lvalue !== null) {
lvalues.push({ place: lvalue, level: MemoizationLevel.Conditional });
}
return {
lvalues: lvalues,
rvalues: [
...computeMemoizationInputs(value.value, null, options).rvalues,
],
};
}
case "RegExpLiteral":
case "FunctionExpression":
case "TaggedTemplateExpression":
@@ -18,16 +18,17 @@ import { unstable_useMemoCache as useMemoCache } from "react"; // We should code
// (i.e. placing `?` in the correct PropertyLoad)
function Component(props) {
const $ = useMemoCache(2);
const c_0 = $[0] !== props.a;
let t0;
const t0 = props.a?.b.c.d;
const c_0 = $[0] !== t0;
let t1;
if (c_0) {
t0 = foo(props.a?.b.c.d);
$[0] = props.a;
$[1] = t0;
t1 = foo(t0);
$[0] = t0;
$[1] = t1;
} else {
t0 = $[1];
t1 = $[1];
}
const x = t0;
const x = t1;
return x;
}
@@ -38,13 +38,13 @@ import { unstable_useMemoCache as useMemoCache } from "react"; // To preserve th
function Component(props) {
const $ = useMemoCache(2);
const c_0 = $[0] !== props.a.b;
const c_0 = $[0] !== props.a;
let x;
if (c_0) {
x = [];
x.push(props.a?.b);
x.push(props.a.b.c);
$[0] = props.a.b;
$[0] = props.a;
$[1] = x;
} else {
x = $[1];