Skip to content

Commit 40207bc

Browse files
committed
Format binary operators comments
1 parent 666b9e4 commit 40207bc

File tree

1 file changed

+90
-2
lines changed

1 file changed

+90
-2
lines changed

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

+90-2
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,16 @@ defmodule Code.Formatter do
804804
left_context = left_op_context(context)
805805
right_context = right_op_context(context)
806806

807+
{comments, [left_arg, right_arg]} = pop_binary_op_chain_comments(op, [left_arg, right_arg], [])
808+
comments = Enum.sort_by(comments, &(&1.line))
809+
comments_docs =
810+
Enum.map(comments, fn comment ->
811+
comment = format_comment(comment)
812+
{comment.text, @empty, 1}
813+
end)
814+
815+
comments_docs = merge_algebra_with_comments(comments_docs, @empty)
816+
807817
{left, state} =
808818
binary_operand_to_algebra(left_arg, left_context, state, op, op_info, :left, 2)
809819

@@ -825,18 +835,68 @@ defmodule Code.Formatter do
825835

826836
next_break_fits? =
827837
op in @next_break_fits_operators and next_break_fits?(right_arg, state) and not eol?
828-
829838
with_next_break_fits(next_break_fits?, right, fn right ->
830839
op_doc = color_doc(" " <> op_string, :operator, state.inspect_opts)
831840
right = nest(glue(op_doc, group(right)), nesting, :break)
832841
right = if eol?, do: force_unfit(right), else: right
833-
concat(group(left), group(right))
842+
doc = concat(group(left), group(right))
843+
844+
case comments_docs do
845+
[] -> doc
846+
[line] -> line(line, doc)
847+
lines -> line(lines |> Enum.reduce(&line(&2, &1)) |> force_unfit(), doc)
848+
end
834849
end)
835850
end
836851

837852
{doc, state}
838853
end
839854

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

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

0 commit comments

Comments
 (0)