isMutableState

tcmts.cli.placement.isMutableState · #u2u2uhpw · term · runs anywhere

Whether a definition is module-level mutable state: a const holding a fresh mutable object (new Map(), [], {}), as opposed to a function, a primitive, an as const value or anything frozen or computed.

import type { IR } from "#codebase/tcmts/core/hash";
import { defParts, initializerOf } from "#codebase/tcmts/core/ir";

export function isMutableState(ir: IR): boolean {
  if (!Array.isArray(ir) || defParts(ir).tag !== "Const") return false;
  let init = initializerOf(ir);
  while (
    init &&
    (init[0] === "AsExpression" ||
      init[0] === "SatisfiesExpression" ||
      init[0] === "NonNullExpression")
  ) {
    const type = init.find((x) => Array.isArray(x) && x[0] === "type") as IR[] | undefined;
    if (
      init[0] === "AsExpression" &&
      JSON.stringify(type) ===
        JSON.stringify(["type", ["TypeReference", ["typeName", ["G", "const"]]]])
    )
      return false;
    init = (
      init.find((x) => Array.isArray(x) && x[0] === "expression") as IR[] | undefined
    )?.[1] as IR[] | undefined;
  }
  return (
    !!init &&
    ["NewExpression", "ArrayLiteralExpression", "ObjectLiteralExpression"].includes(
      init[0] as string,
    )
  );
}

uses

used by