Home / Class/ Visitor Class — react Architecture

Visitor Class — react Architecture

Architecture documentation for the Visitor class in ValidateMemoizedEffectDependencies.ts from the react codebase.

Entity Profile

Dependency Diagram

graph TD
  5cd10448_f0eb_0786_b718_13989afbbde5["Visitor"]
  4f3dd743_0a09_5d8d_bf24_d727c39bc26f["ValidateMemoizedEffectDependencies.ts"]
  5cd10448_f0eb_0786_b718_13989afbbde5 -->|defined in| 4f3dd743_0a09_5d8d_bf24_d727c39bc26f
  8e7603e1_e406_67bf_e050_540df344e5ff["visitScope()"]
  5cd10448_f0eb_0786_b718_13989afbbde5 -->|method| 8e7603e1_e406_67bf_e050_540df344e5ff
  b0098168_1428_1a79_dc10_829e8e1a5595["visitInstruction()"]
  5cd10448_f0eb_0786_b718_13989afbbde5 -->|method| b0098168_1428_1a79_dc10_829e8e1a5595

Relationship Graph

Source Code

compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateMemoizedEffectDependencies.ts lines 60–122

class Visitor extends ReactiveFunctionVisitor<CompilerError> {
  scopes: Set<ScopeId> = new Set();

  override visitScope(
    scopeBlock: ReactiveScopeBlock,
    state: CompilerError,
  ): void {
    this.traverseScope(scopeBlock, state);

    /*
     * Record scopes that exist in the AST so we can later check to see if
     * effect dependencies which should be memoized (have a scope assigned)
     * actually are memoized (that scope exists).
     * However, we only record scopes if *their* dependencies are also
     * memoized, allowing a transitive memoization check.
     */
    let areDependenciesMemoized = true;
    for (const dep of scopeBlock.scope.dependencies) {
      if (isUnmemoized(dep.identifier, this.scopes)) {
        areDependenciesMemoized = false;
        break;
      }
    }
    if (areDependenciesMemoized) {
      this.scopes.add(scopeBlock.scope.id);
      for (const id of scopeBlock.scope.merged) {
        this.scopes.add(id);
      }
    }
  }

  override visitInstruction(
    instruction: ReactiveInstruction,
    state: CompilerError,
  ): void {
    this.traverseInstruction(instruction, state);
    if (
      instruction.value.kind === 'CallExpression' &&
      isEffectHook(instruction.value.callee.identifier) &&
      instruction.value.args.length >= 2
    ) {
      const deps = instruction.value.args[1]!;
      if (
        deps.kind === 'Identifier' &&
        /*
         * TODO: isMutable is not safe to call here as it relies on identifier mutableRange which is no longer valid at this point
         * in the pipeline
         */
        (isMutable(instruction as Instruction, deps) ||
          isUnmemoized(deps.identifier, this.scopes))
      ) {
        state.push({
          category: ErrorCategory.EffectDependencies,
          reason:
            'React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior',
          description: null,
          loc: typeof instruction.loc !== 'symbol' ? instruction.loc : null,
          suggestions: null,
        });
      }
    }
  }
}

Domain

Frequently Asked Questions

What is the Visitor class?
Visitor is a class in the react codebase, defined in compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateMemoizedEffectDependencies.ts.
Where is Visitor defined?
Visitor is defined in compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateMemoizedEffectDependencies.ts at line 60.

Analyze Your Own Codebase

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

Try Supermodel Free