isCalled

tcmts.core.canonicalize.isCalled · #lf3vfhs3 · term · runs anywhere

Whether a reference is called where it's written: f(…), new f(…), f`…`, or class C extends f (making a C calls it). Calling a function runs its body, so what that uses is needed then too (see initOrder); a reference that's only read (const alias = f) doesn't run it.

import {
  isAsExpression as ts_isAsExpression, isCallExpression as ts_isCallExpression,
  isExpressionWithTypeArguments as ts_isExpressionWithTypeArguments, isHeritageClause as ts_isHeritageClause,
  isNewExpression as ts_isNewExpression, isNonNullExpression as ts_isNonNullExpression,
  isParenthesizedExpression as ts_isParenthesizedExpression, isSatisfiesExpression as ts_isSatisfiesExpression,
  isTaggedTemplateExpression as ts_isTaggedTemplateExpression, SyntaxKind as ts_SyntaxKind,
} from "typescript/ast";
import type { Node as ts_Node } from "typescript/ast";

export function isCalled(id: ts_Node): boolean {
  let n = id;
  while (
    n.parent &&
    (ts_isParenthesizedExpression(n.parent) ||
      ts_isNonNullExpression(n.parent) ||
      ts_isAsExpression(n.parent) ||
      ts_isSatisfiesExpression(n.parent))
  )
    n = n.parent;
  const p = n.parent;
  if (!p) return false;
  if (ts_isCallExpression(p) || ts_isNewExpression(p)) return p.expression === n;
  if (ts_isTaggedTemplateExpression(p)) return p.tag === n;
  return (
    ts_isExpressionWithTypeArguments(p) &&
    p.expression === n &&
    !!p.parent &&
    ts_isHeritageClause(p.parent) &&
    p.parent.token === ts_SyntaxKind.ExtendsKeyword
  );
}

used by