isNamingPosition
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; }