@@ -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