diff --git a/compiler/grainformat/reformat.re b/compiler/grainformat/reformat.re index 68bd723811..60fba9a421 100644 --- a/compiler/grainformat/reformat.re +++ b/compiler/grainformat/reformat.re @@ -473,24 +473,45 @@ let rec resugar_list_patterns = ~original_source: array(string), ) => { let processed_list = resugar_pattern_list_inner(patterns, parent_loc); + let last_item_was_spread = ref(false); + let items = List.map( i => switch (i) { | RegularPattern(e) => - print_pattern(~pat=e, ~parent_loc, ~original_source) + last_item_was_spread := false; + + Doc.group(print_pattern(~pat=e, ~parent_loc, ~original_source)); | SpreadPattern(e) => - Doc.concat([ - Doc.text("..."), - print_pattern(~pat=e, ~parent_loc, ~original_source), - ]) + last_item_was_spread := true; + Doc.group( + Doc.concat([ + Doc.text("..."), + print_pattern(~pat=e, ~parent_loc, ~original_source), + ]), + ); }, processed_list, ); + Doc.group( Doc.concat([ - Doc.lbracket, - Doc.join(Doc.concat([Doc.comma, Doc.line]), items), + Doc.indent( + Doc.concat([ + Doc.lbracket, + Doc.concat([ + Doc.softLine, + Doc.join(Doc.concat([Doc.comma, Doc.line]), items), + ]), + if (last_item_was_spread^) { + Doc.nil; + } else { + Doc.ifBreaks(Doc.comma, Doc.nil); + }, + ]), + ), + Doc.softLine, Doc.rbracket, ]), ); @@ -511,9 +532,13 @@ and resugar_pattern_list_inner = if (func == "[]") { [RegularPattern(arg1)]; + } else if (func == list_cons) { + let inner = resugar_pattern_list_inner(innerpatterns, parent_loc); + List.append([RegularPattern(arg1)], inner); } else { [RegularPattern(arg1), SpreadPattern(arg2)]; }; + | _ => [RegularPattern(arg1), SpreadPattern(arg2)] }; } @@ -2962,7 +2987,7 @@ let data_print = original_source: array(string), ) => { Doc.join( - Doc.comma, + Doc.concat([Doc.comma, Doc.hardLine]), List.map( data => { let (expt, decl) = data; @@ -3505,7 +3530,6 @@ let reformat_ast = //Doc.debug(final_doc); // - Doc.toString(~width=80, final_doc); //use this to see the AST in JSON // print_endline( // Yojson.Basic.pretty_to_string( @@ -3514,4 +3538,6 @@ let reformat_ast = // ), // ), // ); + + Doc.toString(~width=80, final_doc); }; diff --git a/compiler/test/formatter_inputs/enums.gr b/compiler/test/formatter_inputs/enums.gr index a3e0e3cc1c..4eac42f3b0 100644 --- a/compiler/test/formatter_inputs/enums.gr +++ b/compiler/test/formatter_inputs/enums.gr @@ -44,3 +44,8 @@ enum ParsedRegularExpression { RERange(List<(Number, Number)>), REUnicodeCategories(List, Bool) // symlist, true=match/false=does-not-match } + + +record Node { node: AstValue }, + +enum AstValue { NodeValue(Node), StringValue(String) } diff --git a/compiler/test/formatter_inputs/matches.gr b/compiler/test/formatter_inputs/matches.gr index d6eb893b4c..ce7dff6239 100644 --- a/compiler/test/formatter_inputs/matches.gr +++ b/compiler/test/formatter_inputs/matches.gr @@ -27,4 +27,11 @@ match (A(1, 2)) { b, c ) => false -} \ No newline at end of file +} + +let testFormatting = charlist => { + match (charlist) { + ['f', 'o', 'r', 'm', 'a', 't', ...rest] => true, + _ => false + } +} diff --git a/compiler/test/formatter_inputs/nested_matches.gr b/compiler/test/formatter_inputs/nested_matches.gr index 13d8814c89..f1743d70cb 100644 --- a/compiler/test/formatter_inputs/nested_matches.gr +++ b/compiler/test/formatter_inputs/nested_matches.gr @@ -12,3 +12,4 @@ let join = (separator: String, items: List) => { } } } + diff --git a/compiler/test/formatter_outputs/enums.gr b/compiler/test/formatter_outputs/enums.gr index c5aa395b1a..817ddae705 100644 --- a/compiler/test/formatter_outputs/enums.gr +++ b/compiler/test/formatter_outputs/enums.gr @@ -77,3 +77,6 @@ enum ParsedRegularExpression { Bool ), // symlist, true=match/false=does-not-match } + +record Node { node: AstValue }, +enum AstValue { NodeValue(Node), StringValue(String) } diff --git a/compiler/test/formatter_outputs/matches.gr b/compiler/test/formatter_outputs/matches.gr index 9106417d20..3b6d7adf09 100644 --- a/compiler/test/formatter_outputs/matches.gr +++ b/compiler/test/formatter_outputs/matches.gr @@ -29,3 +29,10 @@ match (A(1, 2)) { A(a, b) => true, B(b, c) => false, } + +let testFormatting = charlist => { + match (charlist) { + ['f', 'o', 'r', 'm', 'a', 't', ...rest] => true, + _ => false, + } +}