@@ -804,6 +804,16 @@ defmodule Code.Formatter do
804
804
left_context = left_op_context ( context )
805
805
right_context = right_op_context ( context )
806
806
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
+
807
817
{ left , state } =
808
818
binary_operand_to_algebra ( left_arg , left_context , state , op , op_info , :left , 2 )
809
819
@@ -825,18 +835,68 @@ defmodule Code.Formatter do
825
835
826
836
next_break_fits? =
827
837
op in @ next_break_fits_operators and next_break_fits? ( right_arg , state ) and not eol?
828
-
829
838
with_next_break_fits ( next_break_fits? , right , fn right ->
830
839
op_doc = color_doc ( " " <> op_string , :operator , state . inspect_opts )
831
840
right = nest ( glue ( op_doc , group ( right ) ) , nesting , :break )
832
841
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
834
849
end )
835
850
end
836
851
837
852
{ doc , state }
838
853
end
839
854
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
+
840
900
# TODO: We can remove this workaround once we remove
841
901
# ?rearrange_uop from the parser on v2.0.
842
902
# (! left) in right
@@ -1626,6 +1686,34 @@ defmodule Code.Formatter do
1626
1686
fun = & quoted_to_algebra ( & 1 , :parens_arg , & 2 )
1627
1687
{ left_doc , state } = fun . ( left , state )
1628
1688
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
+
1629
1717
{ right_doc , _join , state } =
1630
1718
args_to_algebra_with_comments ( right , meta , :none , join , state , fun )
1631
1719
0 commit comments