Skip to content

Commit c97ee1f

Browse files
committed
Format binary operators comments
1 parent c0e4f8b commit c97ee1f

File tree

1 file changed

+91
-2
lines changed

1 file changed

+91
-2
lines changed

Diff for: lib/elixir/lib/code/formatter.ex

+91-2
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,16 @@ defmodule Code.Formatter do
807807
left_context = left_op_context(context)
808808
right_context = right_op_context(context)
809809

810+
{comments, [left_arg, right_arg]} = pop_binary_op_chain_comments(op, [left_arg, right_arg], [])
811+
comments = Enum.sort_by(comments, &(&1.line))
812+
comments_docs =
813+
Enum.map(comments, fn comment ->
814+
comment = format_comment(comment)
815+
{comment.text, @empty, 1}
816+
end)
817+
818+
comments_docs = merge_algebra_with_comments(comments_docs, @empty)
819+
810820
{left, state} =
811821
binary_operand_to_algebra(left_arg, left_context, state, op, op_info, :left, 2)
812822

@@ -826,7 +836,6 @@ defmodule Code.Formatter do
826836

827837
next_break_fits? =
828838
op in @next_break_fits_operators and next_break_fits?(right_arg, state) and not eol?
829-
830839
{" " <> op_string,
831840
with_next_break_fits(next_break_fits?, right, fn right ->
832841
right = nest(concat(break(), right), nesting, :break)
@@ -835,10 +844,62 @@ defmodule Code.Formatter do
835844
end
836845

837846
op_doc = color_doc(op_string, :operator, state.inspect_opts)
838-
doc = concat(concat(group(left), op_doc), group(right))
847+
doc = concat(doc = concat(group(left), op_doc), group(right))
848+
849+
doc =
850+
case comments_docs do
851+
[] -> doc
852+
[line] -> line(line, doc)
853+
lines -> line(lines |> Enum.reduce(&line(&2, &1)) |> force_unfit(), doc)
854+
end
839855
{doc, state}
840856
end
841857

858+
defp pop_binary_op_chain_comments(op, [{_, left_meta, _} = left, right], acc) do
859+
left_leading = List.wrap(left_meta[:leading_comments])
860+
left_trailing = List.wrap(left_meta[:trailing_comments])
861+
862+
left = Macro.update_meta(left, &Keyword.drop(&1, [:leading_comments, :trailing_comments]))
863+
864+
acc = Enum.concat([left_leading, left_trailing, acc])
865+
866+
{_assoc, prec} = augmented_binary_op(op)
867+
868+
with {right_op, right_meta, right_args} <- right,
869+
true <- right_op not in @pipeline_operators,
870+
true <- right_op not in @right_new_line_before_binary_operators,
871+
{_, right_prec} <- augmented_binary_op(right_op) do
872+
{acc, right_args} = pop_binary_op_chain_comments(right_op, right_args, acc)
873+
874+
right = {right_op, right_meta, right_args}
875+
876+
{acc, [left, right]}
877+
else
878+
_ ->
879+
{acc, right} =
880+
case right do
881+
{_, right_meta, _} ->
882+
right_leading = List.wrap(right_meta[:leading_comments])
883+
right_trailing = List.wrap(right_meta[:trailing_comments])
884+
885+
right = Macro.update_meta(right, &Keyword.drop(&1, [:leading_comments, :trailing_comments]))
886+
887+
acc = Enum.concat([right_leading, right_trailing, acc])
888+
889+
{acc, right}
890+
891+
_ ->
892+
{acc, right}
893+
end
894+
895+
{acc, [left, right]}
896+
end
897+
end
898+
899+
defp pop_binary_op_chain_comments(_, args, acc) do
900+
{acc, args}
901+
end
902+
842903
# TODO: We can remove this workaround once we remove
843904
# ?rearrange_uop from the parser on v2.0.
844905
# (! left) in right
@@ -1624,6 +1685,34 @@ defmodule Code.Formatter do
16241685
fun = &quoted_to_algebra(&1, :parens_arg, &2)
16251686
{left_doc, state} = fun.(left, state)
16261687

1688+
before_cons_comments =
1689+
case left do
1690+
{_, meta, _} ->
1691+
List.wrap(meta[:trailing_comments])
1692+
1693+
_ ->
1694+
[]
1695+
end
1696+
1697+
right =
1698+
case right do
1699+
{_, _, _} ->
1700+
Macro.update_meta(right, fn meta ->
1701+
Keyword.update(meta, :leading_comments, before_cons_comments, &(before_cons_comments ++ &1))
1702+
end)
1703+
1704+
[{{_, _, _} = key, value} | rest] ->
1705+
key =
1706+
Macro.update_meta(key, fn meta ->
1707+
Keyword.update(meta, :leading_comments, before_cons_comments, &(before_cons_comments ++ &1))
1708+
end)
1709+
1710+
[{key, value} | rest]
1711+
1712+
_ ->
1713+
right
1714+
end
1715+
16271716
{right_doc, _join, state} =
16281717
args_to_algebra_with_comments(right, meta, :none, join, state, fun)
16291718

0 commit comments

Comments
 (0)