class Parser::Rewriter
{Parser::Rewriter} offers a basic API that makes it easy to rewrite existing ASTs. It's built on top of {Parser::AST::Processor} and {Parser::Source::Rewriter}.
For example, assume you want to remove `do` tokens from a while statement. You can do this as following:
require 'parser/current' class RemoveDo < Parser::Rewriter def on_while(node) # Check if the statement starts with "do" if node.location.begin.is?('do') remove(node.location.begin) end end end code = <<-EOF while true do puts 'hello' end EOF buffer = Parser::Source::Buffer.new('(example)') buffer.source = code parser = Parser::CurrentRuby.new ast = parser.parse(buffer) rewriter = RemoveDo.new # Rewrite the AST, returns a String with the new form. puts rewriter.rewrite(buffer, ast)
This would result in the following Ruby code:
while true puts 'hello' end
Keep in mind that {Parser::Rewriter} does not take care of indentation when inserting/replacing code so you'll have to do this yourself.
See also [a blog entry](whitequark.org/blog/2013/04/26/lets-play-with-ruby-code/) describing rewriters in greater detail.
@api public
Public Instance Methods
Returns `true` if the specified node is an assignment node, returns false otherwise.
@param [Parser::AST::Node] node @return [Boolean]
# File lib/parser/rewriter.rb, line 75 def assignment?(node) [:lvasgn, :ivasgn, :gvasgn, :cvasgn, :casgn].include?(node.type) end
Inserts new code after the given source range.
@param [Parser::Source::Range] range @param [String] content
# File lib/parser/rewriter.rb, line 104 def insert_after(range, content) @source_rewriter.insert_after(range, content) end
Inserts new code before the given source range.
@param [Parser::Source::Range] range @param [String] content
# File lib/parser/rewriter.rb, line 94 def insert_before(range, content) @source_rewriter.insert_before(range, content) end
Removes the source range.
@param [Parser::Source::Range] range
# File lib/parser/rewriter.rb, line 84 def remove(range) @source_rewriter.remove(range) end
Replaces the code of the source range `range` with `content`.
@param [Parser::Source::Range] range @param [String] content
# File lib/parser/rewriter.rb, line 114 def replace(range, content) @source_rewriter.replace(range, content) end
Rewrites the AST/source buffer and returns a String
containing the new version.
@param [Parser::Source::Buffer] source_buffer @param [Parser::AST::Node] ast @return [String]
# File lib/parser/rewriter.rb, line 60 def rewrite(source_buffer, ast) @source_rewriter = Source::Rewriter.new(source_buffer) process(ast) @source_rewriter.process end