@@ -2213,18 +2213,14 @@ def format(q)
22132213 end
22142214
22152215 class CallChainFormatter
2216- # [Call] the top of the call chain
2216+ # [Call | MethodAddBlock ] the top of the call chain
22172217 attr_reader :node
22182218
22192219 def initialize ( node )
22202220 @node = node
22212221 end
22222222
22232223 def format ( q )
2224- q . group { q . if_break { format_chain ( q ) } . if_flat { node . format_contents ( q ) } }
2225- end
2226-
2227- def format_chain ( q )
22282224 children = [ node ]
22292225
22302226 # First, walk down the chain until we get to the point where we're not
@@ -2242,6 +2238,14 @@ def format_chain(q)
22422238 end
22432239 end
22442240
2241+ if children . length > 2
2242+ q . group { q . if_break { format_chain ( q , children ) } . if_flat { node . format_contents ( q ) } }
2243+ else
2244+ node . format_contents ( q )
2245+ end
2246+ end
2247+
2248+ def format_chain ( q , children )
22452249 # We're going to have some specialized behavior for if it's an entire
22462250 # chain of calls without arguments except for the last one. This is common
22472251 # enough in Ruby source code that it's worth the extra complexity here.
@@ -2263,6 +2267,11 @@ def format_chain(q)
22632267 end
22642268
22652269 q . indent do
2270+ # We track another variable that checks if you need to move the
2271+ # operator to the previous line in case there are trailing comments
2272+ # and a trailing operator.
2273+ skip_operator = false
2274+
22662275 while child = children . pop
22672276 case child
22682277 in Call [ receiver : Call [ message : { value : "where" } ] , message : { value : "not" } ]
@@ -2277,7 +2286,17 @@ def format_chain(q)
22772286 else
22782287 end
22792288
2280- format_child ( q , child , skip_attached : empty_except_last && children . empty? )
2289+ format_child ( q , child , skip_operator : skip_operator , skip_attached : empty_except_last && children . empty? )
2290+
2291+ # If the parent call node has a comment on the message then we need
2292+ # to print the operator trailing in order to keep it working.
2293+ case children . last
2294+ in Call [ message : { comments : [ _ , *] } , operator :]
2295+ q . format ( CallOperatorFormatter . new ( operator ) )
2296+ skip_operator = true
2297+ else
2298+ skip_operator = false
2299+ end
22812300
22822301 # Pop off the formatter's stack so that it aligns with what would
22832302 # have happened if we had been formatting normally.
@@ -2315,11 +2334,11 @@ def attach_directly?(child)
23152334 . include? ( child . receiver . class )
23162335 end
23172336
2318- def format_child ( q , child , skip_attached : false )
2337+ def format_child ( q , child , skip_operator : false , skip_attached : false )
23192338 # First, format the actual contents of the child.
23202339 case child
23212340 in Call
2322- q . format ( CallOperatorFormatter . new ( child . operator ) )
2341+ q . format ( CallOperatorFormatter . new ( child . operator ) ) unless skip_operator
23232342 q . format ( child . message ) if child . message != :call
23242343 child . format_arguments ( q ) unless skip_attached
23252344 in MethodAddBlock
@@ -5925,6 +5944,17 @@ def deconstruct_keys(keys)
59255944 end
59265945
59275946 def format ( q )
5947+ # If we're at the top of a call chain, then we're going to do some
5948+ # specialized printing in case we can print it nicely. We _only_ do this
5949+ # at the top of the chain to avoid weird recursion issues.
5950+ if !CallChainFormatter . chained? ( q . parent ) && CallChainFormatter . chained? ( call )
5951+ q . group { q . if_break { CallChainFormatter . new ( self ) . format ( q ) } . if_flat { format_contents ( q ) } }
5952+ else
5953+ format_contents ( q )
5954+ end
5955+ end
5956+
5957+ def format_contents ( q )
59285958 q . format ( call )
59295959 q . format ( block )
59305960 end
0 commit comments