use crate::predoc::{Doc, DocE, GroupAnn, Pretty, hardline, line};
use crate::types::{Binder, Expression, Items, Leaf, Parameter, Trivia, Trivium};
use super::term::push_pretty_items;
use super::absorb::{is_absorbable_expr, push_absorb_expr};
use super::util::{Width, move_trailing_comment_up};
pub(super) fn push_absorb_abs(doc: &mut Doc, depth: usize, expr: &Expression) {
match expr {
Expression::Abstraction {
param: Parameter::Id(param),
colon,
body,
} => {
doc.hardspace();
param.pretty(doc);
colon.pretty(doc);
push_absorb_abs(doc, depth + 1, body);
}
_ if is_absorbable_expr(expr) => {
doc.hardspace();
doc.group_ann(GroupAnn::Priority, |priority_group| {
push_absorb_expr(priority_group, Width::Regular, expr);
});
}
_ => {
let separator = if depth <= 2 { line() } else { hardline() };
doc.push_raw(separator);
expr.pretty(doc);
}
}
}
pub(super) fn insert_into_app(insert: Expression, expr: Expression) -> (Expression, Expression) {
match expr {
Expression::Application { func: f, arg: a } => {
let (f2, a2) = insert_into_app(insert, *f);
(
Expression::Application {
func: Box::new(f2),
arg: Box::new(a2),
},
*a,
)
}
other => (insert, other),
}
}
pub(super) fn pretty_let(
doc: &mut Doc,
let_kw: &Leaf,
binders: &Items<Binder>,
in_kw: &Leaf,
expr: &Expression,
) {
let mut in_kw_clean = in_kw.clone();
in_kw_clean.pre_trivia = Trivia::new();
in_kw_clean.trail_comment = None;
let mut moved_trivia_vec: Vec<Trivium> = in_kw.pre_trivia.clone().into();
if let Some(trailing) = &in_kw.trail_comment {
moved_trivia_vec.push(trailing.into());
}
let moved_trivia: Trivia = moved_trivia_vec.into();
doc.group(|g| {
let_kw.pretty(g);
g.hardline();
g.nested(|n| push_pretty_items(n, binders));
});
doc.hardline();
doc.group(|g| {
in_kw_clean.pretty(g);
g.hardline();
moved_trivia.pretty(g);
expr.pretty(g);
});
}
pub(super) fn pretty_with(
doc: &mut Doc,
with: &Leaf,
expr0: &Expression,
semicolon: &Leaf,
expr1: &Expression,
) {
doc.group(|g| {
with.pretty(g);
g.hardspace();
g.nested(|n| {
n.group(|inner| expr0.pretty(inner));
});
semicolon.pretty(g);
});
doc.line();
expr1.pretty(doc);
}
pub(super) fn pretty_if(doc: &mut Doc, sep: DocE, expr: &Expression) {
match expr {
Expression::If {
kw_if: if_kw,
cond,
kw_then: then_kw,
then_branch: expr0,
kw_else: else_kw,
else_branch: expr1,
} => {
doc.group(|g| {
if_kw.pretty(g);
g.line();
g.nested(|n| cond.pretty(n));
g.line();
then_kw.pretty(g);
});
doc.surrounded(&[sep], |d| {
d.nested(|n| {
n.group(|g| expr0.pretty(g));
});
});
move_trailing_comment_up(else_kw).pretty(doc);
doc.hardspace();
pretty_if(doc, hardline(), expr1);
}
x => {
doc.line();
doc.nested(|n| {
n.group(|g| x.pretty(g));
});
}
}
}