[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:
Mofei Zhang
2023-02-27 13:38:02 -05:00
parent f335e7d4d9
commit 9ca41f8a2e
7 changed files with 30 additions and 24 deletions
+1 -1
View File
@@ -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);
}