Skip to content

⬅️ Back to Table of Contents

📄 ClassVisitor

📊 Analysis Summary

Metric Count
🔧 Functions 19
🧱 Classes 1
📦 Imports 7

📚 Table of Contents

🛠️ File Location:

📂 packages/scope-manager/src/referencer/ClassVisitor.ts

📦 Imports

Name Source
TSESTree @typescript-eslint/types
AST_NODE_TYPES @typescript-eslint/types
Referencer ./Referencer
ClassNameDefinition ../definition
ParameterDefinition ../definition
TypeVisitor ./TypeVisitor
Visitor ./Visitor

Functions

ClassVisitor.visit(referencer: Referencer, node: TSESTree.ClassDeclaration | TSESTree.Cl…): void

Parameters:

  • referencer Referencer
  • node TSESTree.ClassDeclaration | TSESTree.ClassExpression

Returns: void

Calls:

  • classVisitor.visitClass
Code
static visit(
    referencer: Referencer,
    node: TSESTree.ClassDeclaration | TSESTree.ClassExpression,
  ): void {
    const classVisitor = new ClassVisitor(referencer);
    classVisitor.visitClass(node);
  }

ClassVisitor.visitClass(node: TSESTree.ClassDeclaration | TSESTree.Cl…): void

Parameters:

  • node TSESTree.ClassDeclaration | TSESTree.ClassExpression

Returns: void

Calls:

  • this.#referencer .currentScope() .defineIdentifier
  • node.decorators.forEach
  • this.#referencer.visit
  • this.#referencer.scopeManager.nestClassScope
  • this.visitType
  • node.implements.forEach
  • this.visit
  • this.#referencer.close

Internal Comments:

// define the class name again inside the new scope (x7)
// references to the class should not resolve directly to the parent class (x7)
// visit the type param declarations (x4)
// then the usages (x4)

Code
protected visitClass(
    node: TSESTree.ClassDeclaration | TSESTree.ClassExpression,
  ): void {
    if (node.type === AST_NODE_TYPES.ClassDeclaration && node.id) {
      this.#referencer
        .currentScope()
        .defineIdentifier(node.id, new ClassNameDefinition(node.id, node));
    }

    node.decorators.forEach(d => this.#referencer.visit(d));

    this.#referencer.scopeManager.nestClassScope(node);

    if (node.id) {
      // define the class name again inside the new scope
      // references to the class should not resolve directly to the parent class
      this.#referencer
        .currentScope()
        .defineIdentifier(node.id, new ClassNameDefinition(node.id, node));
    }

    this.#referencer.visit(node.superClass);

    // visit the type param declarations
    this.visitType(node.typeParameters);
    // then the usages
    this.visitType(node.superTypeArguments);
    node.implements.forEach(imp => this.visitType(imp));

    this.visit(node.body);

    this.#referencer.close(node);
  }

ClassVisitor.visitFunctionParameterTypeAnnotation(node: TSESTree.Parameter): void

Parameters:

  • node TSESTree.Parameter

Returns: void

Calls:

  • this.visitType
  • this.visitFunctionParameterTypeAnnotation
Code
protected visitFunctionParameterTypeAnnotation(
    node: TSESTree.Parameter,
  ): void {
    switch (node.type) {
      case AST_NODE_TYPES.AssignmentPattern:
        this.visitType(node.left.typeAnnotation);
        break;
      case AST_NODE_TYPES.TSParameterProperty:
        this.visitFunctionParameterTypeAnnotation(node.parameter);
        break;
      default:
        this.visitType(node.typeAnnotation);
    }
  }

ClassVisitor.visitMethod(node: TSESTree.MethodDefinition): void

Parameters:

  • node TSESTree.MethodDefinition

Returns: void

Calls:

  • this.#referencer.visit
  • this.visitMethodFunction
  • node.decorators.forEach
Code
protected visitMethod(node: TSESTree.MethodDefinition): void {
    if (node.computed) {
      this.#referencer.visit(node.key);
    }

    if (node.value.type === AST_NODE_TYPES.FunctionExpression) {
      this.visitMethodFunction(node.value);
    } else {
      this.#referencer.visit(node.value);
    }

    node.decorators.forEach(d => this.#referencer.visit(d));
  }

ClassVisitor.visitMethodFunction(node: TSESTree.FunctionExpression): void

Parameters:

  • node TSESTree.FunctionExpression

Returns: void

Calls:

  • this.#referencer.scopeManager.nestFunctionExpressionNameScope
  • node.params.forEach
  • param.decorators.forEach
  • this.visit
  • this.#referencer.scopeManager.nestFunctionScope
  • this.visitPattern
  • this.#referencer .currentScope() .defineIdentifier
  • this.#referencer.referencingDefaultValue
  • this.visitFunctionParameterTypeAnnotation
  • this.visitType
  • this.#referencer.visitChildren
  • this.#referencer.close

Internal Comments:

// FunctionExpression with name creates its special scope; (x6)
// FunctionExpressionNameScope. (x6)
// Consider this function is in the MethodDefinition. (x6)
// Process parameter declarations.

Code
protected visitMethodFunction(node: TSESTree.FunctionExpression): void {
    if (node.id) {
      // FunctionExpression with name creates its special scope;
      // FunctionExpressionNameScope.
      this.#referencer.scopeManager.nestFunctionExpressionNameScope(node);
    }

    node.params.forEach(param => {
      param.decorators.forEach(d => this.visit(d));
    });

    // Consider this function is in the MethodDefinition.
    this.#referencer.scopeManager.nestFunctionScope(node, true);

    // Process parameter declarations.
    for (const param of node.params) {
      this.visitPattern(
        param,
        (pattern, info) => {
          this.#referencer
            .currentScope()
            .defineIdentifier(
              pattern,
              new ParameterDefinition(pattern, node, info.rest),
            );

          this.#referencer.referencingDefaultValue(
            pattern,
            info.assignments,
            null,
            true,
          );
        },
        { processRightHandNodes: true },
      );
      this.visitFunctionParameterTypeAnnotation(param);
    }

    this.visitType(node.returnType);
    this.visitType(node.typeParameters);

    this.#referencer.visitChildren(node.body);
    this.#referencer.close(node);
  }

ClassVisitor.visitPropertyBase(node: | TSESTree.AccessorProperty | TSESTree.…): void

Parameters:

  • node | TSESTree.AccessorProperty | TSESTree.PropertyDefinition | TSESTree.TSAbstractAccessorProperty | TSESTree.TSAbstractMethodDefinition | TSESTree.TSAbstractPropertyDefinition

Returns: void

Calls:

  • this.#referencer.visit
  • this.#referencer.scopeManager.nestClassFieldInitializerScope
  • this.#referencer.close
  • node.decorators.forEach
Code
protected visitPropertyBase(
    node:
      | TSESTree.AccessorProperty
      | TSESTree.PropertyDefinition
      | TSESTree.TSAbstractAccessorProperty
      | TSESTree.TSAbstractMethodDefinition
      | TSESTree.TSAbstractPropertyDefinition,
  ): void {
    if (node.computed) {
      this.#referencer.visit(node.key);
    }

    if (node.value) {
      if (
        node.type === AST_NODE_TYPES.PropertyDefinition ||
        node.type === AST_NODE_TYPES.AccessorProperty
      ) {
        this.#referencer.scopeManager.nestClassFieldInitializerScope(
          node.value,
        );
      }

      this.#referencer.visit(node.value);

      if (
        node.type === AST_NODE_TYPES.PropertyDefinition ||
        node.type === AST_NODE_TYPES.AccessorProperty
      ) {
        this.#referencer.close(node.value);
      }
    }

    node.decorators.forEach(d => this.#referencer.visit(d));
  }

ClassVisitor.visitPropertyDefinition(node: | TSESTree.AccessorProperty | TSESTree.…): void

Parameters:

  • node | TSESTree.AccessorProperty | TSESTree.PropertyDefinition | TSESTree.TSAbstractAccessorProperty | TSESTree.TSAbstractPropertyDefinition

Returns: void

Calls:

  • this.visitPropertyBase
  • this.visitType

Internal Comments:

/**
     * class A {
     *   @meta     // <--- check this
     *   foo: Type;
     * }
     */ (x4)

Code
protected visitPropertyDefinition(
    node:
      | TSESTree.AccessorProperty
      | TSESTree.PropertyDefinition
      | TSESTree.TSAbstractAccessorProperty
      | TSESTree.TSAbstractPropertyDefinition,
  ): void {
    this.visitPropertyBase(node);
    /**
     * class A {
     *   @meta     // <--- check this
     *   foo: Type;
     * }
     */
    this.visitType(node.typeAnnotation);
  }

ClassVisitor.visitType(node: TSESTree.Node | null | undefined): void

Parameters:

  • node TSESTree.Node | null | undefined

Returns: void

Calls:

  • TypeVisitor.visit
Code
protected visitType(node: TSESTree.Node | null | undefined): void {
    if (!node) {
      return;
    }
    TypeVisitor.visit(this.#referencer, node);
  }

ClassVisitor.AccessorProperty(node: TSESTree.AccessorProperty): void

Parameters:

  • node TSESTree.AccessorProperty

Returns: void

Calls:

  • this.visitPropertyDefinition
Code
protected AccessorProperty(node: TSESTree.AccessorProperty): void {
    this.visitPropertyDefinition(node);
  }

ClassVisitor.ClassBody(node: TSESTree.ClassBody): void

Parameters:

  • node TSESTree.ClassBody

Returns: void

Calls:

  • this.visitChildren

Internal Comments:

// this is here on purpose so that this visitor explicitly declares visitors (x4)
// for all nodes it cares about (see the instance visit method above) (x4)

Code
protected ClassBody(node: TSESTree.ClassBody): void {
    // this is here on purpose so that this visitor explicitly declares visitors
    // for all nodes it cares about (see the instance visit method above)
    this.visitChildren(node);
  }

ClassVisitor.Identifier(node: TSESTree.Identifier): void

Parameters:

  • node TSESTree.Identifier

Returns: void

Calls:

  • this.#referencer.visit
Code
protected Identifier(node: TSESTree.Identifier): void {
    this.#referencer.visit(node);
  }

ClassVisitor.MethodDefinition(node: TSESTree.MethodDefinition): void

Parameters:

  • node TSESTree.MethodDefinition

Returns: void

Calls:

  • this.visitMethod
Code
protected MethodDefinition(node: TSESTree.MethodDefinition): void {
    this.visitMethod(node);
  }

ClassVisitor.PrivateIdentifier(): void

Returns: void

Code
protected PrivateIdentifier(): void {
    // intentionally skip
  }

ClassVisitor.PropertyDefinition(node: TSESTree.PropertyDefinition): void

Parameters:

  • node TSESTree.PropertyDefinition

Returns: void

Calls:

  • this.visitPropertyDefinition
Code
protected PropertyDefinition(node: TSESTree.PropertyDefinition): void {
    this.visitPropertyDefinition(node);
  }

ClassVisitor.StaticBlock(node: TSESTree.StaticBlock): void

Parameters:

  • node TSESTree.StaticBlock

Returns: void

Calls:

  • this.#referencer.scopeManager.nestClassStaticBlockScope
  • node.body.forEach
  • this.visit
  • this.#referencer.close
Code
protected StaticBlock(node: TSESTree.StaticBlock): void {
    this.#referencer.scopeManager.nestClassStaticBlockScope(node);

    node.body.forEach(b => this.visit(b));

    this.#referencer.close(node);
  }

ClassVisitor.TSAbstractAccessorProperty(node: TSESTree.TSAbstractAccessorProperty): void

Parameters:

  • node TSESTree.TSAbstractAccessorProperty

Returns: void

Calls:

  • this.visitPropertyDefinition
Code
protected TSAbstractAccessorProperty(
    node: TSESTree.TSAbstractAccessorProperty,
  ): void {
    this.visitPropertyDefinition(node);
  }

ClassVisitor.TSAbstractMethodDefinition(node: TSESTree.TSAbstractMethodDefinition): void

Parameters:

  • node TSESTree.TSAbstractMethodDefinition

Returns: void

Calls:

  • this.visitPropertyBase
Code
protected TSAbstractMethodDefinition(
    node: TSESTree.TSAbstractMethodDefinition,
  ): void {
    this.visitPropertyBase(node);
  }

ClassVisitor.TSAbstractPropertyDefinition(node: TSESTree.TSAbstractPropertyDefinition): void

Parameters:

  • node TSESTree.TSAbstractPropertyDefinition

Returns: void

Calls:

  • this.visitPropertyDefinition
Code
protected TSAbstractPropertyDefinition(
    node: TSESTree.TSAbstractPropertyDefinition,
  ): void {
    this.visitPropertyDefinition(node);
  }

ClassVisitor.TSIndexSignature(node: TSESTree.TSIndexSignature): void

Parameters:

  • node TSESTree.TSIndexSignature

Returns: void

Calls:

  • this.visitType
Code
protected TSIndexSignature(node: TSESTree.TSIndexSignature): void {
    this.visitType(node);
  }

Classes

ClassVisitor

Extends: Visitor

Methods (20) — full entries under Functions

Method Signature
visit (referencer: Referencer, node: TSESTree.ClassDeclaration \| TSESTree.ClassExpression): void
visit (node: TSESTree.Node \| null \| undefined): void
visitClass (node: TSESTree.ClassDeclaration \| TSESTree.ClassExpression): void
visitFunctionParameterTypeAnnotation (node: TSESTree.Parameter): void
visitMethod (node: TSESTree.MethodDefinition): void
visitMethodFunction (node: TSESTree.FunctionExpression): void
visitPropertyBase (node: \| TSESTree.AccessorProperty \| TSESTree.PropertyDefinition \| TSESTree.TSAbstractAccessor...
visitPropertyDefinition (node: \| TSESTree.AccessorProperty \| TSESTree.PropertyDefinition \| TSESTree.TSAbstractAccessor...
visitType (node: TSESTree.Node \| null \| undefined): void
AccessorProperty (node: TSESTree.AccessorProperty): void
ClassBody (node: TSESTree.ClassBody): void
Identifier (node: TSESTree.Identifier): void
MethodDefinition (node: TSESTree.MethodDefinition): void
PrivateIdentifier (): void
PropertyDefinition (node: TSESTree.PropertyDefinition): void
StaticBlock (node: TSESTree.StaticBlock): void
TSAbstractAccessorProperty (node: TSESTree.TSAbstractAccessorProperty): void
TSAbstractMethodDefinition (node: TSESTree.TSAbstractMethodDefinition): void
TSAbstractPropertyDefinition (node: TSESTree.TSAbstractPropertyDefinition): void
TSIndexSignature (node: TSESTree.TSIndexSignature): void

Generated by Syntax Scribe