mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove unused Place.memberPath
After the previous PR to change the scope dependency representation, `Place.memberPath` is now completely unused, this PR deletes that field and all references. Rejoice!
This commit is contained in:
@@ -79,7 +79,6 @@ export function lower(
|
||||
const place: Place = {
|
||||
kind: "Identifier",
|
||||
identifier,
|
||||
memberPath: null,
|
||||
effect: Effect.Unknown,
|
||||
loc: param.loc ?? GeneratedSource,
|
||||
};
|
||||
@@ -624,6 +623,10 @@ function lowerStatement(
|
||||
nodeKind === "let" ? InstructionKind.Let : InstructionKind.Const;
|
||||
for (const declaration of stmt.get("declarations")) {
|
||||
const id = declaration.get("id");
|
||||
invariant(
|
||||
id.isIdentifier(),
|
||||
"Support non-identifier variable declarations"
|
||||
);
|
||||
const init = declaration.get("init");
|
||||
let value: InstructionValue;
|
||||
if (init.hasNode()) {
|
||||
@@ -942,11 +945,12 @@ function lowerExpression(
|
||||
const leftNode = left.node;
|
||||
switch (leftNode.type) {
|
||||
case "Identifier": {
|
||||
const lvalue = left as NodePath<t.Identifier>;
|
||||
return lowerAssignment(
|
||||
builder,
|
||||
leftNode.loc ?? GeneratedSource,
|
||||
InstructionKind.Reassign,
|
||||
left,
|
||||
lvalue,
|
||||
lowerExpression(builder, expr.get("right"))
|
||||
);
|
||||
}
|
||||
@@ -1247,7 +1251,6 @@ function lowerJsxElementName(
|
||||
const place: Place = {
|
||||
kind: "Identifier",
|
||||
identifier: identifier,
|
||||
memberPath: null,
|
||||
effect: Effect.Unknown,
|
||||
loc: exprLoc,
|
||||
};
|
||||
@@ -1373,47 +1376,12 @@ function lowerIdentifier(
|
||||
const place: Place = {
|
||||
kind: "Identifier",
|
||||
identifier: identifier,
|
||||
memberPath: null,
|
||||
effect: Effect.Unknown,
|
||||
loc: exprLoc,
|
||||
};
|
||||
return place;
|
||||
}
|
||||
|
||||
function lowerLVal(builder: HIRBuilder, exprPath: NodePath<t.LVal>): Place {
|
||||
const exprNode = exprPath.node;
|
||||
const exprLoc = exprNode.loc ?? GeneratedSource;
|
||||
switch (exprNode.type) {
|
||||
case "Identifier": {
|
||||
const expr = exprPath as NodePath<t.Identifier>;
|
||||
return lowerIdentifier(builder, expr);
|
||||
}
|
||||
case "MemberExpression": {
|
||||
const expr = exprPath as NodePath<t.MemberExpression>;
|
||||
const objectPath = expr.get("object");
|
||||
todoInvariant(objectPath.isLVal(), "Support complex object assignment");
|
||||
const object = lowerLVal(builder, objectPath);
|
||||
const propertyPath = expr.get("property");
|
||||
todoInvariant(
|
||||
propertyPath.isIdentifier(),
|
||||
"Support non-identifier properties"
|
||||
);
|
||||
const place: Place = {
|
||||
kind: "Identifier",
|
||||
identifier: object.identifier,
|
||||
memberPath: [...(object.memberPath ?? []), propertyPath.node.name],
|
||||
effect: Effect.Unknown,
|
||||
loc: exprLoc,
|
||||
};
|
||||
return place;
|
||||
}
|
||||
default: {
|
||||
todo(`lowerLVal(${exprNode.type})`);
|
||||
// assertExhaustive(exprNode, "Unexpected lval kind");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a temporary Identifier and Place referencing that identifier.
|
||||
*/
|
||||
@@ -1421,7 +1389,6 @@ function buildTemporaryPlace(builder: HIRBuilder, loc: SourceLocation): Place {
|
||||
const place: Place = {
|
||||
kind: "Identifier",
|
||||
identifier: builder.makeTemporary(),
|
||||
memberPath: null,
|
||||
effect: Effect.Unknown,
|
||||
loc,
|
||||
};
|
||||
@@ -1432,10 +1399,10 @@ function lowerAssignment(
|
||||
builder: HIRBuilder,
|
||||
loc: SourceLocation,
|
||||
kind: InstructionKind,
|
||||
lvalue: NodePath<t.LVal>,
|
||||
lvalue: NodePath<t.Identifier>,
|
||||
value: InstructionValue
|
||||
): InstructionValue {
|
||||
const id = lowerLVal(builder, lvalue);
|
||||
const id = lowerIdentifier(builder, lvalue);
|
||||
builder.push({
|
||||
id: makeInstructionId(0),
|
||||
lvalue: { place: id, kind },
|
||||
|
||||
@@ -302,10 +302,7 @@ export function codegenInstruction(
|
||||
if (instr.lvalue === null) {
|
||||
return t.expressionStatement(value);
|
||||
}
|
||||
if (
|
||||
instr.lvalue.place.memberPath === null &&
|
||||
instr.lvalue.place.identifier.name === null
|
||||
) {
|
||||
if (instr.lvalue.place.identifier.name === null) {
|
||||
// temporary
|
||||
temp.set(instr.lvalue.place.identifier.id, value);
|
||||
return t.emptyStatement();
|
||||
@@ -511,15 +508,7 @@ function codegenJsxElement(
|
||||
}
|
||||
|
||||
export function codegenLVal(lval: LValue): t.LVal {
|
||||
const expr = convertIdentifier(lval.place.identifier);
|
||||
const memberPath = lval.place.memberPath;
|
||||
return memberPath == null
|
||||
? expr
|
||||
: memberPath.reduceRight(
|
||||
(path: t.Identifier | t.MemberExpression, member) =>
|
||||
t.memberExpression(path, t.identifier(member)),
|
||||
expr
|
||||
);
|
||||
return convertIdentifier(lval.place.identifier);
|
||||
}
|
||||
|
||||
function codegenValue(
|
||||
@@ -543,19 +532,11 @@ function codegenValue(
|
||||
|
||||
export function codegenPlace(temp: Temporaries, place: Place): t.Expression {
|
||||
todoInvariant(place.kind === "Identifier", "support scope values");
|
||||
if (place.memberPath === null) {
|
||||
let tmp = temp.get(place.identifier.id);
|
||||
if (tmp != null) {
|
||||
return tmp;
|
||||
}
|
||||
return convertIdentifier(place.identifier);
|
||||
} else {
|
||||
let object: t.Expression = convertIdentifier(place.identifier);
|
||||
for (const path of place.memberPath) {
|
||||
object = t.memberExpression(object, t.identifier(path));
|
||||
}
|
||||
return object;
|
||||
let tmp = temp.get(place.identifier.id);
|
||||
if (tmp != null) {
|
||||
return tmp;
|
||||
}
|
||||
return convertIdentifier(place.identifier);
|
||||
}
|
||||
|
||||
export function convertIdentifier(identifier: Identifier): t.Identifier {
|
||||
|
||||
@@ -316,7 +316,6 @@ export type InstructionData =
|
||||
export type Place = {
|
||||
kind: "Identifier";
|
||||
identifier: Identifier;
|
||||
memberPath: Array<string> | null;
|
||||
effect: Effect;
|
||||
loc: SourceLocation;
|
||||
};
|
||||
|
||||
@@ -7,11 +7,6 @@ class AliasAnalyser {
|
||||
aliases = new DisjointSet<Identifier>();
|
||||
|
||||
alias(lvalue: LValue, alias: Place) {
|
||||
// This is handled by InferAliasForStores.
|
||||
if (lvalue.place.memberPath !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.aliases.union([lvalue.place.identifier, alias.identifier]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,19 +122,15 @@ export function inferMutableLifetimes(
|
||||
}
|
||||
|
||||
if (instr.lvalue !== null) {
|
||||
if (instr.lvalue.place.memberPath === null) {
|
||||
const lvalueId = instr.lvalue.place.identifier;
|
||||
const lvalueId = instr.lvalue.place.identifier;
|
||||
|
||||
// lvalue start being mutable when they're initially assigned a
|
||||
// value.
|
||||
lvalueId.mutableRange.start = instr.id;
|
||||
// lvalue start being mutable when they're initially assigned a
|
||||
// value.
|
||||
lvalueId.mutableRange.start = instr.id;
|
||||
|
||||
// Let's be optimistic and assume this lvalue is not mutable by
|
||||
// default.
|
||||
lvalueId.mutableRange.end = makeInstructionId(instr.id + 1);
|
||||
} else {
|
||||
inferPlace(instr.lvalue.place, instr, inferMutableRangeForStores);
|
||||
}
|
||||
// Let's be optimistic and assume this lvalue is not mutable by
|
||||
// default.
|
||||
lvalueId.mutableRange.end = makeInstructionId(instr.id + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ export default function inferReferenceEffects(fn: HIRFunction) {
|
||||
const initialEnvironment = Environment.empty();
|
||||
const id: Place = {
|
||||
kind: "Identifier",
|
||||
memberPath: null,
|
||||
identifier: fn.id as any,
|
||||
loc: fn.loc,
|
||||
effect: Effect.Freeze,
|
||||
@@ -172,7 +171,7 @@ class Environment {
|
||||
*/
|
||||
initialize(value: InstructionValue, kind: ValueKind) {
|
||||
invariant(
|
||||
value.kind !== "Identifier" || value.memberPath !== null,
|
||||
value.kind !== "Identifier",
|
||||
"Expected all top-level identifiers to be defined as variables, not values"
|
||||
);
|
||||
this.#values.set(value, kind);
|
||||
@@ -218,10 +217,6 @@ class Environment {
|
||||
* Defines (initializing or updating) a variable with a specific kind of value.
|
||||
*/
|
||||
define(place: Place, value: InstructionValue) {
|
||||
invariant(
|
||||
place.memberPath === null,
|
||||
"Expected a top-level identifier, not a member path"
|
||||
);
|
||||
invariant(
|
||||
this.#values.has(value),
|
||||
`Expected value to be initialized at '${printSourceLocation(value.loc)}'`
|
||||
@@ -587,10 +582,6 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
|
||||
const lvalue = instr.lvalue;
|
||||
if (lvalue !== null) {
|
||||
invariant(
|
||||
lvalue.place.memberPath === null,
|
||||
"PropertyLoad must always be saved to a temporary"
|
||||
);
|
||||
env.alias(lvalue.place, instrValue.value);
|
||||
lvalue.place.effect = Effect.Store;
|
||||
}
|
||||
@@ -611,27 +602,15 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
env.reference(instrValue.object, Effect.Read);
|
||||
const lvalue = instr.lvalue;
|
||||
if (lvalue !== null) {
|
||||
invariant(
|
||||
lvalue.place.memberPath === null,
|
||||
"PropertyLoad must always be saved to a temporary"
|
||||
);
|
||||
env.initialize(instrValue, env.kind(instrValue.object));
|
||||
env.define(lvalue.place, instrValue);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case "Identifier": {
|
||||
invariant(
|
||||
instrValue.memberPath === null,
|
||||
"Expected RHS memberPath to be lowered to PropertyLoad"
|
||||
);
|
||||
env.reference(instrValue, Effect.Read);
|
||||
const lvalue = instr.lvalue;
|
||||
if (lvalue !== null) {
|
||||
invariant(
|
||||
lvalue.place.memberPath === null,
|
||||
"Expected lvalue member path to be null"
|
||||
);
|
||||
lvalue.place.effect = Effect.Mutate;
|
||||
// direct aliasing: `a = b`;
|
||||
env.alias(lvalue.place, instrValue);
|
||||
@@ -654,10 +633,6 @@ function inferBlock(env: Environment, block: BasicBlock) {
|
||||
|
||||
env.initialize(instrValue, valueKind);
|
||||
if (instr.lvalue !== null) {
|
||||
invariant(
|
||||
instr.lvalue.place.memberPath === null,
|
||||
"Expected lvalue member path to be null"
|
||||
);
|
||||
env.define(instr.lvalue.place, instrValue);
|
||||
instr.lvalue.place.effect = lvalueEffect;
|
||||
}
|
||||
@@ -695,10 +670,6 @@ type HookKind = { kind: "State" } | { kind: "Ref" } | { kind: "Custom" };
|
||||
type Hook = HookKind & { effectKind: Effect; valueKind: ValueKind };
|
||||
|
||||
function parseHookCall(place: Place): Hook | null {
|
||||
if (place.memberPath !== null) {
|
||||
// Hook calls must be statically resolved
|
||||
return null;
|
||||
}
|
||||
const name = place.identifier.name;
|
||||
if (name === null || !name.match(/^_?use/)) {
|
||||
return null;
|
||||
|
||||
@@ -132,7 +132,7 @@ function generateTypeEquation(
|
||||
function assignType(place: Place | undefined): Type | null {
|
||||
// We type only top level identifiers. Typing objects is not very useful
|
||||
// when we have to be so conservative.
|
||||
if (place?.memberPath !== null) {
|
||||
if (place === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -321,14 +321,7 @@ export function printLValue(lval: LValue): string {
|
||||
|
||||
export function printPlace(place: Place): string {
|
||||
const items = [place.effect, " ", printIdentifier(place.identifier)];
|
||||
if (place.memberPath !== null) {
|
||||
for (const path of place.memberPath) {
|
||||
items.push(".");
|
||||
items.push(path);
|
||||
}
|
||||
} else {
|
||||
items.push(printType(place.identifier.type));
|
||||
}
|
||||
items.push(printType(place.identifier.type));
|
||||
return items.filter((x) => x != null).join("");
|
||||
}
|
||||
|
||||
|
||||
@@ -305,11 +305,7 @@ export function codegenInstructionNullable(
|
||||
value: t.Expression
|
||||
): t.Statement | null {
|
||||
let statement;
|
||||
if (
|
||||
instr.lvalue !== null &&
|
||||
instr.lvalue.place.memberPath === null &&
|
||||
cx.declared(instr.lvalue.place.identifier)
|
||||
) {
|
||||
if (instr.lvalue !== null && cx.declared(instr.lvalue.place.identifier)) {
|
||||
statement = codegenInstruction(
|
||||
cx.temp,
|
||||
{
|
||||
|
||||
@@ -80,11 +80,7 @@ export function inferReactiveScopeVariables(fn: HIRFunction) {
|
||||
const operands: Array<Identifier> = [];
|
||||
if (instr.lvalue !== null) {
|
||||
const range = instr.lvalue.place.identifier.mutableRange;
|
||||
if (
|
||||
instr.lvalue.place.memberPath !== null ||
|
||||
range.end > range.start + 1 ||
|
||||
mayAllocate(instr.value)
|
||||
) {
|
||||
if (range.end > range.start + 1 || mayAllocate(instr.value)) {
|
||||
operands.push(instr.lvalue!.place.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
ReactiveValueBlock,
|
||||
} from "../HIR/HIR";
|
||||
import { eachInstructionValueOperand } from "../HIR/visitors";
|
||||
import { invariant } from "../Utils/CompilerError";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
|
||||
/**
|
||||
@@ -76,14 +75,6 @@ class Context {
|
||||
}
|
||||
|
||||
declareProperty(lvalue: Place, object: Place, property: string): void {
|
||||
invariant(
|
||||
lvalue.memberPath === null,
|
||||
"Expected property loads to be stored to a temporary (no member path)"
|
||||
);
|
||||
invariant(
|
||||
object.memberPath === null,
|
||||
"Expected operands to have null memberPath"
|
||||
);
|
||||
const objectDependency = this.#properties.get(object.identifier);
|
||||
let nextDependency: ReactiveScopeDependency;
|
||||
if (objectDependency === undefined) {
|
||||
@@ -281,17 +272,7 @@ function visitInstructionValue(
|
||||
): void {
|
||||
for (const operand of eachInstructionValueOperand(value)) {
|
||||
// check for method invocation, we want to depend on the callee, not the method
|
||||
if (
|
||||
value.kind === "CallExpression" &&
|
||||
operand === value.callee &&
|
||||
operand.memberPath !== null
|
||||
) {
|
||||
const callee = {
|
||||
...operand,
|
||||
memberPath: operand.memberPath.slice(0, -1),
|
||||
};
|
||||
context.visitOperand(callee);
|
||||
} else if (value.kind === "PropertyLoad" && lvalue !== null) {
|
||||
if (value.kind === "PropertyLoad" && lvalue !== null) {
|
||||
context.declareProperty(lvalue.place, value.object, value.property);
|
||||
} else {
|
||||
context.visitOperand(operand);
|
||||
@@ -302,11 +283,7 @@ function visitInstructionValue(
|
||||
function visitInstruction(context: Context, instr: Instruction): void {
|
||||
const { lvalue } = instr;
|
||||
visitInstructionValue(context, instr.value, lvalue);
|
||||
if (
|
||||
lvalue !== null &&
|
||||
lvalue.kind !== InstructionKind.Reassign &&
|
||||
lvalue.place.memberPath === null
|
||||
) {
|
||||
if (lvalue !== null && lvalue.kind !== InstructionKind.Reassign) {
|
||||
const range = lvalue.place.identifier.mutableRange;
|
||||
// TODO: only assign Const if the value is never reassigned
|
||||
const kind =
|
||||
|
||||
@@ -199,12 +199,8 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
|
||||
if (instr.lvalue != null) {
|
||||
const oldPlace = instr.lvalue.place;
|
||||
let newPlace: Place;
|
||||
if (oldPlace.memberPath !== null) {
|
||||
newPlace = builder.getPlace(oldPlace);
|
||||
} else {
|
||||
newPlace = builder.definePlace(oldPlace);
|
||||
instr.lvalue.kind = InstructionKind.Const;
|
||||
}
|
||||
newPlace = builder.definePlace(oldPlace);
|
||||
instr.lvalue.kind = InstructionKind.Const;
|
||||
instr.lvalue.place = newPlace;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,13 +136,6 @@ export function leaveSSA(fn: HIRFunction) {
|
||||
const update = fn.body.blocks.get(terminal.update)!;
|
||||
rewritePhis.push(...update.phis);
|
||||
update.phis.clear();
|
||||
|
||||
// find declarations in the for init
|
||||
for (const instr of init.instructions) {
|
||||
if (instr.lvalue !== null && instr.lvalue.place.memberPath === null) {
|
||||
// hasDeclaration.add(instr.lvalue.place.identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const phi of reassignmentPhis) {
|
||||
@@ -197,7 +190,6 @@ export function leaveSSA(fn: HIRFunction) {
|
||||
lvalue: {
|
||||
place: {
|
||||
kind: "Identifier",
|
||||
memberPath: null,
|
||||
identifier: canonicalId,
|
||||
effect: Effect.Mutate,
|
||||
loc: GeneratedSource,
|
||||
@@ -208,7 +200,6 @@ export function leaveSSA(fn: HIRFunction) {
|
||||
initOperand !== null
|
||||
? {
|
||||
kind: "Identifier",
|
||||
memberPath: null,
|
||||
identifier: initOperand,
|
||||
effect: Effect.Read,
|
||||
loc: GeneratedSource,
|
||||
@@ -234,7 +225,6 @@ export function leaveSSA(fn: HIRFunction) {
|
||||
lvalue: {
|
||||
place: {
|
||||
kind: "Identifier",
|
||||
memberPath: null,
|
||||
identifier: canonicalId,
|
||||
effect: Effect.Mutate,
|
||||
loc: GeneratedSource,
|
||||
@@ -243,7 +233,6 @@ export function leaveSSA(fn: HIRFunction) {
|
||||
},
|
||||
value: {
|
||||
kind: "Identifier",
|
||||
memberPath: null,
|
||||
identifier: operand,
|
||||
effect: Effect.Read,
|
||||
loc: GeneratedSource,
|
||||
@@ -295,7 +284,6 @@ export function leaveSSA(fn: HIRFunction) {
|
||||
if (lvalue !== null) {
|
||||
if (
|
||||
lvalue.kind === InstructionKind.Const &&
|
||||
lvalue.place.memberPath === null &&
|
||||
rewrites.has(lvalue.place.identifier)
|
||||
) {
|
||||
// For rewrites, the declaration of the canonical identifier has to be `let`,
|
||||
|
||||
Reference in New Issue
Block a user