class SyntaxTree::FlowControlFormatter

Formats either a Break, Next, or Return node.

Attributes

keyword[R]
String

the keyword to print

node[R]
Break | Next | Return

the node being formatted

Public Class Methods

new(keyword, node) click to toggle source
# File lib/syntax_tree/node.rb, line 2445
def initialize(keyword, node)
  @keyword = keyword
  @node = node
end

Public Instance Methods

format(q) click to toggle source
# File lib/syntax_tree/node.rb, line 2450
def format(q)
  # If there are no arguments associated with this flow control, then we can
  # safely just print the keyword and return.
  if node.arguments.nil?
    q.text(keyword)
    return
  end

  q.group do
    q.text(keyword)

    parts = node.arguments.parts
    length = parts.length

    if length == 0
      # Here there are no arguments at all, so we're not going to print
      # anything. This would be like if we had:
      #
      #     break
      #
    elsif length >= 2
      # If there are multiple arguments, format them all. If the line is
      # going to break into multiple, then use brackets to start and end the
      # expression.
      format_arguments(q, " [", "]")
    else
      # If we get here, then we're formatting a single argument to the flow
      # control keyword.
      part = parts.first

      case part
      when Paren
        statements = part.contents.body

        if statements.length == 1
          statement = statements.first

          if statement.is_a?(ArrayLiteral)
            contents = statement.contents

            if contents && contents.parts.length >= 2
              # Here we have a single argument that is a set of parentheses
              # wrapping an array literal that has at least 2 elements.
              # We're going to print the contents of the array directly.
              # This would be like if we had:
              #
              #     break([1, 2, 3])
              #
              # which we will print as:
              #
              #     break 1, 2, 3
              #
              q.text(" ")
              format_array_contents(q, statement)
            else
              # Here we have a single argument that is a set of parentheses
              # wrapping an array literal that has 0 or 1 elements. We're
              # going to skip the parentheses but print the array itself.
              # This would be like if we had:
              #
              #     break([1])
              #
              # which we will print as:
              #
              #     break [1]
              #
              q.text(" ")
              q.format(statement)
            end
          elsif skip_parens?(statement)
            # Here we have a single argument that is a set of parentheses
            # that themselves contain a single statement. That statement is
            # a simple value that we can skip the parentheses for. This
            # would be like if we had:
            #
            #     break(1)
            #
            # which we will print as:
            #
            #     break 1
            #
            q.text(" ")
            q.format(statement)
          else
            # Here we have a single argument that is a set of parentheses.
            # We're going to print the parentheses themselves as if they
            # were the set of arguments. This would be like if we had:
            #
            #     break(foo.bar)
            #
            q.format(part)
          end
        else
          q.format(part)
        end
      when ArrayLiteral
        contents = part.contents

        if contents && contents.parts.length >= 2
          # Here there is a single argument that is an array literal with at
          # least two elements. We skip directly into the array literal's
          # elements in order to print the contents. This would be like if
          # we had:
          #
          #     break [1, 2, 3]
          #
          # which we will print as:
          #
          #     break 1, 2, 3
          #
          q.text(" ")
          format_array_contents(q, part)
        else
          # Here there is a single argument that is an array literal with 0
          # or 1 elements. In this case we're going to print the array as it
          # is because skipping the brackets would change the remaining.
          # This would be like if we had:
          #
          #     break []
          #     break [1]
          #
          q.text(" ")
          q.format(part)
        end
      else
        # Here there is a single argument that hasn't matched one of our
        # previous cases. We're going to print the argument as it is. This
        # would be like if we had:
        #
        #     break foo
        #
        format_arguments(q, "(", ")")
      end
    end
  end
end