Skip to content

⬅️ Back to Table of Contents

📄 PatternVisitor

📊 Analysis Summary

Metric Count
🔧 Functions 13
🧱 Classes 1
📦 Imports 4
📑 Type Aliases 2

📚 Table of Contents

🛠️ File Location:

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

📦 Imports

Name Source
TSESTree @typescript-eslint/types
AST_NODE_TYPES @typescript-eslint/types
VisitorOptions ./VisitorBase
VisitorBase ./VisitorBase

Functions

PatternVisitor.isPattern(node: TSESTree.Node): node is | TSESTree.ArrayPattern | TSESTree.AssignmentPatter…

Parameters:

  • node TSESTree.Node

Returns: node is | TSESTree.ArrayPattern | TSESTree.AssignmentPattern | TSESTree.Identifier | TSESTree.ObjectPattern | TSESTree.RestElement | TSESTree.SpreadElement

Code
public static isPattern(
    node: TSESTree.Node,
  ): node is
    | TSESTree.ArrayPattern
    | TSESTree.AssignmentPattern
    | TSESTree.Identifier
    | TSESTree.ObjectPattern
    | TSESTree.RestElement
    | TSESTree.SpreadElement {
    const nodeType = node.type;

    return (
      nodeType === AST_NODE_TYPES.Identifier ||
      nodeType === AST_NODE_TYPES.ObjectPattern ||
      nodeType === AST_NODE_TYPES.ArrayPattern ||
      nodeType === AST_NODE_TYPES.SpreadElement ||
      nodeType === AST_NODE_TYPES.RestElement ||
      nodeType === AST_NODE_TYPES.AssignmentPattern
    );
  }

PatternVisitor.ArrayExpression(node: TSESTree.ArrayExpression): void

Parameters:

  • node TSESTree.ArrayExpression

Returns: void

Calls:

  • node.elements.forEach
Code
protected ArrayExpression(node: TSESTree.ArrayExpression): void {
    node.elements.forEach(this.visit, this);
  }

PatternVisitor.ArrayPattern(pattern: TSESTree.ArrayPattern): void

Parameters:

  • pattern TSESTree.ArrayPattern

Returns: void

Calls:

  • this.visit
Code
protected ArrayPattern(pattern: TSESTree.ArrayPattern): void {
    for (const element of pattern.elements) {
      this.visit(element);
    }
  }

PatternVisitor.AssignmentExpression(node: TSESTree.AssignmentExpression): void

Parameters:

  • node TSESTree.AssignmentExpression

Returns: void

Calls:

  • this.#assignments.push
  • this.visit
  • this.rightHandNodes.push
  • this.#assignments.pop
Code
protected AssignmentExpression(node: TSESTree.AssignmentExpression): void {
    this.#assignments.push(node);
    this.visit(node.left);
    this.rightHandNodes.push(node.right);
    this.#assignments.pop();
  }

PatternVisitor.AssignmentPattern(pattern: TSESTree.AssignmentPattern): void

Parameters:

  • pattern TSESTree.AssignmentPattern

Returns: void

Calls:

  • this.#assignments.push
  • this.visit
  • this.rightHandNodes.push
  • this.#assignments.pop
Code
protected AssignmentPattern(pattern: TSESTree.AssignmentPattern): void {
    this.#assignments.push(pattern);
    this.visit(pattern.left);
    this.rightHandNodes.push(pattern.right);
    this.#assignments.pop();
  }

PatternVisitor.CallExpression(node: TSESTree.CallExpression): void

Parameters:

  • node TSESTree.CallExpression

Returns: void

Calls:

  • node.arguments.forEach
  • this.rightHandNodes.push
  • this.visit

Internal Comments:

// arguments are right hand nodes. (x5)

Code
protected CallExpression(node: TSESTree.CallExpression): void {
    // arguments are right hand nodes.
    node.arguments.forEach(a => {
      this.rightHandNodes.push(a);
    });
    this.visit(node.callee);
  }

PatternVisitor.Decorator(): void

Returns: void

Code
protected Decorator(): void {
    // don't visit any decorators when exploring a pattern
  }

PatternVisitor.Identifier(pattern: TSESTree.Identifier): void

Parameters:

  • pattern TSESTree.Identifier

Returns: void

Calls:

  • this.#restElements.at
  • this.#callback
Code
protected Identifier(pattern: TSESTree.Identifier): void {
    const lastRestElement = this.#restElements.at(-1);

    this.#callback(pattern, {
      assignments: this.#assignments,
      rest: lastRestElement?.argument === pattern,
      topLevel: pattern === this.#rootPattern,
    });
  }

PatternVisitor.MemberExpression(node: TSESTree.MemberExpression): void

Parameters:

  • node TSESTree.MemberExpression

Returns: void

Calls:

  • this.rightHandNodes.push

Internal Comments:

// Computed property's key is a right hand node.
// the object is only read, write to its property. (x5)

Code
protected MemberExpression(node: TSESTree.MemberExpression): void {
    // Computed property's key is a right hand node.
    if (node.computed) {
      this.rightHandNodes.push(node.property);
    }

    // the object is only read, write to its property.
    this.rightHandNodes.push(node.object);
  }

PatternVisitor.Property(property: TSESTree.Property): void

Parameters:

  • property TSESTree.Property

Returns: void

Calls:

  • this.rightHandNodes.push
  • this.visit

Internal Comments:

// Computed property's key is a right hand node.
// If it's shorthand, its key is same as its value. (x4)
// If it's shorthand and has its default value, its key is same as its value.left (the value is AssignmentPattern). (x4)
// If it's not shorthand, the name of new variable is its value's. (x4)

Code
protected Property(property: TSESTree.Property): void {
    // Computed property's key is a right hand node.
    if (property.computed) {
      this.rightHandNodes.push(property.key);
    }

    // If it's shorthand, its key is same as its value.
    // If it's shorthand and has its default value, its key is same as its value.left (the value is AssignmentPattern).
    // If it's not shorthand, the name of new variable is its value's.
    this.visit(property.value);
  }

PatternVisitor.RestElement(pattern: TSESTree.RestElement): void

Parameters:

  • pattern TSESTree.RestElement

Returns: void

Calls:

  • this.#restElements.push
  • this.visit
  • this.#restElements.pop
Code
protected RestElement(pattern: TSESTree.RestElement): void {
    this.#restElements.push(pattern);
    this.visit(pattern.argument);
    this.#restElements.pop();
  }

PatternVisitor.SpreadElement(node: TSESTree.SpreadElement): void

Parameters:

  • node TSESTree.SpreadElement

Returns: void

Calls:

  • this.visit
Code
protected SpreadElement(node: TSESTree.SpreadElement): void {
    this.visit(node.argument);
  }

PatternVisitor.TSTypeAnnotation(): void

Returns: void

Code
protected TSTypeAnnotation(): void {
    // we don't want to visit types
  }

Classes

PatternVisitor

Extends: VisitorBase

Class Code
export class PatternVisitor extends VisitorBase {
  readonly #assignments: (
    TSESTree.AssignmentExpression | TSESTree.AssignmentPattern
  )[] = [];
  readonly #callback: PatternVisitorCallback;
  readonly #restElements: TSESTree.RestElement[] = [];
  readonly #rootPattern: TSESTree.Node;

  public readonly rightHandNodes: TSESTree.Node[] = [];

  constructor(
    options: PatternVisitorOptions,
    rootPattern: TSESTree.Node,
    callback: PatternVisitorCallback,
  ) {
    super(options);
    this.#rootPattern = rootPattern;
    this.#callback = callback;
  }

  public static isPattern(
    node: TSESTree.Node,
  ): node is
    | TSESTree.ArrayPattern
    | TSESTree.AssignmentPattern
    | TSESTree.Identifier
    | TSESTree.ObjectPattern
    | TSESTree.RestElement
    | TSESTree.SpreadElement {
    const nodeType = node.type;

    return (
      nodeType === AST_NODE_TYPES.Identifier ||
      nodeType === AST_NODE_TYPES.ObjectPattern ||
      nodeType === AST_NODE_TYPES.ArrayPattern ||
      nodeType === AST_NODE_TYPES.SpreadElement ||
      nodeType === AST_NODE_TYPES.RestElement ||
      nodeType === AST_NODE_TYPES.AssignmentPattern
    );
  }

  protected ArrayExpression(node: TSESTree.ArrayExpression): void {
    node.elements.forEach(this.visit, this);
  }

  protected ArrayPattern(pattern: TSESTree.ArrayPattern): void {
    for (const element of pattern.elements) {
      this.visit(element);
    }
  }

  protected AssignmentExpression(node: TSESTree.AssignmentExpression): void {
    this.#assignments.push(node);
    this.visit(node.left);
    this.rightHandNodes.push(node.right);
    this.#assignments.pop();
  }

  protected AssignmentPattern(pattern: TSESTree.AssignmentPattern): void {
    this.#assignments.push(pattern);
    this.visit(pattern.left);
    this.rightHandNodes.push(pattern.right);
    this.#assignments.pop();
  }

  protected CallExpression(node: TSESTree.CallExpression): void {
    // arguments are right hand nodes.
    node.arguments.forEach(a => {
      this.rightHandNodes.push(a);
    });
    this.visit(node.callee);
  }

  protected Decorator(): void {
    // don't visit any decorators when exploring a pattern
  }

  protected Identifier(pattern: TSESTree.Identifier): void {
    const lastRestElement = this.#restElements.at(-1);

    this.#callback(pattern, {
      assignments: this.#assignments,
      rest: lastRestElement?.argument === pattern,
      topLevel: pattern === this.#rootPattern,
    });
  }

  protected MemberExpression(node: TSESTree.MemberExpression): void {
    // Computed property's key is a right hand node.
    if (node.computed) {
      this.rightHandNodes.push(node.property);
    }

    // the object is only read, write to its property.
    this.rightHandNodes.push(node.object);
  }

  protected Property(property: TSESTree.Property): void {
    // Computed property's key is a right hand node.
    if (property.computed) {
      this.rightHandNodes.push(property.key);
    }

    // If it's shorthand, its key is same as its value.
    // If it's shorthand and has its default value, its key is same as its value.left (the value is AssignmentPattern).
    // If it's not shorthand, the name of new variable is its value's.
    this.visit(property.value);
  }

  protected RestElement(pattern: TSESTree.RestElement): void {
    this.#restElements.push(pattern);
    this.visit(pattern.argument);
    this.#restElements.pop();
  }

  protected SpreadElement(node: TSESTree.SpreadElement): void {
    this.visit(node.argument);
  }

  protected TSTypeAnnotation(): void {
    // we don't want to visit types
  }
}

Methods (13) — full entries under Functions

Method Signature
isPattern (node: TSESTree.Node): node is \| TSESTree.ArrayPattern \| TSESTree.AssignmentPattern \| TSESTree...
ArrayExpression (node: TSESTree.ArrayExpression): void
ArrayPattern (pattern: TSESTree.ArrayPattern): void
AssignmentExpression (node: TSESTree.AssignmentExpression): void
AssignmentPattern (pattern: TSESTree.AssignmentPattern): void
CallExpression (node: TSESTree.CallExpression): void
Decorator (): void
Identifier (pattern: TSESTree.Identifier): void
MemberExpression (node: TSESTree.MemberExpression): void
Property (property: TSESTree.Property): void
RestElement (pattern: TSESTree.RestElement): void
SpreadElement (node: TSESTree.SpreadElement): void
TSTypeAnnotation (): void

Type Aliases

PatternVisitorCallback

type PatternVisitorCallback = (
  pattern: TSESTree.Identifier,
  info: {
    assignments: (TSESTree.AssignmentExpression | TSESTree.AssignmentPattern)[];
    rest: boolean;
    topLevel: boolean;
  },
) => void;

PatternVisitorOptions

type PatternVisitorOptions = VisitorOptions;

Generated by Syntax Scribe