use super::*;
use shuck_ast::raw_shell;
pub(crate) fn span_contains(outer: Span, inner: Span) -> bool {
outer.start.offset <= inner.start.offset && outer.end.offset >= inner.end.offset
}
pub(crate) fn advance_shell_char(text: &str, index: usize) -> usize {
raw_shell::advance_shell_char(text, index)
}
pub(crate) fn collect_scan_span_excluding(
span: Span,
excluded: &[Span],
source: &str,
spans: &mut Vec<Span>,
) {
if excluded.is_empty() {
spans.push(span);
return;
}
let mut cursor = span.start.offset;
for excluded_span in excluded.iter().copied().filter(|excluded_span| {
excluded_span.end.offset > span.start.offset && excluded_span.start.offset < span.end.offset
}) {
let segment_end = excluded_span.start.offset.min(span.end.offset);
if cursor < segment_end {
spans.push(scan_span_segment(span, cursor, segment_end, source));
}
cursor = cursor.max(excluded_span.end.offset).min(span.end.offset);
}
if cursor < span.end.offset {
spans.push(scan_span_segment(span, cursor, span.end.offset, source));
}
}
pub(crate) fn scan_span_segment(span: Span, start: usize, end: usize, source: &str) -> Span {
let segment_start = span.start.advanced_by(&source[span.start.offset..start]);
let segment_end = span.start.advanced_by(&source[span.start.offset..end]);
Span::from_positions(segment_start, segment_end)
}
pub(crate) fn span_is_backslash_escaped(span: Span, source: &str) -> bool {
offset_is_backslash_escaped(span.start.offset, source)
}
pub(crate) fn offset_is_backslash_escaped(offset: usize, source: &str) -> bool {
raw_shell::offset_is_backslash_escaped(source, offset)
}
pub(crate) fn span_is_escaped(span: Span, source: &str) -> bool {
span_is_backslash_escaped(span, source)
}