class Unparser::Writer::DynamicString

Constants

FLAT_INTERPOLATION
PATTERNS_2
PATTERNS_3

Public Instance Methods

dispatch() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 32
def dispatch
  if heredoc?
    emit_heredoc_header
  else
    emit_dstr
  end
end
emit_heredoc_reminder() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 25
def emit_heredoc_reminder
  return unless heredoc?

  emit_heredoc_body
  emit_heredoc_footer
end

Private Instance Methods

breakpoint?(child, current) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 171
def breakpoint?(child, current)
  last_type = current.last&.type

  [
    n_str?(child) && last_type.equal?(:str) && current.none?(&method(:n_begin?)),
    last_type.equal?(:dstr),
    n_dstr?(child) && last_type
  ].any?
end
classify(node) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 63
def classify(node)
  if n_str?(node)
    classify_str(node)
  else
    node.type
  end
end
classify_str(node) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 71
def classify_str(node)
  if str_nl?(node)
    :str_nl
  elsif node.children.first.end_with?("\n")
    :str_nl_eol
  elsif str_ws?(node)
    :str_ws
  elsif str_empty?(node)
    :str_empty
  end
end
emit_body(children) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 205
def emit_body(children)
  buffer.root_indent do
    children.each_with_index do |child, index|
      if n_str?(child)
        string = child.children.first
        if string.eql?("\n") && children.fetch(index.pred).type.equal?(:begin)
          write("\n")
        else
          write(string.inspect[1..-2])
        end
      else
        emit_dynamic(child)
      end
    end
  end
end
emit_dstr() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 161
def emit_dstr
  if children.empty?
    write('%()')
  else
    segments.each_with_index do |children, index|
      emit_segment(children, index)
    end
  end
end
emit_dynamic(child) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 144
def emit_dynamic(child)
  if FLAT_INTERPOLATION.include?(child.type)
    write('#')
    visit(child)
  elsif n_dstr?(child)
    emit_body(child.children)
  else
    write('#{')
    emit_dynamic_component(child.children.first)
    write('}')
  end
end
emit_dynamic_component(node) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 157
def emit_dynamic_component(node)
  visit(node) if node
end
emit_heredoc_body() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 54
def emit_heredoc_body
  nl
  emit_normal_heredoc_body
end
emit_heredoc_header() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 50
def emit_heredoc_header
  write(heredoc_header)
end
emit_normal_heredoc_body() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 128
def emit_normal_heredoc_body
  buffer.root_indent do
    children.each do |child|
      if n_str?(child)
        write(escape_dynamic(child.children.first))
      else
        emit_dynamic(child)
      end
    end
  end
end
emit_segment(children, index) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 197
def emit_segment(children, index)
  write(' ') unless index.zero?

  write('"')
  emit_body(children)
  write('"')
end
emit_squiggly_heredoc_body() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 116
def emit_squiggly_heredoc_body
  buffer.indent
  children.each do |child|
    if n_str?(child)
      write(escape_dynamic(child.children.first))
    else
      emit_dynamic(child)
    end
  end
  buffer.unindent
end
escape_dynamic(string) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 140
def escape_dynamic(string)
  string.gsub('#', '\#')
end
heredoc?() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 46
def heredoc?
  !children.empty? && (nl_last_child? && heredoc_pattern?)
end
heredoc_header() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 42
def heredoc_header
  '<<-HEREDOC'
end
heredoc_pattern?() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 95
def heredoc_pattern?
  heredoc_pattern_2? || heredoc_pattern_3?
end
heredoc_pattern_2?() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 105
def heredoc_pattern_2?
  children.each_cons(2).any? do |group|
    PATTERNS_2.include?(group.map(&method(:classify)))
  end
end
heredoc_pattern_3?() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 99
def heredoc_pattern_3?
  children.each_cons(3).any? do |group|
    PATTERNS_3.include?(group.map(&method(:classify)))
  end
end
nl_last_child?() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 111
def nl_last_child?
  last = children.last
  n_str?(last) && last.children.first[-1].eql?("\n")
end
segments() click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 181
def segments
  segments = []

  segments << current = []

  children.each do |child|
    if breakpoint?(child, current)
      segments << current = []
    end

    current << child
  end

  segments
end
str_empty?(node) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 87
def str_empty?(node)
  node.eql?(s(:str, ''))
end
str_nl?(node) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 83
def str_nl?(node)
  node.eql?(s(:str, "\n"))
end
str_ws?(node) click to toggle source
# File lib/unparser/writer/dynamic_string.rb, line 91
def str_ws?(node)
  /\A( |\t)+\z/.match?(node.children.first)
end