Home / Function/ traverseOptionalBlock() — react Function Reference

traverseOptionalBlock() — react Function Reference

Architecture documentation for the traverseOptionalBlock() function in CollectOptionalChainDependencies.ts from the react codebase.

Entity Profile

Dependency Diagram

graph TD
  8e720f44_2b97_3d0b_5bc7_8a340dc6f442["traverseOptionalBlock()"]
  fd3023fa_cdd5_e8f0_669a_c459a0f89746["CollectOptionalChainDependencies.ts"]
  8e720f44_2b97_3d0b_5bc7_8a340dc6f442 -->|defined in| fd3023fa_cdd5_e8f0_669a_c459a0f89746
  9f4cf94f_95fc_c715_8c19_d3886a1e066d["traverseFunction()"]
  9f4cf94f_95fc_c715_8c19_d3886a1e066d -->|calls| 8e720f44_2b97_3d0b_5bc7_8a340dc6f442
  7cd776c7_0283_e0eb_af1b_5474c371bd16["assertNonNull()"]
  8e720f44_2b97_3d0b_5bc7_8a340dc6f442 -->|calls| 7cd776c7_0283_e0eb_af1b_5474c371bd16
  7768e811_2923_bb27_1697_f9458cbb2d02["matchOptionalTestBlock()"]
  8e720f44_2b97_3d0b_5bc7_8a340dc6f442 -->|calls| 7768e811_2923_bb27_1697_f9458cbb2d02
  style 8e720f44_2b97_3d0b_5bc7_8a340dc6f442 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

compiler/packages/babel-plugin-react-compiler/src/HIR/CollectOptionalChainDependencies.ts lines 238–412

function traverseOptionalBlock(
  optional: TBasicBlock<OptionalTerminal>,
  context: OptionalTraversalContext,
  outerAlternate: BlockId | null,
): IdentifierId | null {
  context.seenOptionals.add(optional.id);
  const maybeTest = context.blocks.get(optional.terminal.test)!;
  let test: BranchTerminal;
  let baseObject: ReactiveScopeDependency;
  if (maybeTest.terminal.kind === 'branch') {
    CompilerError.invariant(optional.terminal.optional, {
      reason: '[OptionalChainDeps] Expect base case to be always optional',
      loc: optional.terminal.loc,
    });
    /**
     * Optional base expressions are currently within value blocks which cannot
     * be interrupted by scope boundaries. As such, the only dependencies we can
     * hoist out of optional chains are property load chains with no intervening
     * instructions.
     *
     * Ideally, we would be able to flatten base instructions out of optional
     * blocks, but this would require changes to HIR.
     *
     * For now, only match base expressions that are straightforward
     * PropertyLoad chains
     */
    if (
      maybeTest.instructions.length === 0 ||
      maybeTest.instructions[0].value.kind !== 'LoadLocal'
    ) {
      return null;
    }
    const path: Array<DependencyPathEntry> = [];
    for (let i = 1; i < maybeTest.instructions.length; i++) {
      const instrVal = maybeTest.instructions[i].value;
      const prevInstr = maybeTest.instructions[i - 1];
      if (
        instrVal.kind === 'PropertyLoad' &&
        instrVal.object.identifier.id === prevInstr.lvalue.identifier.id
      ) {
        path.push({property: instrVal.property, optional: false});
      } else {
        return null;
      }
    }
    CompilerError.invariant(
      maybeTest.terminal.test.identifier.id ===
        maybeTest.instructions.at(-1)!.lvalue.identifier.id,
      {
        reason: '[OptionalChainDeps] Unexpected test expression',
        loc: maybeTest.terminal.loc,
      },
    );
    baseObject = {
      identifier: maybeTest.instructions[0].value.place.identifier,
      reactive: maybeTest.instructions[0].value.place.reactive,
      path,
    };
    test = maybeTest.terminal;
  } else if (maybeTest.terminal.kind === 'optional') {
    /**
     * This is either
     * - <inner_optional>?.property (optional=true)
     * - <inner_optional>.property  (optional=false)
     * - <inner_optional> <other operation>
     * - a optional base block with a separate nested optional-chain (e.g. a(c?.d)?.d)
     */
    const testBlock = context.blocks.get(maybeTest.terminal.fallthrough)!;
    if (testBlock!.terminal.kind !== 'branch') {
      /**
       * Fallthrough of the inner optional should be a block with no
       * instructions, terminating with Test($<temporary written to from
       * StoreLocal>)
       */
      CompilerError.throwTodo({
        reason: `Unexpected terminal kind \`${testBlock.terminal.kind}\` for optional fallthrough block`,
        loc: maybeTest.terminal.loc,
      });
    }
    /**
     * Recurse into inner optional blocks to collect inner optional-chain

Subdomains

Called By

Frequently Asked Questions

What does traverseOptionalBlock() do?
traverseOptionalBlock() is a function in the react codebase, defined in compiler/packages/babel-plugin-react-compiler/src/HIR/CollectOptionalChainDependencies.ts.
Where is traverseOptionalBlock() defined?
traverseOptionalBlock() is defined in compiler/packages/babel-plugin-react-compiler/src/HIR/CollectOptionalChainDependencies.ts at line 238.
What does traverseOptionalBlock() call?
traverseOptionalBlock() calls 2 function(s): assertNonNull, matchOptionalTestBlock.
What calls traverseOptionalBlock()?
traverseOptionalBlock() is called by 1 function(s): traverseFunction.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free