blankImports

tcmts.cli.main.blankImports · #pfxfnomf · term · runs on the server

uses tcmts.core.ts.parse, which uses tcmts.core.ts.compiler, which uses process

A module's text without the imports of these names, blanked (spaces where they were) so nothing else moves.

import { parse } from "#codebase/tcmts/core/ts";
import {
  isImportDeclaration as ts_isImportDeclaration, isNamespaceImport as ts_isNamespaceImport,
} from "typescript/ast";

export function blankImports(file: string, text: string, names: Set<string>): string {
  const sf = parse(file, text);
  const blanks: [number, number][] = [];
  for (const st of sf.statements) {
    if (!ts_isImportDeclaration(st) || !st.importClause) continue;
    const c = st.importClause;
    const b = c.namedBindings;
    const elements = b && !ts_isNamespaceImport(b) ? [...b.elements] : [];
    const locals = [
      ...(c.name ? [c.name.text] : []),
      ...(b && ts_isNamespaceImport(b) ? [b.name.text] : []),
      ...elements.map((e) => e.name.text),
    ];
    if (!locals.some((l) => names.has(l))) continue;
    if (locals.every((l) => names.has(l)) || (b && ts_isNamespaceImport(b))) {
      blanks.push([st.getStart(sf), st.end]);
      continue;
    }
    // the default, with its comma
    if (c.name && names.has(c.name.text))
      blanks.push([c.name.getStart(sf), text.indexOf(",", c.name.end) + 1]);
    const kept = elements.filter((e) => !names.has(e.name.text));
    const lastKept = kept.at(-1);
    // none of the braces' kept (only the default): the braces go, with the comma before them
    if (!lastKept && b && c.name) blanks.push([c.name.end, b.end]);
    else
      elements.forEach((e, i) => {
        if (!names.has(e.name.text)) return;
        // after the last one kept: from it, so its comma goes with them; before: with the comma that follows it
        const next = elements[i + 1];
        if (lastKept && e.pos > lastKept.pos) blanks.push([lastKept.end, e.end]);
        else if (next) blanks.push([e.getStart(sf), next.getStart(sf)]);
      });
  }
  let out = text;
  for (const [from, to] of blanks.sort((x, y) => y[0] - x[0]))
    out = out.slice(0, from) + out.slice(from, to).replace(/[^\n]/g, " ") + out.slice(to);
  return out;
}

uses

used by