use crate::types::{Expression, SimpleSelector, Span, Term};
pub(super) fn expr_end(expr: &Expression) -> Span {
match expr {
Expression::Term(term) => term_end(term),
Expression::With(_, _, _, expr)
| Expression::Let(_, _, _, expr)
| Expression::Assert(_, _, _, expr)
| Expression::If(_, _, _, _, _, expr)
| Expression::Abstraction(_, _, expr)
| Expression::Application(_, expr)
| Expression::Operation(_, _, expr)
| Expression::Negation(_, expr)
| Expression::Inversion(_, expr) => expr_end(expr),
Expression::MemberCheck(_, _, selectors) => selectors
.last()
.map_or(Span::point(0), |last| simple_selector_end(&last.selector)),
}
}
fn term_end(term: &Term) -> Span {
match term {
Term::Token(leaf) => leaf.span,
Term::SimpleString(s) | Term::IndentedString(s) => s.span,
Term::Path(p) => p.span,
Term::List(_, _, close) | Term::Set(_, _, _, close) | Term::Parenthesized(_, _, close) => {
close.span
}
Term::Selection(_, selectors, default) => {
if let Some((_, default_expr)) = default {
term_end(default_expr)
} else {
simple_selector_end(&selectors.last().expect("≥1 selector").selector)
}
}
}
}
const fn simple_selector_end(sel: &SimpleSelector) -> Span {
match sel {
SimpleSelector::ID(leaf) => leaf.span,
SimpleSelector::Interpol(ann) => ann.span,
SimpleSelector::String(s) => s.span,
}
}