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
These options are overridden in plugins to we need to make sure they are available here.
These options are overridden in plugins to we need to make sure they are available here.
These options are overridden in plugins to we need to make sure they are available here.
These options are overridden in plugins to we need to make sure they are available here.
These options are overridden in plugins to we need to make sure they are available here.
These options are overridden in plugins to we need to make sure they are available here.
Public Class Methods
# 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
# 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
# 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
# File lib/syntax_tree/formatter.rb, line 175 def format_each(nodes) nodes.each { |node| format(node) } end
# File lib/syntax_tree/formatter.rb, line 179 def grandparent stack[-3] end
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
# File lib/syntax_tree/formatter.rb, line 183 def parent stack[-2] end
# File lib/syntax_tree/formatter.rb, line 187 def parents stack[0...-1].reverse_each end
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
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