@samitouri / QOS-React-2 / commits / 4aef9dac49

[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