PruneAlwaysInvalidatingScopes.ts — react Source File
Architecture documentation for PruneAlwaysInvalidatingScopes.ts, a typescript file in the react codebase. 2 imports, 1 dependents.
Entity Profile
Dependency Diagram
graph LR fec8c712_326d_ff8d_0b77_541838e68d7b["PruneAlwaysInvalidatingScopes.ts"] 0423f759_97e0_9101_4634_ed555abc5ca9["index.ts"] fec8c712_326d_ff8d_0b77_541838e68d7b --> 0423f759_97e0_9101_4634_ed555abc5ca9 9dc3e5f8_0649_d981_e520_38c0ab672d18["."] fec8c712_326d_ff8d_0b77_541838e68d7b --> 9dc3e5f8_0649_d981_e520_38c0ab672d18 e3cfc07a_10c8_5dcd_e270_e8e14c29309b["Pipeline.ts"] e3cfc07a_10c8_5dcd_e270_e8e14c29309b --> fec8c712_326d_ff8d_0b77_541838e68d7b style fec8c712_326d_ff8d_0b77_541838e68d7b fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {ReactiveFunctionTransform, Transformed, visitReactiveFunction} from '.';
import {
Identifier,
ReactiveFunction,
ReactiveInstruction,
ReactiveScopeBlock,
ReactiveStatement,
} from '../HIR';
/**
* Some instructions will *always* produce a new value, and unless memoized will *always*
* invalidate downstream reactive scopes. This pass finds such values and prunes downstream
* memoization.
*
* NOTE: function calls are an edge-case: function calls *may* return primitives, so this
* pass optimistically assumes they do. Therefore, unmemoized function calls will *not*
* prune downstream memoization. Only guaranteed new allocations, such as object and array
* literals, will cause pruning.
*/
export function pruneAlwaysInvalidatingScopes(fn: ReactiveFunction): void {
visitReactiveFunction(fn, new Transform(), false);
}
class Transform extends ReactiveFunctionTransform<boolean> {
alwaysInvalidatingValues: Set<Identifier> = new Set();
unmemoizedValues: Set<Identifier> = new Set();
override transformInstruction(
instruction: ReactiveInstruction,
withinScope: boolean,
): Transformed<ReactiveStatement> {
this.visitInstruction(instruction, withinScope);
const {lvalue, value} = instruction;
switch (value.kind) {
case 'ArrayExpression':
case 'ObjectExpression':
case 'JsxExpression':
case 'JsxFragment':
case 'NewExpression': {
if (lvalue !== null) {
this.alwaysInvalidatingValues.add(lvalue.identifier);
if (!withinScope) {
this.unmemoizedValues.add(lvalue.identifier);
}
}
break;
}
case 'StoreLocal': {
if (this.alwaysInvalidatingValues.has(value.value.identifier)) {
this.alwaysInvalidatingValues.add(value.lvalue.place.identifier);
}
if (this.unmemoizedValues.has(value.value.identifier)) {
this.unmemoizedValues.add(value.lvalue.place.identifier);
}
break;
}
case 'LoadLocal': {
if (
lvalue !== null &&
this.alwaysInvalidatingValues.has(value.place.identifier)
) {
this.alwaysInvalidatingValues.add(lvalue.identifier);
}
if (
lvalue !== null &&
this.unmemoizedValues.has(value.place.identifier)
) {
this.unmemoizedValues.add(lvalue.identifier);
}
break;
}
}
return {kind: 'keep'};
}
override transformScope(
scopeBlock: ReactiveScopeBlock,
_withinScope: boolean,
): Transformed<ReactiveStatement> {
this.visitScope(scopeBlock, true);
for (const dep of scopeBlock.scope.dependencies) {
if (this.unmemoizedValues.has(dep.identifier)) {
/*
* This scope depends on an always-invalidating value so the scope will always invalidate:
* prune it to avoid wasted comparisons
*/
for (const [_, decl] of scopeBlock.scope.declarations) {
if (this.alwaysInvalidatingValues.has(decl.identifier)) {
this.unmemoizedValues.add(decl.identifier);
}
}
for (const identifier of scopeBlock.scope.reassignments) {
if (this.alwaysInvalidatingValues.has(identifier)) {
this.unmemoizedValues.add(identifier);
}
}
return {
kind: 'replace',
value: {
kind: 'pruned-scope',
scope: scopeBlock.scope,
instructions: scopeBlock.instructions,
},
};
}
}
return {kind: 'keep'};
}
}
Domain
Subdomains
Functions
Classes
Dependencies
Source
Frequently Asked Questions
What does PruneAlwaysInvalidatingScopes.ts do?
PruneAlwaysInvalidatingScopes.ts is a source file in the react codebase, written in typescript. It belongs to the BabelCompiler domain, Validation subdomain.
What functions are defined in PruneAlwaysInvalidatingScopes.ts?
PruneAlwaysInvalidatingScopes.ts defines 1 function(s): pruneAlwaysInvalidatingScopes.
What does PruneAlwaysInvalidatingScopes.ts depend on?
PruneAlwaysInvalidatingScopes.ts imports 2 module(s): ., index.ts.
What files import PruneAlwaysInvalidatingScopes.ts?
PruneAlwaysInvalidatingScopes.ts is imported by 1 file(s): Pipeline.ts.
Where is PruneAlwaysInvalidatingScopes.ts in the architecture?
PruneAlwaysInvalidatingScopes.ts is located at compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneAlwaysInvalidatingScopes.ts (domain: BabelCompiler, subdomain: Validation, directory: compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes).
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free