inferReactivePlaces() — react Function Reference
Architecture documentation for the inferReactivePlaces() function in InferReactivePlaces.ts from the react codebase.
Entity Profile
Dependency Diagram
graph TD fddc4da2_1151_8052_c771_8b67085ebeca["inferReactivePlaces()"] 725143dd_a713_5e8e_fdf0_9c99de3b528f["InferReactivePlaces.ts"] fddc4da2_1151_8052_c771_8b67085ebeca -->|defined in| 725143dd_a713_5e8e_fdf0_9c99de3b528f b474edef_a60d_b132_2ae0_98f6768ec241["findDisjointMutableValues()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| b474edef_a60d_b132_2ae0_98f6768ec241 a9512b67_abe2_2599_90d7_8e0d1c81a618["markReactive()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| a9512b67_abe2_2599_90d7_8e0d1c81a618 1c6dc7ec_72e1_b907_d23f_94b6a80c2a2d["createControlDominators()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| 1c6dc7ec_72e1_b907_d23f_94b6a80c2a2d 35406eee_9521_0419_7a1e_5d1f16da6f89["isReactive()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| 35406eee_9521_0419_7a1e_5d1f16da6f89 0f37c797_b04e_2552_16c2_13b03579eacc["handleInstruction()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| 0f37c797_b04e_2552_16c2_13b03579eacc b2fc2985_a7ba_9865_c2a3_2a7531f27d44["eachInstructionValueOperand()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| b2fc2985_a7ba_9865_c2a3_2a7531f27d44 10043bf1_f7ee_9ed9_307a_fe3edfd02b09["eachInstructionLValue()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| 10043bf1_f7ee_9ed9_307a_fe3edfd02b09 8c11f7cf_78dd_776d_68b9_80dedace987b["isStable()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| 8c11f7cf_78dd_776d_68b9_80dedace987b 11746e9a_2fdf_98bb_bb3c_a63d8b200df2["isMutable()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| 11746e9a_2fdf_98bb_bb3c_a63d8b200df2 d7fde76c_4fd9_feb3_299b_798689f05bc6["assertExhaustive()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| d7fde76c_4fd9_feb3_299b_798689f05bc6 41232a25_deb6_6e83_05a8_ae9f961656f7["eachTerminalOperand()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| 41232a25_deb6_6e83_05a8_ae9f961656f7 e2b6f209_e0ee_d067_5cde_f180db8dbb52["snapshot()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| e2b6f209_e0ee_d067_5cde_f180db8dbb52 ccace1c3_85b7_a05e_c2a5_7eff8b3422ed["eachInstructionOperand()"] fddc4da2_1151_8052_c771_8b67085ebeca -->|calls| ccace1c3_85b7_a05e_c2a5_7eff8b3422ed style fddc4da2_1151_8052_c771_8b67085ebeca fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts lines 205–366
export function inferReactivePlaces(fn: HIRFunction): void {
const reactiveIdentifiers = new ReactivityMap(findDisjointMutableValues(fn));
const stableIdentifierSources = new StableSidemap(fn.env);
for (const param of fn.params) {
const place = param.kind === 'Identifier' ? param : param.place;
reactiveIdentifiers.markReactive(place);
}
const isReactiveControlledBlock = createControlDominators(fn, place =>
reactiveIdentifiers.isReactive(place),
);
do {
for (const [, block] of fn.body.blocks) {
let hasReactiveControl = isReactiveControlledBlock(block.id);
for (const phi of block.phis) {
if (reactiveIdentifiers.isReactive(phi.place)) {
// Already marked reactive on a previous pass
continue;
}
let isPhiReactive = false;
for (const [, operand] of phi.operands) {
if (reactiveIdentifiers.isReactive(operand)) {
isPhiReactive = true;
break;
}
}
if (isPhiReactive) {
reactiveIdentifiers.markReactive(phi.place);
} else {
for (const [pred] of phi.operands) {
if (isReactiveControlledBlock(pred)) {
reactiveIdentifiers.markReactive(phi.place);
break;
}
}
}
}
for (const instruction of block.instructions) {
stableIdentifierSources.handleInstruction(instruction);
const {value} = instruction;
let hasReactiveInput = false;
/*
* NOTE: we want to mark all operands as reactive or not, so we
* avoid short-circuiting here
*/
for (const operand of eachInstructionValueOperand(value)) {
const reactive = reactiveIdentifiers.isReactive(operand);
hasReactiveInput ||= reactive;
}
/**
* Hooks and the 'use' operator are sources of reactivity because
* they can access state (for hooks) or context (for hooks/use).
*
* Technically, `use` could be used to await a non-reactive promise,
* but we are conservative and assume that the value could be reactive.
*/
if (
value.kind === 'CallExpression' &&
(getHookKind(fn.env, value.callee.identifier) != null ||
isUseOperator(value.callee.identifier))
) {
hasReactiveInput = true;
} else if (
value.kind === 'MethodCall' &&
(getHookKind(fn.env, value.property.identifier) != null ||
isUseOperator(value.property.identifier))
) {
hasReactiveInput = true;
}
if (hasReactiveInput) {
for (const lvalue of eachInstructionLValue(instruction)) {
/**
* Note that it's not correct to mark all stable-typed identifiers
* as non-reactive, since ternaries and other value blocks can
* produce reactive identifiers typed as these.
* (e.g. `props.cond ? setState1 : setState2`)
*/
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does inferReactivePlaces() do?
inferReactivePlaces() is a function in the react codebase, defined in compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts.
Where is inferReactivePlaces() defined?
inferReactivePlaces() is defined in compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts at line 205.
What does inferReactivePlaces() call?
inferReactivePlaces() calls 13 function(s): assertExhaustive, createControlDominators, eachInstructionLValue, eachInstructionOperand, eachInstructionValueOperand, eachTerminalOperand, findDisjointMutableValues, handleInstruction, and 5 more.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free