isNamingPosition

tcmts.core.canonicalize.isNamingPosition · #eiygrany · term · runs anywhere

Identifiers whose text becomes a runtime name: declared function/class names, and bindings that name an anonymous function or class (const f = () => {}, (cb = () => {}) =>, f = function () {}). Renaming these is observable through .name, so their text is hashed; every other local stays alpha-renamable.

import { NAMING_ASSIGNMENTS } from "#codebase/tcmts/core/canonicalize";
import { isAnonymousFunction } from "#codebase/tcmts/core/extract";
import {
  isBinaryExpression as ts_isBinaryExpression, isBindingElement as ts_isBindingElement,
  isClassDeclaration as ts_isClassDeclaration, isClassExpression as ts_isClassExpression,
  isFunctionDeclaration as ts_isFunctionDeclaration, isFunctionExpression as ts_isFunctionExpression,
  isParameterDeclaration as ts_isParameter, isVariableDeclaration as ts_isVariableDeclaration,
} from "typescript/ast";
import type { Identifier as ts_Identifier } from "typescript/ast";

export function isNamingPosition(id: ts_Identifier): boolean {
  const p = id.parent;
  if ((ts_isFunctionDeclaration(p) || ts_isFunctionExpression(p) || ts_isClassDeclaration(p) || ts_isClassExpression(p)) && p.name === id) return true;
  if ((ts_isVariableDeclaration(p) || ts_isParameter(p) || ts_isBindingElement(p)) && p.name === id) return !!p.initializer && isAnonymousFunction(p.initializer);
  if (ts_isBinaryExpression(p) && p.left === id && NAMING_ASSIGNMENTS.has(p.operatorToken.kind)) return isAnonymousFunction(p.right);
  return false;
}

uses

used by