Skip to content

⬅️ Back to Table of Contents

πŸ“„ astUtils

πŸ“Š Analysis Summary

Metric Count
πŸ”§ Functions 6
πŸ“¦ Imports 4
πŸ”„ Re-exports 1

πŸ“š Table of Contents

πŸ› οΈ File Location:

πŸ“‚ packages/eslint-plugin/src/util/astUtils.ts

πŸ“¦ Imports

Name Source
TSESLint @typescript-eslint/utils
TSESTree @typescript-eslint/utils
visitorKeys @typescript-eslint/visitor-keys
escapeRegExp ./escapeRegExp

Re-exports

Type Source Exported Names
namespace @typescript-eslint/utils/ast-utils *

Functions

getNameLocationInGlobalDirectiveComment(sourceCode: TSESLint.SourceCode, comment: TSESTree.Comment, name: string): TSESTree.SourceLocation

Get the loc object of a given name in a /*globals comment directive.

Parameters:

  • sourceCode any: The source code to convert index to loc.
  • comment any: The /*globals comment directive which include the name.
  • name any: The name to find.

Returns: undefined The loc object.

Raw JSDoc
/**
 * Get the `loc` object of a given name in a `/*globals` comment directive.
 * @param sourceCode The source code to convert index to loc.
 * @param comment The `/*globals` comment directive which include the name.
 * @param name The name to find.
 * @returns The `loc` object.
 */

Calls:

  • escapeRegExp (from ./escapeRegExp)
  • comment.value.indexOf
  • namePattern.exec
  • sourceCode.getLocFromIndex

Internal Comments:

// To ignore the first text "global". (x4)
// Search a given variable name. (x2)
// Convert the index to loc. (x2)

Code
export function getNameLocationInGlobalDirectiveComment(
  sourceCode: TSESLint.SourceCode,
  comment: TSESTree.Comment,
  name: string,
): TSESTree.SourceLocation {
  const namePattern = new RegExp(
    `[\\s,]${escapeRegExp(name)}(?:$|[\\s,:])`,
    'gu',
  );

  // To ignore the first text "global".
  namePattern.lastIndex = comment.value.indexOf('global') + 6;

  // Search a given variable name.
  const match = namePattern.exec(comment.value);

  // Convert the index to loc.
  const start = sourceCode.getLocFromIndex(
    comment.range[0] + '/*'.length + (match ? match.index + 1 : 0),
  );
  const end = {
    column: start.column + (match ? name.length : 1),
    line: start.line,
  };

  return { end, start };
}

forEachReturnStatement(body: ts.Block, visitor: (stmt: ts.ReturnStatement) => T): T | undefined

Parameters:

  • body ts.Block
  • visitor (stmt: ts.ReturnStatement) => T

Returns: T | undefined

Calls:

  • traverse
  • visitor
  • ts.forEachChild
Code
export function forEachReturnStatement<T>(
  body: ts.Block,
  visitor: (stmt: ts.ReturnStatement) => T,
): T | undefined {
  return traverse(body);

  function traverse(node: ts.Node): T | undefined {
    switch (node.kind) {
      case ts.SyntaxKind.ReturnStatement:
        return visitor(node as ts.ReturnStatement);
      case ts.SyntaxKind.CaseBlock:
      case ts.SyntaxKind.Block:
      case ts.SyntaxKind.IfStatement:
      case ts.SyntaxKind.DoStatement:
      case ts.SyntaxKind.WhileStatement:
      case ts.SyntaxKind.ForStatement:
      case ts.SyntaxKind.ForInStatement:
      case ts.SyntaxKind.ForOfStatement:
      case ts.SyntaxKind.WithStatement:
      case ts.SyntaxKind.SwitchStatement:
      case ts.SyntaxKind.CaseClause:
      case ts.SyntaxKind.DefaultClause:
      case ts.SyntaxKind.LabeledStatement:
      case ts.SyntaxKind.TryStatement:
      case ts.SyntaxKind.CatchClause:
        return ts.forEachChild(node, traverse);
    }

    return undefined;
  }
}

forEachChildESTree(node: TSESTree.Node, callback: (child: TSESTree.Node) => false | Resul…): Result | undefined

Rough equivalent to ts.forEachChild for ESTree nodes. It returns the first truthy value returned by the callback, if any.

Raw JSDoc
/**
 * Rough equivalent to ts.forEachChild for ESTree nodes.
 * It returns the first truthy value returned by the callback, if any.
 */

Calls:

  • callback
  • Array.isArray
  • isESTreeNodeLike
  • visit
Code
export function forEachChildESTree<Result>(
  node: TSESTree.Node,
  callback: (child: TSESTree.Node) => false | Result | null | undefined,
): Result | undefined {
  function visit(currentNode: TSESTree.Node): Result | undefined {
    const result = callback(currentNode);
    if (result) {
      return result;
    }

    const currentKeys = visitorKeys[currentNode.type];
    if (!currentKeys) {
      return undefined;
    }

    for (const key of currentKeys) {
      const currentProperty = currentNode[key as keyof typeof currentNode];

      if (Array.isArray(currentProperty)) {
        for (const child of currentProperty) {
          if (isESTreeNodeLike(child)) {
            const result = visit(child);
            if (result) {
              return result;
            }
          }
        }
      } else if (isESTreeNodeLike(currentProperty)) {
        const result = visit(currentProperty);
        if (result) {
          return result;
        }
      }
    }

    return undefined;
  }

  return visit(node);
}

isESTreeNodeLike(node: unknown): node is TSESTree.Node

Parameters:

  • node unknown

Returns: node is TSESTree.Node

Internal Comments:

// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access (x2)

Code
function isESTreeNodeLike(node: unknown): node is TSESTree.Node {
  return (
    typeof node === 'object' &&
    node != null &&
    'type' in node &&
    // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
    typeof (node as any).type === 'string'
  );
}

Internal helpers

Declared inside another function in this file.

traverse(node: ts.Node): T | undefined

Parameters:

  • node ts.Node

Returns: T | undefined

Calls:

  • visitor
  • ts.forEachChild
Code
function traverse(node: ts.Node): T | undefined {
    switch (node.kind) {
      case ts.SyntaxKind.ReturnStatement:
        return visitor(node as ts.ReturnStatement);
      case ts.SyntaxKind.CaseBlock:
      case ts.SyntaxKind.Block:
      case ts.SyntaxKind.IfStatement:
      case ts.SyntaxKind.DoStatement:
      case ts.SyntaxKind.WhileStatement:
      case ts.SyntaxKind.ForStatement:
      case ts.SyntaxKind.ForInStatement:
      case ts.SyntaxKind.ForOfStatement:
      case ts.SyntaxKind.WithStatement:
      case ts.SyntaxKind.SwitchStatement:
      case ts.SyntaxKind.CaseClause:
      case ts.SyntaxKind.DefaultClause:
      case ts.SyntaxKind.LabeledStatement:
      case ts.SyntaxKind.TryStatement:
      case ts.SyntaxKind.CatchClause:
        return ts.forEachChild(node, traverse);
    }

    return undefined;
  }

visit(currentNode: TSESTree.Node): Result | undefined

Parameters:

  • currentNode TSESTree.Node

Returns: Result | undefined

Calls:

  • callback
  • Array.isArray
  • isESTreeNodeLike
  • visit
Code
function visit(currentNode: TSESTree.Node): Result | undefined {
    const result = callback(currentNode);
    if (result) {
      return result;
    }

    const currentKeys = visitorKeys[currentNode.type];
    if (!currentKeys) {
      return undefined;
    }

    for (const key of currentKeys) {
      const currentProperty = currentNode[key as keyof typeof currentNode];

      if (Array.isArray(currentProperty)) {
        for (const child of currentProperty) {
          if (isESTreeNodeLike(child)) {
            const result = visit(child);
            if (result) {
              return result;
            }
          }
        }
      } else if (isESTreeNodeLike(currentProperty)) {
        const result = visit(currentProperty);
        if (result) {
          return result;
        }
      }
    }

    return undefined;
  }

Generated by Syntax Scribe