///|
/// A range of source text: UTF-16 code unit offsets, `end` exclusive.
pub(all) struct Span {
start : Int
end : Int
} derive(Debug, Eq)
///|
/// The smallest span that covers both spans.
pub fn Span::merge(self : Span, other : Span) -> Span {
{
start: if self.start < other.start {
self.start
} else {
other.start
},
end: if self.end > other.end {
self.end
} else {
other.end
},
}
}
///|
/// 1-based (line, column) of the start and of the end of the span. Lines end
/// at `\n` (a preceding `\r` belongs to the line); columns count UTF-16 code
/// units.
pub fn Span::line_column(
self : Span,
source : String,
) -> ((Int, Int), (Int, Int)) {
(position(source, self.start), position(source, self.end))
}
///|
fn position(source : String, offset : Int) -> (Int, Int) {
let mut line = 1
let mut line_start = 0
let limit = if offset < source.length() { offset } else { source.length() }
for i in 0..