class Parser::TreeRewriter
{Parser::TreeRewriter} offers a basic API that makes it easy to rewrite existing ASTs. It’s built on top of {Parser::AST::Processor} and {Parser::Source::TreeRewriter}
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::TreeRewriter 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 ast = Parser::CurrentRuby.parse code buffer = Parser::Source::Buffer.new('(example)', source: code) 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::TreeRewriter} 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/tree_rewriter.rb, line 79 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/tree_rewriter.rb, line 118 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/tree_rewriter.rb, line 108 def insert_before(range, content) @source_rewriter.insert_before(range, content) end
Removes the source range.
@param [Parser::Source::Range] range
# File lib/parser/tree_rewriter.rb, line 88 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/tree_rewriter.rb, line 128 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 @param [Symbol] crossing_deletions:, different_replacements:, swallowed_insertions:
policy arguments for TreeRewriter (optional)
@return [String]
# File lib/parser/tree_rewriter.rb, line 62 def rewrite(source_buffer, ast, **policy) @source_rewriter = Parser::Source::TreeRewriter.new(source_buffer, **policy) process(ast) @source_rewriter.process end
Wraps the given source range with the given values.
@param [Parser::Source::Range] range @param [String] content
# File lib/parser/tree_rewriter.rb, line 98 def wrap(range, before, after) @source_rewriter.wrap(range, before, after) end