Skip to content

Commit

Permalink
fix(grainfmt): Handle comments within lists (#1429)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusroberts committed Sep 15, 2022
1 parent be4b38d commit 05b5f52
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 9 deletions.
123 changes: 114 additions & 9 deletions compiler/src/formatting/format.re
Original file line number Diff line number Diff line change
Expand Up @@ -1066,41 +1066,146 @@ and resugar_list =

let last_item_was_spread = ref(false);

let list_length = List.length(processed_list);

let items =
List.map(
i =>
switch (i) {
List.mapi(
(index, item) =>
switch (item) {
| Regular(e) =>
last_item_was_spread := false;

Doc.group(print_expression(~original_source, ~comments, e));
// Do we have any comments on this line?
// If so, we break the whole list

// we might have a list list [1, 2 // comment
// 3]
// so need to use the comment after the last item
// [1,
// 2, //comment
// 3]

let end_line_comments =
if (index < list_length - 2) {
let next_item = List.nth(processed_list, index + 1);
Comment_utils.get_comments_between_locations(
~loc1=e.pexp_loc,
~loc2=
switch (next_item) {
| Regular(e)
| Spread(e) => e.pexp_loc
},
comments,
);
} else {
let (_, item_line, item_char, _) =
Locations.get_raw_pos_info(e.pexp_loc.loc_end);
Comment_utils.get_comments_on_line_end(
~line=item_line,
~char=item_char,
comments,
);
};

(
print_expression(
~original_source,
~comments=
Comment_utils.get_comments_inside_location(
~location=e.pexp_loc,
comments,
),
e,
),
end_line_comments,
);

| Spread(e) =>
last_item_was_spread := true;
Doc.group(

(
Doc.concat([
Doc.text("..."),
print_expression(~original_source, ~comments, e),
print_expression(
~original_source,
~comments=
Comment_utils.get_comments_inside_location(
~location=e.pexp_loc,
comments,
),
e,
),
]),
[],
);
},
processed_list,
);

// We have to compose this list by hand because of the complexity of if a list item
// is followed by a comment, the comma must come before the comment.
// It also impacts how we force a new line for a line ending comment at the end of a list
// without introducing an extra blank line when bringing the indentation back in again

let last_line_breaks_for_comments = ref(false);
let items_length = List.length(items);
let list_items =
List.mapi(
(i, (item, item_comments)) => {
let final_item = items_length - 1 == i;

let comment_doc =
switch (item_comments) {
| [] =>
last_line_breaks_for_comments := false;
if (final_item) {
Doc.nil;
} else {
Doc.concat([Doc.comma, Doc.line]);
};
| _ =>
let trailing_comments =
List.map(
(cmt: Parsetree.comment) =>
Doc.concat([
Doc.space,
Comment_utils.nobreak_comment_to_doc(cmt),
]),
item_comments,
);

last_line_breaks_for_comments := true;
Doc.concat([
Doc.comma,
Doc.concat(trailing_comments),
if (final_item) {Doc.nil} else {Doc.hardLine},
]);
};

Doc.concat([Doc.group(item), comment_doc]);
},
items,
);

Doc.group(
Doc.concat([
Doc.lbracket,
Doc.indent(
Doc.concat([
Doc.softLine,
Doc.join(~sep=Doc.concat([Doc.comma, Doc.line]), items),
if (last_item_was_spread^) {
Doc.concat(list_items),
if (last_item_was_spread^ || last_line_breaks_for_comments^) {
Doc.nil;
} else {
Doc.ifBreaks(Doc.comma, Doc.nil);
},
]),
),
Doc.softLine,
if (last_line_breaks_for_comments^) {
Doc.hardLine;
} else {
Doc.softLine;
},
Doc.rbracket,
]),
);
Expand Down
27 changes: 27 additions & 0 deletions compiler/test/formatter_inputs/list_sugar.gr
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,31 @@ let list4 = [[1,2],[3,4],[5,6]]
let list5 = [[1,2,3],[3,4,5],[5,6,7]]
}

let test = [ 1, /* a */
2, // test
3,
]

let test2 = [ 1, /* a */
2, // test
3, // final comment
]

let test3 = [ 1, // comm

]



let recs = [
{ num: 1, var: A, str: "" },


{ num: 1, var: A, str: "foo" }, // A comment
{ num: 1, var: A, str: "bar" },
]

let t = [ 1, /*inline*/ 2, // comment
3]

let cons = (a, b) => [a, ...b] // <- some long comment some long comment some long comment some long comment
28 changes: 28 additions & 0 deletions compiler/test/formatter_outputs/list_sugar.gr
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,34 @@ let inaBlock = {
let list5 = [[1, 2, 3], [3, 4, 5], [5, 6, 7]]
}

let test = [
1, /* a */
2, // test
3,
]

let test2 = [
1, /* a */
2, // test
3, // final comment
]

let test3 = [
1, // comm
]

let recs = [
{ num: 1, var: A, str: "" },
{ num: 1, var: A, str: "foo" }, // A comment
{ num: 1, var: A, str: "bar" },
]

let t = [
1, /*inline*/
2, // comment
3,
]

let cons = (a, b) =>
[
a,
Expand Down

0 comments on commit 05b5f52

Please sign in to comment.