@@ -551,6 +551,96 @@ def var_alias?
551551 end
552552 end
553553
554+ class AndNode < Node
555+ # Since AndNode's operator is a symbol, it's better to use the `name` method
556+ # than to allocate a new string every time. This is a tiny performance
557+ # optimization, but enough that it shows up in the profiler. Adding this in
558+ # for older Ruby versions.
559+ unless :+ . respond_to? ( :name )
560+ using Module . new {
561+ refine Symbol do
562+ def name
563+ to_s . freeze
564+ end
565+ end
566+ }
567+ end
568+
569+ # [Node] the left side of the && operator
570+ attr_reader :left
571+
572+ # [Symbol] the operator
573+ attr_reader :operator
574+
575+ # [Node] the right side of the && operator
576+ attr_reader :right
577+
578+ # [Array[ Comment | EmbDoc ]] the comments attached to this node
579+ attr_reader :comments
580+
581+ def initialize ( left :, operator :, right :, location :)
582+ @left = left
583+ @operator = operator
584+ @right = right
585+ @location = location
586+ @comments = [ ]
587+ end
588+
589+ def accept ( visitor )
590+ visitor . visit_and ( self )
591+ end
592+
593+ def child_nodes
594+ [ left , right ]
595+ end
596+
597+ def copy ( left : nil , operator : nil , right : nil , location : nil )
598+ node =
599+ AndNode . new (
600+ left : left || self . left ,
601+ operator : operator || self . operator ,
602+ right : right || self . right ,
603+ location : location || self . location
604+ )
605+ node . comments . concat ( comments . map ( &:copy ) )
606+ node
607+ end
608+
609+ alias deconstruct child_nodes
610+
611+ def deconstruct_keys ( _keys )
612+ {
613+ left : left ,
614+ operator : operator ,
615+ right : right ,
616+ location : location ,
617+ comments : comments
618+ }
619+ end
620+
621+ def format ( q )
622+ left = self . left
623+
624+ q . group do
625+ q . group { q . format ( left ) }
626+ q . text ( " " )
627+
628+ q . group do
629+ q . text ( operator . name )
630+ q . indent do
631+ q . breakable_space
632+ q . format ( right )
633+ end
634+ end
635+ end
636+ end
637+
638+ def ===( other )
639+ other . is_a? ( AndNode ) && left === other . left &&
640+ operator === other . operator && right === other . right
641+ end
642+ end
643+
554644 # ARef represents when you're pulling a value out of a collection at a
555645 # specific index. Put another way, it's any time you're calling the method
556646 # #[].
@@ -6267,7 +6357,7 @@ def call(q, node)
62676357 # want to force it to not be a ternary, like if the predicate is an
62686358 # assignment because it's hard to read.
62696359 case node . predicate
6270- when Assign , Binary , Command , CommandCall , MAssign , OpAssign
6360+ when Assign , AndNode , Binary , Command , CommandCall , MAssign , OpAssign
62716361 return false
62726362 when Not
62736363 return false unless node . predicate . parentheses?
0 commit comments