ControlDominators.ts — react Source File
Architecture documentation for ControlDominators.ts, a typescript file in the react codebase. 3 imports, 2 dependents.
Entity Profile
Dependency Diagram
graph LR 5d62162e_5fa5_1488_29bf_5150b4be53a0["ControlDominators.ts"] 0423f759_97e0_9101_4634_ed555abc5ca9["index.ts"] 5d62162e_5fa5_1488_29bf_5150b4be53a0 --> 0423f759_97e0_9101_4634_ed555abc5ca9 b02a9daf_aca4_b66a_9b9b_0b739a8ca4aa["Dominator.ts"] 5d62162e_5fa5_1488_29bf_5150b4be53a0 --> b02a9daf_aca4_b66a_9b9b_0b739a8ca4aa 0732b54e_6e75_2208_9742_addaecfa3581["PostDominator"] 5d62162e_5fa5_1488_29bf_5150b4be53a0 --> 0732b54e_6e75_2208_9742_addaecfa3581 725143dd_a713_5e8e_fdf0_9c99de3b528f["InferReactivePlaces.ts"] 725143dd_a713_5e8e_fdf0_9c99de3b528f --> 5d62162e_5fa5_1488_29bf_5150b4be53a0 71d73648_b3a1_c2f2_a010_106a2a2c80f6["ValidateNoSetStateInEffects.ts"] 71d73648_b3a1_c2f2_a010_106a2a2c80f6 --> 5d62162e_5fa5_1488_29bf_5150b4be53a0 style 5d62162e_5fa5_1488_29bf_5150b4be53a0 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 {BlockId, computePostDominatorTree, HIRFunction, Place} from '../HIR';
import {PostDominator} from '../HIR/Dominator';
export type ControlDominators = (id: BlockId) => boolean;
/**
* Returns an object that lazily calculates whether particular blocks are controlled
* by values of interest. Which values matter are up to the caller.
*/
export function createControlDominators(
fn: HIRFunction,
isControlVariable: (place: Place) => boolean,
): ControlDominators {
const postDominators = computePostDominatorTree(fn, {
includeThrowsAsExitNode: false,
});
const postDominatorFrontierCache = new Map<BlockId, Set<BlockId>>();
function isControlledBlock(id: BlockId): boolean {
let controlBlocks = postDominatorFrontierCache.get(id);
if (controlBlocks === undefined) {
controlBlocks = postDominatorFrontier(fn, postDominators, id);
postDominatorFrontierCache.set(id, controlBlocks);
}
for (const blockId of controlBlocks) {
const controlBlock = fn.body.blocks.get(blockId)!;
switch (controlBlock.terminal.kind) {
case 'if':
case 'branch': {
if (isControlVariable(controlBlock.terminal.test)) {
return true;
}
break;
}
case 'switch': {
if (isControlVariable(controlBlock.terminal.test)) {
return true;
}
for (const case_ of controlBlock.terminal.cases) {
if (case_.test !== null && isControlVariable(case_.test)) {
return true;
}
}
break;
}
}
}
return false;
}
return isControlledBlock;
}
/*
* Computes the post-dominator frontier of @param block. These are immediate successors of nodes that
* post-dominate @param targetId and from which execution may not reach @param block. Intuitively, these
* are the earliest blocks from which execution branches such that it may or may not reach the target block.
*/
function postDominatorFrontier(
fn: HIRFunction,
postDominators: PostDominator<BlockId>,
targetId: BlockId,
): Set<BlockId> {
const visited = new Set<BlockId>();
const frontier = new Set<BlockId>();
const targetPostDominators = postDominatorsOf(fn, postDominators, targetId);
for (const blockId of [...targetPostDominators, targetId]) {
if (visited.has(blockId)) {
continue;
}
visited.add(blockId);
const block = fn.body.blocks.get(blockId)!;
for (const pred of block.preds) {
if (!targetPostDominators.has(pred)) {
// The predecessor does not always reach this block, we found an item on the frontier!
frontier.add(pred);
}
}
}
return frontier;
}
function postDominatorsOf(
fn: HIRFunction,
postDominators: PostDominator<BlockId>,
targetId: BlockId,
): Set<BlockId> {
const result = new Set<BlockId>();
const visited = new Set<BlockId>();
const queue = [targetId];
while (queue.length) {
const currentId = queue.shift()!;
if (visited.has(currentId)) {
continue;
}
visited.add(currentId);
const current = fn.body.blocks.get(currentId)!;
for (const pred of current.preds) {
const predPostDominator = postDominators.get(pred) ?? pred;
if (predPostDominator === targetId || result.has(predPostDominator)) {
result.add(pred);
}
queue.push(pred);
}
}
return result;
}
Domain
Subdomains
Types
Dependencies
Imported By
Source
Frequently Asked Questions
What does ControlDominators.ts do?
ControlDominators.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 ControlDominators.ts?
ControlDominators.ts defines 4 function(s): createControlDominators, id, postDominatorFrontier, postDominatorsOf.
What does ControlDominators.ts depend on?
ControlDominators.ts imports 3 module(s): Dominator.ts, PostDominator, index.ts.
What files import ControlDominators.ts?
ControlDominators.ts is imported by 2 file(s): InferReactivePlaces.ts, ValidateNoSetStateInEffects.ts.
Where is ControlDominators.ts in the architecture?
ControlDominators.ts is located at compiler/packages/babel-plugin-react-compiler/src/Inference/ControlDominators.ts (domain: BabelCompiler, subdomain: Validation, directory: compiler/packages/babel-plugin-react-compiler/src/Inference).
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free