visitBlock() — react Function Reference
Architecture documentation for the visitBlock() function in MergeReactiveScopesThatInvalidateTogether.ts from the react codebase.
Entity Profile
Dependency Diagram
graph TD 11690004_c468_3b6b_f07f_36a6501f870a["visitBlock()"] ae117d0c_24d0_3002_1a6e_1e952a421d6e["Transform"] 11690004_c468_3b6b_f07f_36a6501f870a -->|defined in| ae117d0c_24d0_3002_1a6e_1e952a421d6e 108b8884_5432_e93d_5f46_a6634348d340["visitBlock()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| 108b8884_5432_e93d_5f46_a6634348d340 2ac731a7_1748_e943_7a74_4b9c344e4398["log()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| 2ac731a7_1748_e943_7a74_4b9c344e4398 10043bf1_f7ee_9ed9_307a_fe3edfd02b09["eachInstructionLValue()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| 10043bf1_f7ee_9ed9_307a_fe3edfd02b09 f767b6e4_1078_08b0_bc4b_f27f690658e6["canMergeScopes()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| f767b6e4_1078_08b0_bc4b_f27f690658e6 34751151_352b_2ab2_756a_e87e6700e5d1["areLValuesLastUsedByScope()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| 34751151_352b_2ab2_756a_e87e6700e5d1 96ea77cd_c72d_e8a8_1897_f9e11e062fbe["updateScopeDeclarations()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| 96ea77cd_c72d_e8a8_1897_f9e11e062fbe 432e8f07_8888_739b_b310_8ed9622fdd73["scopeIsEligibleForMerging()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| 432e8f07_8888_739b_b310_8ed9622fdd73 d7fde76c_4fd9_feb3_299b_798689f05bc6["assertExhaustive()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| d7fde76c_4fd9_feb3_299b_798689f05bc6 694a6a07_b3ca_4ab4_beba_18f4053a49f2["printReactiveScopeSummary()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| 694a6a07_b3ca_4ab4_beba_18f4053a49f2 c6838a07_559a_1310_1c4f_e78266267fb1["traverseBlock()"] 11690004_c468_3b6b_f07f_36a6501f870a -->|calls| c6838a07_559a_1310_1c4f_e78266267fb1 style 11690004_c468_3b6b_f07f_36a6501f870a fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts lines 145–398
override visitBlock(
block: ReactiveBlock,
state: ReactiveScopeDependencies | null,
): void {
// Pass 1: visit nested blocks to potentially merge their scopes
this.traverseBlock(block, state);
// Pass 2: identify scopes for merging
type MergedScope = {
block: ReactiveScopeBlock;
from: number;
to: number;
lvalues: Set<DeclarationId>;
};
let current: MergedScope | null = null;
const merged: Array<MergedScope> = [];
function reset(): void {
CompilerError.invariant(current !== null, {
reason:
'MergeConsecutiveScopes: expected current scope to be non-null if reset()',
loc: GeneratedSource,
});
if (current.to > current.from + 1) {
merged.push(current);
}
current = null;
}
for (let i = 0; i < block.length; i++) {
const instr = block[i]!;
switch (instr.kind) {
case 'terminal': {
// For now we don't merge across terminals
if (current !== null) {
log(
`Reset scope @${current.block.scope.id} from terminal [${instr.terminal.id}]`,
);
reset();
}
break;
}
case 'pruned-scope': {
// For now we don't merge across pruned scopes
if (current !== null) {
log(
`Reset scope @${current.block.scope.id} from pruned scope @${instr.scope.id}`,
);
reset();
}
break;
}
case 'instruction': {
switch (instr.instruction.value.kind) {
case 'BinaryExpression':
case 'ComputedLoad':
case 'JSXText':
case 'LoadGlobal':
case 'LoadLocal':
case 'Primitive':
case 'PropertyLoad':
case 'TemplateLiteral':
case 'UnaryExpression': {
/*
* We can merge two scopes if there are intervening instructions, but:
* - Only if the instructions are simple and it's okay to make them
* execute conditionally (hence allowing a conservative subset of value kinds)
* - The values produced are used at or before the next scope. If they are used
* later and we move them into the scope, then they wouldn't be accessible to
* subsequent code wo expanding the set of declarations, which we want to avoid
*/
if (current !== null && instr.instruction.lvalue !== null) {
current.lvalues.add(
instr.instruction.lvalue.identifier.declarationId,
);
if (instr.instruction.value.kind === 'LoadLocal') {
this.temporaries.set(
instr.instruction.lvalue.identifier.declarationId,
instr.instruction.value.place.identifier.declarationId,
);
}
}
break;
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does visitBlock() do?
visitBlock() is a function in the react codebase, defined in compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts.
Where is visitBlock() defined?
visitBlock() is defined in compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts at line 145.
What does visitBlock() call?
visitBlock() calls 10 function(s): areLValuesLastUsedByScope, assertExhaustive, canMergeScopes, eachInstructionLValue, log, printReactiveScopeSummary, scopeIsEligibleForMerging, traverseBlock, and 2 more.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free