class SyntaxTree::Formatter

A slightly enhanced PP that knows how to format recursively including comments.

Constants

COMMENT_PRIORITY
DISABLE_AUTO_TERNARY
HEREDOC_PRIORITY
SINGLE_QUOTES
TRAILING_COMMA

Attributes

disable_auto_ternary[R]

These options are overridden in plugins to we need to make sure they are available here.

disable_auto_ternary?[R]

These options are overridden in plugins to we need to make sure they are available here.

quote[R]

These options are overridden in plugins to we need to make sure they are available here.

source[R]
stack[R]
target_ruby_version[R]

These options are overridden in plugins to we need to make sure they are available here.

trailing_comma[R]

These options are overridden in plugins to we need to make sure they are available here.

trailing_comma?[R]

These options are overridden in plugins to we need to make sure they are available here.

Public Class Methods

format(source, node, base_indentation = 0) click to toggle source
# File lib/syntax_tree/formatter.rb, line 108
def self.format(source, node, base_indentation = 0)
  q = new(source, [])
  q.format(node)
  q.flush(base_indentation)
  q.output.join
end
new(source, *args, options: Options.new) click to toggle source
Calls superclass method
# File lib/syntax_tree/formatter.rb, line 95
def initialize(source, *args, options: Options.new)
  super(*args)

  @source = source
  @stack = []

  # Memoizing these values to make access faster.
  @quote = options.quote
  @trailing_comma = options.trailing_comma
  @disable_auto_ternary = options.disable_auto_ternary
  @target_ruby_version = options.target_ruby_version
end

Public Instance Methods

format(node, stackable: true) click to toggle source
# File lib/syntax_tree/formatter.rb, line 115
def format(node, stackable: true)
  stack << node if stackable
  doc = nil

  # If there are comments, then we're going to format them around the node
  # so that they get printed properly.
  if node.comments.any?
    trailing = []
    last_leading = nil

    # First, we're going to print all of the comments that were found before
    # the node. We'll also gather up any trailing comments that we find.
    node.comments.each do |comment|
      if comment.leading?
        comment.format(self)
        breakable(force: true)
        last_leading = comment
      else
        trailing << comment
      end
    end

    # If the node has a stree-ignore comment right before it, then we're
    # going to just print out the node as it was seen in the source.
    doc =
      if last_leading&.ignore?
        range = source[node.start_char...node.end_char]
        first = true

        range.each_line(chomp: true) do |line|
          if first
            first = false
          else
            breakable_return
          end

          text(line)
        end

        breakable_return if range.end_with?("\n")
      else
        node.format(self)
      end

    # Print all comments that were found after the node.
    trailing.each do |comment|
      line_suffix(priority: COMMENT_PRIORITY) do
        comment.inline? ? text(" ") : breakable
        comment.format(self)
        break_parent
      end
    end
  else
    doc = node.format(self)
  end

  stack.pop if stackable
  doc
end
format_each(nodes) click to toggle source
# File lib/syntax_tree/formatter.rb, line 175
def format_each(nodes)
  nodes.each { |node| format(node) }
end
grandparent() click to toggle source
# File lib/syntax_tree/formatter.rb, line 179
def grandparent
  stack[-3]
end
group() { || ... } click to toggle source

This is a simplified version of prettyprint’s group. It doesn’t provide any of the more advanced options because we don’t need them and they take up expensive computation time.

# File lib/syntax_tree/formatter.rb, line 194
def group
  contents = []
  doc = Group.new(0, contents: contents)

  groups << doc
  target << doc

  with_target(contents) { yield }
  groups.pop
  doc
end
parent() click to toggle source
# File lib/syntax_tree/formatter.rb, line 183
def parent
  stack[-2]
end
parents() click to toggle source
# File lib/syntax_tree/formatter.rb, line 187
def parents
  stack[0...-1].reverse_each
end
seplist(list, sep = nil, iter_method = :each) { |*v| ... } click to toggle source

A similar version to the super, except that it calls back into the separator proc with the instance of ‘self`.

# File lib/syntax_tree/formatter.rb, line 208
def seplist(list, sep = nil, iter_method = :each)
  first = true
  list.__send__(iter_method) do |*v|
    if first
      first = false
    elsif sep
      sep.call(self)
    else
      comma_breakable
    end
    yield(*v)
  end
end
text(string) click to toggle source

This is a much simplified version of prettyprint’s text. It avoids calculating width by pushing the string directly onto the target.

# File lib/syntax_tree/formatter.rb, line 224
def text(string)
  target << string
end