use crate::comment::Comment;
use crate::declaration::Declaration;
use crate::file::ElmModule;
use super::Printer;
use super::comment_slots::CommentSlots;
impl Printer {
pub(super) fn write_declarations_with_comments(
&mut self,
module: &ElmModule,
slots: &CommentSlots,
num_imports: usize,
) {
for (i, decl) in module.declarations.iter().enumerate() {
let slot = num_imports + i;
let is_infix = matches!(decl.value, Declaration::InfixDeclaration(_));
let prev_is_infix = i > 0
&& matches!(
module.declarations[i - 1].value,
Declaration::InfixDeclaration(_)
);
let infix_group = self.is_pretty() && is_infix && prev_is_infix;
let inline_trailing = self.is_pretty()
&& i > 0
&& !slots.slots[slot].is_empty()
&& matches!(&slots.slots[slot][0].value, Comment::Line(_))
&& {
let c0 = &slots.slots[slot][0];
let prev_end_line = module.declarations[i - 1].span.end.line;
c0.span.start.line == prev_end_line
};
if inline_trailing {
self.write_char(' ');
self.write_comment(&slots.slots[slot][0].value);
}
let skip_first = if inline_trailing { 1 } else { 0 };
let remaining: Vec<_> = slots.slots[slot].iter().skip(skip_first).collect();
if !remaining.is_empty() {
let is_section = matches!(&remaining[0].value, Comment::Line(_));
let is_attached_marker = remaining.len() == 1
&& matches!(
&remaining[0].value,
Comment::Block(text) if text.trim().is_empty()
|| text.trim().chars().all(|c| c == '-')
);
if self.is_pretty() {
if is_section {
if i > 0 {
self.newline();
self.newline();
self.newline();
self.newline();
} else if num_imports > 0 {
self.newline();
self.newline();
self.newline();
} else {
self.newline();
}
} else if is_attached_marker {
if i > 0 {
self.newline();
self.newline();
self.newline();
} else if num_imports > 0 {
self.newline();
self.newline();
} else {
self.newline();
}
} else {
let first_comment_line = remaining[0].span.start.line;
let prev_end_line: u32 = if i > 0 {
module.declarations[i - 1].span.end.line
} else if num_imports > 0 {
module.imports[num_imports - 1].span.end.line
} else if let Some(doc) = &module.module_documentation {
doc.span.end.line
} else {
module.header.span.end.line
};
let source_blanks = first_comment_line.saturating_sub(prev_end_line + 1);
let min_blanks = if i == 0 && num_imports == 0 {
1u32
} else if i > 0 {
3u32
} else {
2u32
};
let blanks = source_blanks.max(min_blanks);
let newlines = if i > 0 { blanks + 1 } else { blanks };
for _ in 0..newlines {
self.newline();
}
}
} else {
self.newline();
self.newline();
}
for c in &remaining {
self.write_comment(&c.value);
self.newline();
}
if self.is_pretty() && is_attached_marker {
} else {
self.newline();
self.newline();
}
} else if infix_group {
self.newline();
} else {
self.newline();
self.newline();
if self.is_pretty() && i > 0 {
self.newline();
}
}
self.write_declaration(&decl.value);
}
}
pub(super) fn write_trailing_orphan_comments(
&mut self,
module: &ElmModule,
slots: &CommentSlots,
total_anchors: usize,
) {
if slots.slots[total_anchors].is_empty() {
return;
}
let inline_trailing_orphan = self.is_pretty()
&& !module.declarations.is_empty()
&& matches!(&slots.slots[total_anchors][0].value, Comment::Line(_))
&& {
let c0 = &slots.slots[total_anchors][0];
let last_decl = module.declarations.last().unwrap();
c0.span.start.line == last_decl.span.end.line
};
let skip_first = if inline_trailing_orphan { 1 } else { 0 };
if inline_trailing_orphan {
self.write_char(' ');
self.write_comment(&slots.slots[total_anchors][0].value);
}
let trailing: Vec<_> = slots.slots[total_anchors].iter().skip(skip_first).collect();
if trailing.is_empty() {
return;
}
self.newline();
self.newline();
if self.is_pretty() {
self.newline();
self.newline();
}
for (i, c) in trailing.iter().enumerate() {
if i > 0 {
self.newline();
}
self.write_comment(&c.value);
}
}
}