Skip to content

Commit

Permalink
feat: Pretty print record expressions with the .. operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Oct 12, 2017
1 parent d6b03cc commit aeb1d75
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 22 deletions.
29 changes: 13 additions & 16 deletions base/src/types/pretty_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@ pub fn doc_comment<'a>(
text: Option<&'a Comment>,
) -> DocBuilder<'a, Arena<'a>> {
match text {
Some(comment) => {
match comment.typ {
CommentType::Line => {
arena.concat(comment.content.lines().map(|line| {
arena.text("/// ").append(line).append(arena.newline())
}))
}
CommentType::Block => {
chain![arena;
Some(comment) => match comment.typ {
CommentType::Line => arena.concat(comment.content.lines().map(|line| {
arena.text("/// ").append(line).append(arena.newline())
})),
CommentType::Block => chain![arena;
"/**",
arena.newline(),
arena.concat(comment.content.lines().map(|line| {
Expand All @@ -42,10 +38,8 @@ pub fn doc_comment<'a>(
})),
"*/",
arena.newline()
]
}
}
}
],
},
None => arena.nil(),
}
}
Expand Down Expand Up @@ -109,7 +103,7 @@ impl<'a: 'e, 'e> Printer<'a, 'e> {
}

pub fn comments_after(&self, end: BytePos) -> DocBuilder<'a, Arena<'a>> {
let (doc, block_comments) =
let (doc, block_comments, _) =
self.comments_count(Span::new(end, self.source.src().len().into()));
if block_comments == 0 {
doc
Expand All @@ -122,11 +116,14 @@ impl<'a: 'e, 'e> Printer<'a, 'e> {
}
}

pub fn comments_count(&self, span: Span<BytePos>) -> (DocBuilder<'a, Arena<'a>>, usize) {
pub fn comments_count(&self, span: Span<BytePos>) -> (DocBuilder<'a, Arena<'a>>, usize, bool) {
let arena = self.arena;
let mut comments = 0;
let mut ends_with_newline = false;
let doc = arena.concat(self.source.comments_between(span).map(|comment| {
ends_with_newline = false;
if comment.is_empty() {
ends_with_newline = true;
arena.newline()
} else if comment.starts_with("//") {
arena.text(comment).append(arena.newline())
Expand All @@ -135,6 +132,6 @@ impl<'a: 'e, 'e> Printer<'a, 'e> {
arena.text(comment)
}
}));
(doc, comments)
(doc, comments, ends_with_newline)
}
}
36 changes: 30 additions & 6 deletions format/src/pretty_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,12 +298,14 @@ impl<'a: 'e, 'e> Printer<'a, 'e> {
default: DocBuilder<'a, Arena<'a>>,
) -> DocBuilder<'a, Arena<'a>> {
let arena = self.arena;
let (doc, count) = self.comments_count(span);
let (doc, count, ends_with_newline) = self.comments_count(span);
if doc.1 == arena.nil().1 {
default
} else if count == 0 {
// No comments, only newlines from the iterator
doc
} else if ends_with_newline {
arena.space().append(doc)
} else {
arena.space().append(doc).append(arena.space())
}
Expand Down Expand Up @@ -338,6 +340,7 @@ impl<'a: 'e, 'e> Printer<'a, 'e> {
Expr::Record {
ref types,
ref exprs,
ref base,
..
} => {
let ordered_iter = || {
Expand Down Expand Up @@ -373,13 +376,18 @@ impl<'a: 'e, 'e> Printer<'a, 'e> {
let mut line = newline(arena, expr);
// If there are any explicit line breaks then we need put each field on a separate
// line
if newlines.iter().any(|&(ref l, ref r)| {
let newline_in_fields = newlines.iter().any(|&(ref l, ref r)| {
l.1 != arena.nil().1 || r.1 != arena.nil().1
}) {
});
let newline_in_base = base.as_ref().map_or(false, |base| {
self.space_before(base.span.start).1 != arena.nil().1
});
if newline_in_fields || newline_in_base {
line = arena.newline();
}

let last_field_end = spans().last().map_or(expr.span.start, |s| s.end);
let last_field_end = spans().last().map_or(expr.span.start + 1.into(), |s| s.end);
let last_element_end = base.as_ref().map_or(last_field_end, |base| base.span.end);

let record = arena
.concat(self.comma_sep(
Expand Down Expand Up @@ -408,8 +416,19 @@ impl<'a: 'e, 'e> Printer<'a, 'e> {
}),
|spanned| spanned.value,
))
.append(match *base {
Some(ref base) => chain![arena;
self.space_after(last_field_end),
"..",
self.space_before(base.span.start),
self.pretty_expr_(base.span.start, base)
],
None => arena.nil(),
})
.nest(INDENT)
.append(self.whitespace(Span::new(last_field_end, expr.span.end), line.clone()))
.append(
self.whitespace(Span::new(last_element_end, expr.span.end), line.clone()),
)
.group()
.append("}");
(arena.text("{"), record)
Expand Down Expand Up @@ -672,11 +691,16 @@ fn forced_new_line<Id>(expr: &SpannedExpr<Id>) -> bool {
Expr::LetBindings(..) | Expr::Match(..) | Expr::TypeBindings(..) => true,
Expr::Lambda(ref lambda) => forced_new_line(&lambda.body),
Expr::Tuple { ref elems, .. } => elems.iter().any(forced_new_line),
Expr::Record { ref exprs, .. } => exprs.iter().any(|field| {
Expr::Record {
ref exprs,
ref base,
..
} => exprs.iter().any(|field| {
field
.value
.as_ref()
.map_or(false, |expr| forced_new_line(expr))
|| base.as_ref().map_or(false, |base| forced_new_line(base))
}),
Expr::IfElse(_, ref t, ref f) => forced_new_line(t) || forced_new_line(f),
Expr::Infix(ref l, _, ref r) => forced_new_line(l) || forced_new_line(r),
Expand Down
24 changes: 24 additions & 0 deletions format/tests/pretty_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,27 @@ x
"#;
assert_diff!(&format_expr(expr).unwrap(), expr, " ", 0);
}

#[test]
fn preserve_comments_in_empty_record() {
let expr = r#"
{
// 123
}
"#;
assert_diff!(&format_expr(expr).unwrap(), expr, " ", 0);
}

#[test]
fn preserve_comments_in_record_base() {
let expr = r#"
{
// 123
..
// abc
test
/* x */
}
"#;
assert_diff!(&format_expr(expr).unwrap(), expr, " ", 0);
}

0 comments on commit aeb1d75

Please sign in to comment.