[be] Make ReactiveScopeDependency.path nonnullable
--- Previously, both `path=null` and `path=[]` could represent a dependency with no property path (i.e. the result of a LoadLocal with no PropertyLoad). Make path non-nullable so we don't have to add null checks everywhere.
Mofei Zhang committed
Mar 24, 2023 at 17:53 UTC
4aef9dac4990d1869b25ef68671806916d31a396
5 files changed
+21
-30
compiler/forget/src/HIR/HIR.ts
+1
-1
@@ -738,7 +738,7 @@ export type ReactiveScope = {
738
739
export type ReactiveScopeDependency = {
740
identifier: Identifier;
741
- path: Array<string> | null;
741
+ path: Array<string>;
742
};
743
744
/**
compiler/forget/src/Inference/AnalyseFunctions.ts
+2
-2
@@ -26,7 +26,7 @@ class State {
26
} else {
27
nextDependency = {
28
identifier: objectDependency.identifier,
29
- path: [...(objectDependency.path ?? []), property],
29
+ path: [...objectDependency.path, property],
30
};
31
}
32
this.properties.set(lvalue.identifier, nextDependency);
@@ -37,7 +37,7 @@ class State {
37
value.identifier
38
) ?? {
39
identifier: value.identifier,
40
- path: null,
40
+ path: [],
41
};
42
this.properties.set(lvalue.identifier, resolved);
43
}
compiler/forget/src/ReactiveScopes/DeriveMinimalDependencies.ts
+1
-1
@@ -43,7 +43,7 @@ export class ReactiveScopeDependencyTree {
43
}
44
45
add(dep: ReactiveScopeDependency, inConditional: boolean): void {
46
- const path = dep.path ?? [];
46
+ const { path } = dep;
47
let currNode = this.#getOrCreateRoot(dep.identifier);
48
49
const accessType = inConditional
compiler/forget/src/ReactiveScopes/PrintReactiveFunction.ts
+1
-5
@@ -56,11 +56,7 @@ export function printReactiveBlock(
56
57
function printDependency(dependency: ReactiveScopeDependency): string {
58
const identifier = printIdentifier(dependency.identifier);
59
- if (dependency.path === null) {
60
- return identifier;
61
- } else {
62
- return `${identifier}${dependency.path.map((prop) => `.${prop}`).join("")}`;
63
- }
59
+ return `${identifier}${dependency.path.map((prop) => `.${prop}`).join("")}`;
60
}
61
62
export function printReactiveInstructions(
compiler/forget/src/ReactiveScopes/PropagateScopeDependencies.ts
+16
-21
@@ -198,7 +198,7 @@ class Context {
198
} else {
199
nextDependency = {
200
identifier: objectDependency.identifier,
201
- path: [...(objectDependency.path ?? []), property],
201
+ path: [...objectDependency.path, property],
202
};
203
}
204
this.#properties.set(lvalue.identifier, nextDependency);
@@ -231,10 +231,20 @@ class Context {
231
232
visitOperand(place: Place): void {
233
const resolved = this.#temporaries.get(place.identifier) ?? place;
234
- this.visitDependency({
234
+ // if this operand is a temporary created for a property load, try to resolve it to
235
+ // the expanded Place. Fall back to using the operand as-is.
236
+
237
+ let dependency: ReactiveScopeDependency = {
238
identifier: resolved.identifier,
236
- path: null,
237
- });
239
+ path: [],
240
+ };
241
+ if (resolved.identifier.name === null) {
242
+ const propertyDependency = this.#properties.get(resolved.identifier);
243
+ if (propertyDependency !== undefined) {
244
+ dependency = { ...propertyDependency };
245
+ }
246
+ }
247
+ this.visitDependency(dependency);
248
}
249
250
visitProperty(object: Place, property: string): void {
@@ -249,28 +259,13 @@ class Context {
259
} else {
260
nextDependency = {
261
identifier: objectDependency.identifier,
252
- path: [...(objectDependency.path ?? []), property],
262
+ path: [...objectDependency.path, property],
263
};
264
}
265
this.visitDependency(nextDependency);
266
}
267
258
- visitDependency(dependency: ReactiveScopeDependency): void {
259
- let maybeDependency: ReactiveScopeDependency;
260
- if (dependency.path !== null) {
261
- // Operands may have memberPaths when propagating depenencies of an inner scope upward
262
- // In this case we use the dependency as-is
263
- maybeDependency = dependency;
264
- } else {
265
- // Otherwise if this operand is a temporary created for a property load, resolve it to
266
- // the expanded Place. Fall back to using the operand as-is.
267
- let propDep = this.#properties.get(dependency.identifier);
268
- if (dependency.identifier.name === null && propDep !== undefined) {
269
- maybeDependency = { ...propDep };
270
- } else {
271
- maybeDependency = dependency;
272
- }
273
- }
268
+ visitDependency(maybeDependency: ReactiveScopeDependency): void {
269
// Any value used after its originally defining scope has concluded must be added as an
270
// output of its defining scope. Regardless of whether its a const or not,
271
// some later code needs access to the value. If the current