Home / Function/ visitValueForMemoization() — react Function Reference

visitValueForMemoization() — react Function Reference

Architecture documentation for the visitValueForMemoization() function in PruneNonEscapingScopes.ts from the react codebase.

Entity Profile

Dependency Diagram

graph TD
  97a5722d_5f85_030f_127a_0ee70f10e274["visitValueForMemoization()"]
  714af45f_cbe2_027b_49c5_27e47069c22c["CollectDependenciesVisitor"]
  97a5722d_5f85_030f_127a_0ee70f10e274 -->|defined in| 714af45f_cbe2_027b_49c5_27e47069c22c
  5f0939bb_76eb_1279_d295_dacefad72c8a["computeMemoizationInputs()"]
  5f0939bb_76eb_1279_d295_dacefad72c8a -->|calls| 97a5722d_5f85_030f_127a_0ee70f10e274
  3e0ecaac_7842_5d1d_db02_c18fdd69c93b["visitInstruction()"]
  3e0ecaac_7842_5d1d_db02_c18fdd69c93b -->|calls| 97a5722d_5f85_030f_127a_0ee70f10e274
  5f0939bb_76eb_1279_d295_dacefad72c8a["computeMemoizationInputs()"]
  97a5722d_5f85_030f_127a_0ee70f10e274 -->|calls| 5f0939bb_76eb_1279_d295_dacefad72c8a
  5efb04f8_fe7e_23f5_ada1_07f7e110af62["visitOperand()"]
  97a5722d_5f85_030f_127a_0ee70f10e274 -->|calls| 5efb04f8_fe7e_23f5_ada1_07f7e110af62
  458cb99d_78d6_7991_ebe2_061dd4362709["joinAliases()"]
  97a5722d_5f85_030f_127a_0ee70f10e274 -->|calls| 458cb99d_78d6_7991_ebe2_061dd4362709
  9cbd2355_05cd_5bbd_253f_7aeb4f947484["getHookKind()"]
  97a5722d_5f85_030f_127a_0ee70f10e274 -->|calls| 9cbd2355_05cd_5bbd_253f_7aeb4f947484
  d2c89465_144e_76da_505e_4a2de182f6f4["getFunctionCallSignature()"]
  97a5722d_5f85_030f_127a_0ee70f10e274 -->|calls| d2c89465_144e_76da_505e_4a2de182f6f4
  style 97a5722d_5f85_030f_127a_0ee70f10e274 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts lines 860–939

  visitValueForMemoization(
    id: InstructionId,
    value: ReactiveValue,
    lvalue: Place | null,
  ): void {
    const state = this.state;
    // Determe the level of memoization for this value and the lvalues/rvalues
    const aliasing = this.computeMemoizationInputs(value, lvalue);

    // Associate all the rvalues with the instruction's scope if it has one
    for (const operand of aliasing.rvalues) {
      const operandId =
        state.definitions.get(operand.identifier.declarationId) ??
        operand.identifier.declarationId;
      state.visitOperand(id, operand, operandId);
    }

    // Add the operands as dependencies of all lvalues.
    for (const {place: lvalue, level} of aliasing.lvalues) {
      const lvalueId =
        state.definitions.get(lvalue.identifier.declarationId) ??
        lvalue.identifier.declarationId;
      let node = state.identifiers.get(lvalueId);
      if (node === undefined) {
        node = {
          level: MemoizationLevel.Never,
          memoized: false,
          dependencies: new Set(),
          scopes: new Set(),
          seen: false,
        };
        state.identifiers.set(lvalueId, node);
      }
      node.level = joinAliases(node.level, level);
      /*
       * This looks like NxM iterations but in practice all instructions with multiple
       * lvalues have only a single rvalue
       */
      for (const operand of aliasing.rvalues) {
        const operandId =
          state.definitions.get(operand.identifier.declarationId) ??
          operand.identifier.declarationId;
        if (operandId === lvalueId) {
          continue;
        }
        node.dependencies.add(operandId);
      }

      state.visitOperand(id, lvalue, lvalueId);
    }

    if (value.kind === 'LoadLocal' && lvalue !== null) {
      state.definitions.set(
        lvalue.identifier.declarationId,
        value.place.identifier.declarationId,
      );
    } else if (value.kind === 'CallExpression' || value.kind === 'MethodCall') {
      let callee =
        value.kind === 'CallExpression' ? value.callee : value.property;
      if (getHookKind(state.env, callee.identifier) != null) {
        const signature = getFunctionCallSignature(
          this.env,
          callee.identifier.type,
        );
        /*
         * Hook values are assumed to escape by default since they can be inputs
         * to reactive scopes in the hook. However if the hook is annotated as
         * noAlias we know that the arguments cannot escape and don't need to
         * be memoized.
         */
        if (signature && signature.noAlias === true) {
          return;
        }
        for (const operand of value.args) {
          const place = operand.kind === 'Spread' ? operand.place : operand;
          state.escapingValues.add(place.identifier.declarationId);
        }
      }
    }
  }

Domain

Subdomains

Frequently Asked Questions

What does visitValueForMemoization() do?
visitValueForMemoization() is a function in the react codebase, defined in compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts.
Where is visitValueForMemoization() defined?
visitValueForMemoization() is defined in compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts at line 860.
What does visitValueForMemoization() call?
visitValueForMemoization() calls 5 function(s): computeMemoizationInputs, getFunctionCallSignature, getHookKind, joinAliases, visitOperand.
What calls visitValueForMemoization()?
visitValueForMemoization() is called by 2 function(s): computeMemoizationInputs, visitInstruction.

Analyze Your Own Codebase

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

Try Supermodel Free