compare
tcmts.cli.semver_checks.compare · #4wcp4fta · term · runs anywhere
import { callable, change, FLAGS, levelOf, properties, typeChanges } from "#codebase/tcmts/cli/semver_checks";
import type { Finding, LintId, Pair } from "#codebase/tcmts/cli/semver_checks";
import type { TypeChecker } from "#codebase/tcmts/core/ts";
import { SignatureKind as ts_SignatureKind, SymbolFlags as ts_SymbolFlags } from "typescript/sync";
import type { Symbol as ts_Symbol, Type as ts_Type } from "typescript/sync";
export function compare(checker: TypeChecker, p: Pair, o: ts_Symbol, n: ts_Symbol): Finding[] {
const out: Finding[] = [];
const add = (lint: LintId, detail?: string) => out.push({ lint, path: p.path, detail });
const str = (t: ts_Type) => checker.typeToString(t, undefined, FLAGS);
const assignable = (a: ts_Type, b: ts_Type) => checker.isTypeAssignableTo(a, b);
const isValue = (s: ts_Symbol) => !!(s.flags & ts_SymbolFlags.Value);
const isType = (s: ts_Symbol) => !!(s.flags & (ts_SymbolFlags.Type | ts_SymbolFlags.Class));
if (isValue(o) !== isValue(n) || (isType(o) && !isType(n))) {
add("kind_changed");
return out;
}
if (isValue(o)) {
const [ot, nt] = [checker.getTypeOfSymbol(o), checker.getTypeOfSymbol(n)];
callable(checker, ot, nt, ts_SignatureKind.Call, add);
if (o.flags & ts_SymbolFlags.Class) callable(checker, ot, nt, ts_SignatureKind.Construct, add);
const plain = !checker.getSignaturesOfType(ot, ts_SignatureKind.Call).length && !checker.getSignaturesOfType(nt, ts_SignatureKind.Call).length && !(o.flags & ts_SymbolFlags.Class);
if (plain) {
if (!assignable(nt, ot)) {
// say what about it, where the type is an object
const before = out.length;
properties(checker, ot, nt, add);
if (out.length === before) add("value_type_widened", change("", str(ot), str(nt)));
} else if (!assignable(ot, nt)) add("value_type_narrowed", change("", str(ot), str(nt)));
}
}
if (isType(o) && !(o.flags & ts_SymbolFlags.Class && out.some((f) => levelOf(f) === "major"))) {
const [ot, nt] = [checker.getDeclaredTypeOfSymbol(o), checker.getDeclaredTypeOfSymbol(n)];
typeChanges(checker, ot, nt, o, n, add);
}
if (!out.length) add("implementation_changed");
return out;
}
uses
used by