brokenLiteral

tcmts.cli.main.brokenLiteral · #xzypikv3 · term · runs on the server

uses tcmts.cli.main.templateLiterals, which uses tcmts.core.ts.parse, which uses tcmts.core.ts.compiler, which uses process

Why an edit can't be made, if it would end or split a template literal it's inside: before and after it, the places in before it replaced with inserted. A literal an edit is inside (its backticks left as they were) is expected to end where it did, moved by what the edits changed, as parsing both (as file) finds; an edit that takes in a literal's backtick changes it on purpose. Lines are numbered from from + 1.

import { templateLiterals } from "#codebase/tcmts/cli/main";

export function brokenLiteral(
  before: string,
  after: string,
  places: { index: number; length: number }[],
  inserted: string,
  file: string,
  from = 0,
): string | undefined {
  const by = (ps: typeof places) => ps.reduce((n, p) => n + inserted.length - p.length, 0);
  let now: Set<string> | undefined;
  for (const [a, b] of templateLiterals(before, file)) {
    const inside = places.filter((p) => p.index > a && p.index + p.length < b);
    if (
      !inside.length ||
      places.some((p) => p.index < b && p.index + p.length > a && !inside.includes(p))
    )
      continue;
    const shift = by(places.filter((p) => p.index + p.length <= a));
    now ??= new Set(templateLiterals(after, file).map(([a, b]) => `${a}:${b}`));
    if (now.has(`${a + shift}:${b + shift + by(inside)}`)) continue;
    const line = from + before.slice(0, a).split("\n").length;
    // (one that isn't escaped: after no backslash, or an escaped one)
    return /(?<!\\)(?:\\\\)*`/.test(inserted)
      ? `new has a bare backtick inside the template literal at line ${line}, which would end the literal there: escape it as \\\` (in JSON, "\\\\\`"), or, to end the literal, take its closing backtick into old`
      : /(?<!\\)(?:\\\\)*\$\{/.test(inserted)
        ? `new has a bare \${ inside the template literal at line ${line}, which would start a substitution there: escape it as \\\${ (in JSON, "\\\\\${")`
        : `the edit would change where the template literal at line ${line} ends: escape a backtick or \${ in new as \\\` or \\\${`;
  }
  return undefined;
}

uses

used by