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