mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import { z } from "zod";
|
|
import type {
|
|
JavaScriptSourcePoint,
|
|
JavaScriptSourceRange,
|
|
} from "./javascriptStaticAnalysisTypes.js";
|
|
|
|
/** Compare parser coordinates by line, then UTF-16 column. */
|
|
export const compareJavaScriptSourcePoints = (
|
|
left: JavaScriptSourcePoint,
|
|
right: JavaScriptSourcePoint,
|
|
): number => left.line - right.line || left.column - right.column;
|
|
|
|
/** Include equal endpoints without implying runtime reachability. */
|
|
export const javascriptSourceRangeContains = (
|
|
outer: JavaScriptSourceRange,
|
|
inner: JavaScriptSourceRange,
|
|
): boolean =>
|
|
compareJavaScriptSourcePoints(outer.start, inner.start) <= 0 &&
|
|
compareJavaScriptSourcePoints(outer.end, inner.end) >= 0;
|
|
|
|
/** Exact artifact-local coordinate key; callers supply the artifact identity. */
|
|
export const javascriptSourceRangeKey = (
|
|
range: JavaScriptSourceRange,
|
|
): string =>
|
|
`${range.start.line}:${range.start.column}-${range.end.line}:${range.end.column}`;
|
|
|
|
const sourcePointSchema = z.strictObject({
|
|
line: z.number().int().min(1),
|
|
column: z.number().int().min(0),
|
|
});
|
|
|
|
/** JavaScript source coordinates use one-based lines and zero-based columns. */
|
|
export const javascriptSourceRangeSchema = z
|
|
.strictObject({ start: sourcePointSchema, end: sourcePointSchema })
|
|
.superRefine((range, context) => {
|
|
if (compareJavaScriptSourcePoints(range.end, range.start) < 0)
|
|
context.addIssue({
|
|
code: "custom",
|
|
path: ["end"],
|
|
message: "Source range end must not precede its start",
|
|
});
|
|
})
|
|
.describe(
|
|
"One-based lines, zero-based UTF-16 columns; start inclusive, end exclusive.",
|
|
);
|