mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[rhir] small: ReactiveDependency uses Identifier instead of Place
---
We never use the `Place` of a ReactiveScopeDependency, except for when we want
to access its identifier. Later PRs in this stack will convert
`ReactiveScopeDependency` to property access trees (and traverse over the tree).
This usually involves merging multiple Dependencies into trees (where each root
is a unique identifier). We then traverse over each tree to extract its
dependencies (e.g. unconditional leaves).
```
{place: {loc: 1, identifier: 'props'}, path: ['a', 'b']}
{place: {loc: 2, identifier: 'props'}, path: ['a']}
// merges into a single tree root, which should represent a single identifier
```
The `place` of each individual `ReactiveScopeDependency` will be lost during the
tree traversal, and it doesn't really make sense to recreate them using the
`Place` attached to the tree root.
This commit is contained in:
@@ -620,7 +620,7 @@ export type ReactiveScope = {
|
||||
};
|
||||
|
||||
export type ReactiveScopeDependency = {
|
||||
place: Place;
|
||||
identifier: Identifier;
|
||||
path: Array<string> | null;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ class State {
|
||||
const objectDependency = this.properties.get(object.identifier);
|
||||
let nextDependency: ReactiveScopeDependency;
|
||||
if (objectDependency === undefined) {
|
||||
nextDependency = { place: object, path: [property] };
|
||||
nextDependency = { identifier: object.identifier, path: [property] };
|
||||
} else {
|
||||
nextDependency = {
|
||||
place: objectDependency.place,
|
||||
identifier: objectDependency.identifier,
|
||||
path: [...(objectDependency.path ?? []), property],
|
||||
};
|
||||
}
|
||||
@@ -36,7 +36,7 @@ class State {
|
||||
const resolved: ReactiveScopeDependency = this.properties.get(
|
||||
value.identifier
|
||||
) ?? {
|
||||
place: value,
|
||||
identifier: value.identifier,
|
||||
path: null,
|
||||
};
|
||||
this.properties.set(lvalue.identifier, resolved);
|
||||
@@ -98,7 +98,7 @@ function infer(value: FunctionExpression, state: State, context: Place[]) {
|
||||
|
||||
if (state.properties.has(dep.identifier)) {
|
||||
const receiver = state.properties.get(dep.identifier)!;
|
||||
name = receiver.place.identifier.name;
|
||||
name = receiver.identifier.name;
|
||||
} else {
|
||||
name = dep.identifier.name;
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ function codegenDependency(
|
||||
cx: Context,
|
||||
dependency: ReactiveScopeDependency
|
||||
): t.Expression {
|
||||
let object: t.Expression = convertIdentifier(dependency.place.identifier);
|
||||
let object: t.Expression = convertIdentifier(dependency.identifier);
|
||||
if (dependency.path !== null) {
|
||||
for (const path of dependency.path) {
|
||||
object = t.memberExpression(object, t.identifier(path));
|
||||
|
||||
@@ -56,11 +56,11 @@ export function printReactiveBlock(
|
||||
}
|
||||
|
||||
function printDependency(dependency: ReactiveScopeDependency): string {
|
||||
const place = printPlace(dependency.place);
|
||||
const identifier = printIdentifier(dependency.identifier);
|
||||
if (dependency.path === null) {
|
||||
return place;
|
||||
return identifier;
|
||||
} else {
|
||||
return `${place}${dependency.path.map((prop) => `.${prop}`).join("")}`;
|
||||
return `${identifier}${dependency.path.map((prop) => `.${prop}`).join("")}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
|
||||
override visitScope(block: ReactiveScopeBlock, state: VisitorState): void {
|
||||
this.traverseScope(block, state);
|
||||
for (const dep of block.scope.dependencies) {
|
||||
const { identifier } = dep.place;
|
||||
const { identifier } = dep;
|
||||
if (identifier.name == null) {
|
||||
identifier.name = `t${state.nextId++}`;
|
||||
}
|
||||
|
||||
@@ -99,10 +99,13 @@ class Context {
|
||||
const objectDependency = this.#properties.get(resolvedObject.identifier);
|
||||
let nextDependency: ReactiveScopeDependency;
|
||||
if (objectDependency === undefined) {
|
||||
nextDependency = { place: resolvedObject, path: [property] };
|
||||
nextDependency = {
|
||||
identifier: resolvedObject.identifier,
|
||||
path: [property],
|
||||
};
|
||||
} else {
|
||||
nextDependency = {
|
||||
place: objectDependency.place,
|
||||
identifier: objectDependency.identifier,
|
||||
path: [...(objectDependency.path ?? []), property],
|
||||
};
|
||||
}
|
||||
@@ -119,7 +122,7 @@ class Context {
|
||||
|
||||
visitOperand(place: Place): void {
|
||||
const resolved = this.#temporaries.get(place.identifier) ?? place;
|
||||
this.visitDependency({ place: resolved, path: null });
|
||||
this.visitDependency({ identifier: resolved.identifier, path: null });
|
||||
}
|
||||
|
||||
visitProperty(object: Place, property: string): void {
|
||||
@@ -127,10 +130,13 @@ class Context {
|
||||
const objectDependency = this.#properties.get(resolvedObject.identifier);
|
||||
let nextDependency: ReactiveScopeDependency;
|
||||
if (objectDependency === undefined) {
|
||||
nextDependency = { place: resolvedObject, path: [property] };
|
||||
nextDependency = {
|
||||
identifier: resolvedObject.identifier,
|
||||
path: [property],
|
||||
};
|
||||
} else {
|
||||
nextDependency = {
|
||||
place: objectDependency.place,
|
||||
identifier: objectDependency.identifier,
|
||||
path: [...(objectDependency.path ?? []), property],
|
||||
};
|
||||
}
|
||||
@@ -146,8 +152,8 @@ class Context {
|
||||
} else {
|
||||
// Otherwise if this operand is a temporary created for a property load, resolve it to
|
||||
// the expanded Place. Fall back to using the operand as-is.
|
||||
let propDep = this.#properties.get(dependency.place.identifier);
|
||||
if (dependency.place.identifier.name === null && propDep !== undefined) {
|
||||
let propDep = this.#properties.get(dependency.identifier);
|
||||
if (dependency.identifier.name === null && propDep !== undefined) {
|
||||
maybeDependency = propDep;
|
||||
} else {
|
||||
maybeDependency = dependency;
|
||||
@@ -163,7 +169,7 @@ class Context {
|
||||
// if originalDeclaration is undefined here, then this is a free var
|
||||
// (all other decls e.g. `let x;` should be initialized in BuildHIR)
|
||||
const originalDeclaration = this.#declarations.get(
|
||||
maybeDependency.place.identifier.id
|
||||
maybeDependency.identifier.id
|
||||
);
|
||||
if (
|
||||
originalDeclaration !== undefined &&
|
||||
@@ -171,16 +177,16 @@ class Context {
|
||||
!this.#isScopeActive(originalDeclaration.scope)
|
||||
) {
|
||||
originalDeclaration.scope.declarations.set(
|
||||
maybeDependency.place.identifier.id,
|
||||
maybeDependency.place.identifier
|
||||
maybeDependency.identifier.id,
|
||||
maybeDependency.identifier
|
||||
);
|
||||
}
|
||||
|
||||
// If this operand is used in a scope, has a dynamic value, and was defined
|
||||
// before this scope, then its a dependency of the scope.
|
||||
const currentDeclaration =
|
||||
this.#reassignments.get(maybeDependency.place.identifier) ??
|
||||
this.#declarations.get(maybeDependency.place.identifier.id);
|
||||
this.#reassignments.get(maybeDependency.identifier) ??
|
||||
this.#declarations.get(maybeDependency.identifier.id);
|
||||
const currentScope = this.currentScope;
|
||||
if (
|
||||
currentScope != null &&
|
||||
@@ -195,7 +201,7 @@ class Context {
|
||||
// Check if there is an existing dependency that describes this operand
|
||||
for (const dep of this.#dependencies) {
|
||||
// not the same identifier
|
||||
if (dep.place.identifier.id !== maybeDependency.place.identifier.id) {
|
||||
if (dep.identifier.id !== maybeDependency.identifier.id) {
|
||||
continue;
|
||||
}
|
||||
const depPath = dep.path ?? [];
|
||||
|
||||
@@ -26,7 +26,7 @@ class Visitor extends ReactiveFunctionVisitor<State> {
|
||||
override visitScope(scope: ReactiveScopeBlock, state: State): void {
|
||||
this.traverseScope(scope, state);
|
||||
for (const dep of scope.scope.dependencies) {
|
||||
const isReactive = state.has(dep.place.identifier.id);
|
||||
const isReactive = state.has(dep.identifier.id);
|
||||
if (!isReactive) {
|
||||
scope.scope.dependencies.delete(dep);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user