compiler: Infer dependencies for pruned scopes

ghstack-source-id: df1084116f
Pull Request resolved: https://github.com/facebook/react/pull/29783
This commit is contained in:
Joe Savona
2024-06-06 09:31:40 -07:00
parent b0d04e808d
commit bb0605f50f
2 changed files with 29 additions and 5 deletions
@@ -18,6 +18,7 @@ import {
isUseRefType,
makeInstructionId,
Place,
PrunedReactiveScopeBlock,
ReactiveFunction,
ReactiveInstruction,
ReactiveScope,
@@ -687,6 +688,16 @@ class PropagationVisitor extends ReactiveFunctionVisitor<Context> {
scope.scope.dependencies = scopeDependencies;
}
override visitPrunedScope(
scopeBlock: PrunedReactiveScopeBlock,
context: Context
): void {
const scopeDependencies = context.enter(scopeBlock.scope, () => {
this.visitBlock(scopeBlock.instructions, context);
});
scopeBlock.scope.dependencies = scopeDependencies;
}
override visitInstruction(
instruction: ReactiveInstruction,
context: Context
@@ -7,8 +7,10 @@
import {
IdentifierId,
PrunedReactiveScopeBlock,
ReactiveFunction,
ReactiveInstruction,
ReactiveScope,
ReactiveScopeBlock,
isSetStateType,
} from "../HIR";
@@ -95,23 +97,34 @@ class Visitor extends ReactiveFunctionVisitor<ReactiveIdentifiers> {
state: ReactiveIdentifiers
): void {
this.traverseScope(scopeBlock, state);
for (const dep of scopeBlock.scope.dependencies) {
this.visitScopeImpl(scopeBlock.scope, state);
}
override visitPrunedScope(
scopeBlock: PrunedReactiveScopeBlock,
state: ReactiveIdentifiers
): void {
this.traversePrunedScope(scopeBlock, state);
}
visitScopeImpl(scope: ReactiveScope, state: ReactiveIdentifiers): void {
for (const dep of scope.dependencies) {
const isReactive = state.has(dep.identifier.id);
if (!isReactive) {
scopeBlock.scope.dependencies.delete(dep);
scope.dependencies.delete(dep);
}
}
if (scopeBlock.scope.dependencies.size !== 0) {
if (scope.dependencies.size !== 0) {
/**
* If any of a scope's dependencies are reactive, then all of its
* outputs will re-evaluate whenever those dependencies change.
* Mark all of the outputs as reactive to reflect the fact that
* they may change in practice based on a reactive input.
*/
for (const [, declaration] of scopeBlock.scope.declarations) {
for (const [, declaration] of scope.declarations) {
state.add(declaration.identifier.id);
}
for (const reassignment of scopeBlock.scope.reassignments) {
for (const reassignment of scope.reassignments) {
state.add(reassignment.id);
}
}