mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove unnecessary optional property on loads
Now that _all_ optional expression types use the new representation, the optionality of all PropertyLoad and ComputedLoad is modeled via control flow (in HIR) and the structure of OptionalExpression (in ReactiveFunction). Thus we no longer need the `optional` properties on these load instructions — they're optional if they're part of an OptionalExpression.
This commit is contained in:
@@ -2157,7 +2157,6 @@ function lowerMemberExpression(
|
||||
object: { ...object },
|
||||
property: propertyNode.node.name,
|
||||
loc: exprLoc,
|
||||
optional: expr.node.optional ?? false,
|
||||
};
|
||||
return { object, property: propertyNode.node.name, value };
|
||||
} else {
|
||||
@@ -2177,26 +2176,21 @@ function lowerMemberExpression(
|
||||
},
|
||||
};
|
||||
}
|
||||
let optional;
|
||||
let property: Place;
|
||||
|
||||
// See "PropertyLoad" for the difference between optionalMemberExpr()
|
||||
// and node.optional here
|
||||
if (expr.isOptionalMemberExpression()) {
|
||||
// if expr is in an optional chain, evaluation of `property` is
|
||||
// conditional on whether expr is nullish
|
||||
property = lowerReorderableExpression(builder, propertyNode);
|
||||
optional = expr.node.optional ?? false;
|
||||
} else {
|
||||
property = lowerExpressionToTemporary(builder, propertyNode);
|
||||
optional = false;
|
||||
}
|
||||
const value: InstructionValue = {
|
||||
kind: "ComputedLoad",
|
||||
object: { ...object },
|
||||
property: { ...property },
|
||||
loc: exprLoc,
|
||||
optional,
|
||||
};
|
||||
return { object, property, value };
|
||||
}
|
||||
@@ -2280,7 +2274,6 @@ function lowerJsxMemberExpression(
|
||||
kind: "PropertyLoad",
|
||||
object: objectPlace,
|
||||
property,
|
||||
optional: false,
|
||||
loc,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -645,7 +645,6 @@ export type InstructionValue =
|
||||
kind: "PropertyLoad";
|
||||
object: Place;
|
||||
property: string;
|
||||
optional: boolean;
|
||||
loc: SourceLocation;
|
||||
}
|
||||
// `delete object.property`
|
||||
@@ -669,7 +668,6 @@ export type InstructionValue =
|
||||
kind: "ComputedLoad";
|
||||
object: Place;
|
||||
property: Place;
|
||||
optional: boolean;
|
||||
loc: SourceLocation;
|
||||
}
|
||||
// `delete object[property]`
|
||||
|
||||
@@ -367,9 +367,9 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
|
||||
break;
|
||||
}
|
||||
case "PropertyLoad": {
|
||||
value = `PropertyLoad ${printPlace(instrValue.object)}${
|
||||
instrValue.optional ? "?" : ""
|
||||
}.${instrValue.property}`;
|
||||
value = `PropertyLoad ${printPlace(instrValue.object)}.${
|
||||
instrValue.property
|
||||
}`;
|
||||
break;
|
||||
}
|
||||
case "PropertyStore": {
|
||||
@@ -385,9 +385,9 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
|
||||
break;
|
||||
}
|
||||
case "ComputedLoad": {
|
||||
value = `ComputedLoad ${printPlace(instrValue.object)}${
|
||||
instrValue.optional ? "?" : ""
|
||||
}[${printPlace(instrValue.property)}]`;
|
||||
value = `ComputedLoad ${printPlace(instrValue.object)}[${printPlace(
|
||||
instrValue.property
|
||||
)}]`;
|
||||
break;
|
||||
}
|
||||
case "ComputedStore": {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
import { isValidIdentifier } from "@babel/types";
|
||||
import invariant from "invariant";
|
||||
import {
|
||||
GotoVariant,
|
||||
HIRFunction,
|
||||
@@ -180,16 +179,7 @@ function evaluateInstruction(
|
||||
loc: value.loc,
|
||||
property: property.value,
|
||||
object: value.object,
|
||||
optional: value.optional,
|
||||
};
|
||||
// Future-proofing: when we add support for optional computed properties,
|
||||
// we'll need to copy the value here
|
||||
if ((value as any).optional) {
|
||||
invariant(
|
||||
false,
|
||||
"TODO: translate optional computed load to optional property load"
|
||||
);
|
||||
}
|
||||
instr.value = nextValue;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -853,21 +853,11 @@ function codegenInstructionValue(
|
||||
const object = codegenPlace(cx, instrValue.object);
|
||||
// We currently only lower single chains of optional memberexpr.
|
||||
// (See BuildHIR.ts for more detail.)
|
||||
if (t.isOptionalMemberExpression(object) || instrValue.optional) {
|
||||
value = t.optionalMemberExpression(
|
||||
object,
|
||||
t.identifier(instrValue.property),
|
||||
undefined,
|
||||
instrValue.optional
|
||||
);
|
||||
} else {
|
||||
value = t.memberExpression(
|
||||
object,
|
||||
t.identifier(instrValue.property),
|
||||
undefined,
|
||||
instrValue.optional
|
||||
);
|
||||
}
|
||||
value = t.memberExpression(
|
||||
object,
|
||||
t.identifier(instrValue.property),
|
||||
undefined
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "PropertyDelete": {
|
||||
@@ -895,16 +885,7 @@ function codegenInstructionValue(
|
||||
case "ComputedLoad": {
|
||||
const object = codegenPlace(cx, instrValue.object);
|
||||
const property = codegenPlace(cx, instrValue.property);
|
||||
if (t.isOptionalMemberExpression(object) || instrValue.optional) {
|
||||
value = t.optionalMemberExpression(
|
||||
object,
|
||||
property,
|
||||
true,
|
||||
instrValue.optional
|
||||
);
|
||||
} else {
|
||||
value = t.memberExpression(object, property, true, instrValue.optional);
|
||||
}
|
||||
value = t.memberExpression(object, property, true);
|
||||
break;
|
||||
}
|
||||
case "ComputedDelete": {
|
||||
|
||||
@@ -306,13 +306,8 @@ class Context {
|
||||
return objectDependency;
|
||||
}
|
||||
|
||||
declareProperty(
|
||||
lvalue: Place,
|
||||
object: Place,
|
||||
property: string,
|
||||
isConditional: boolean
|
||||
): void {
|
||||
const nextDependency = this.#getProperty(object, property, isConditional);
|
||||
declareProperty(lvalue: Place, object: Place, property: string): void {
|
||||
const nextDependency = this.#getProperty(object, property, false);
|
||||
this.#properties.set(lvalue.identifier, nextDependency);
|
||||
}
|
||||
|
||||
@@ -363,8 +358,8 @@ class Context {
|
||||
this.visitDependency(dependency);
|
||||
}
|
||||
|
||||
visitProperty(object: Place, property: string, isConditional: boolean): void {
|
||||
const nextDependency = this.#getProperty(object, property, isConditional);
|
||||
visitProperty(object: Place, property: string): void {
|
||||
const nextDependency = this.#getProperty(object, property, false);
|
||||
this.visitDependency(nextDependency);
|
||||
}
|
||||
|
||||
@@ -529,14 +524,9 @@ class PropagationVisitor extends ReactiveFunctionVisitor<Context> {
|
||||
}
|
||||
} else if (value.kind === "PropertyLoad") {
|
||||
if (lvalue !== null && !context.isUsedOutsideDeclaringScope(lvalue)) {
|
||||
context.declareProperty(
|
||||
lvalue,
|
||||
value.object,
|
||||
value.property,
|
||||
value.optional
|
||||
);
|
||||
context.declareProperty(lvalue, value.object, value.property);
|
||||
} else {
|
||||
context.visitProperty(value.object, value.property, value.optional);
|
||||
context.visitProperty(value.object, value.property);
|
||||
}
|
||||
} else if (value.kind === "StoreLocal") {
|
||||
context.visitOperand(value.value);
|
||||
|
||||
Reference in New Issue
Block a user