Add slice methods, some helpers for CodePointSlice and a few predicates

This commit is contained in:
Yura Dupyn 2026-04-25 01:24:52 +02:00
parent 8471c60967
commit f72575ae54

View file

@ -37,8 +37,13 @@ export function isDigit(x: CodePoint): boolean {
return isBetween(DIGIT_0, x, DIGIT_9);
}
export function isAlphanumeric(x: CodePoint): boolean {
return isDigit(x) || isBetween(LOWERCASE_a, x, LOWERCASE_z) || isBetween(LOWERCASE_z, x, UPPERCASE_Z);
export function isAsciiAlpha(x: CodePoint): boolean {
return isBetween(LOWERCASE_a, x, LOWERCASE_z)
|| isBetween(UPPERCASE_A, x, UPPERCASE_Z);
}
export function isAsciiAlphanumeric(x: CodePoint): boolean {
return isAsciiAlpha(x) || isDigit(x);
}
export type CodePointRef = {
@ -137,6 +142,10 @@ export class SourceText {
return this.source.slice(startOff, endOff);
}
slice(span: CodePointSpan): string {
return this.sliceByCp(span.start, span.end);
}
// Returns a Span for the given line (1-based index).
// If stripNewlines is true, the span will exclude trailing \r\n.
getLineSpan(line: number, stripNewlines = true): Span {
@ -248,6 +257,18 @@ export function rawSpan(start: CodePointIndex, end: CodePointIndex): CodePointSp
return { start, end };
}
export function pointSpan(index: CodePointIndex): CodePointSpan {
return { start: index, end: index };
}
export function spanLength(span: CodePointSpan): number {
return span.end - span.start;
}
export function isZeroWidth(span: CodePointSpan): boolean {
return span.start === span.end;
}
export class SourceRegion {
constructor(
public readonly source: SourceText,
@ -317,6 +338,13 @@ export class SourceRegion {
}
}
slice(span: CodePointSpan): string {
if (span.start < this.span.start.index || span.end > this.span.end.index) {
throw new Error(`CodePointSpan ${span.start}-${span.end} is outside region ${this.span.start.index}-${this.span.end.index}`);
}
return this.source.sliceByCp(span.start, span.end);
}
// Creates a sub-region within this region.
// Validates that the new span is contained within the current region.
subRegion(span: Span): SourceRegion {