class EagerRewriter

Rewrite Zombies with their idiomatic replacements

Constants

Arg
BUILTINS
INFIX
OPS

Attributes

rules[R]

Public Class Methods

r(**kwargs) click to toggle source
# File lib/zombie_killer/eager_rewriter.rb, line 27
def self.r(**kwargs)
  rule = Rule.new(**kwargs)
  type = rule.from.type
  @rules[type] ||= []
  @rules[type] << rule
end
s(name, *children) click to toggle source
# File lib/zombie_killer/eager_rewriter.rb, line 10
def self.s(name, *children)
  Parser::AST::Node.new(name, children)
end
sformat_replacement1(format_literal, value) click to toggle source
# File lib/zombie_killer/eager_rewriter.rb, line 90
def self.sformat_replacement1(format_literal, value)
  verbatims = format_literal.split("%1", -1)
  return nil unless verbatims.size == 2
  s(:dstr, s(:str, verbatims[0]), value, s(:str, verbatims[1]))
end

Public Instance Methods

process(node) click to toggle source
Calls superclass method
# File lib/zombie_killer/eager_rewriter.rb, line 129
def process(node)
  node = super(node)
  return if node.nil?
  trules = self.class.rules.fetch(node.type, [])
  trules.find do |r|
    replacement = r.match(node)
    node = replace_node(node, replacement) if replacement
  end
  node
end
replace_node(old_node, new_node) click to toggle source
# File lib/zombie_killer/eager_rewriter.rb, line 118
def replace_node(old_node, new_node)
  # puts "OLD #{old_node.inspect}"
  # puts "NEW #{new_node.inspect}"
  source_range = old_node.loc.expression
  unp = Unparser.unparse(new_node)
  unp = unparser_sanitize(unp)
  # puts "UNP #{unp.inspect}"
  replace(source_range, unp)
  new_node
end
s(name, *children) click to toggle source
# File lib/zombie_killer/eager_rewriter.rb, line 14
def s(name, *children)
  self.class.s(name, *children)
end
unparser_sanitize(code_s) click to toggle source

Does not improve readability much, fails on nil. Use foo&.each ? r from: s(:send, BUILTINS, :foreach, Arg),

to:   ->(a) { s(:send, a, :each) }
# File lib/zombie_killer/eager_rewriter.rb, line 103
def unparser_sanitize(code_s)
  # unparser converts "foo#{bar}baz"
  # into "#{"foo"}#{bar}#{"baz"}"
  # so this undoes the escaping of the litetrals
  code_s.gsub(/
                \#
                \{"
                (
                [^"#]*
                )
                "\}
              /x,
              '\1')
end