class SyntaxTree::MutationVisitor
visited. This is useful for mutating the tree before it is formatted.
This visitor walks through the tree and copies each node as it is being
def initialize
def initialize @mutations = [] end
def mutate(query, &block)
of the `copy` method on nodes to create a new node with the same
the place of the given node in the tree. These blocks frequently make use
using the given block. The block should return a new node that will take
Create a new mutation based on the given query that will mutate the node
def mutate(query, &block) mutations << [Pattern.new(query).compile, block] end
def visit(node)
a copy of the node using the visit_* methods defined below. Then it checks
This is the base visit method for each node in the tree. It first creates
def visit(node) return unless node result = node.accept(self) mutations.each do |(pattern, mutation)| result = mutation.call(result) if pattern.call(result) end result end
def visit_BEGIN(node)
def visit_BEGIN(node) node.copy( lbrace: visit(node.lbrace), statements: visit(node.statements) ) end
def visit_CHAR(node)
def visit_CHAR(node) node.copy end
def visit_END(node)
def visit_END(node) node.copy( lbrace: visit(node.lbrace), statements: visit(node.statements) ) end
def visit___end__(node)
def visit___end__(node) node.copy end
def visit_alias(node)
def visit_alias(node) node.copy(left: visit(node.left), right: visit(node.right)) end
def visit_aref(node)
def visit_aref(node) node.copy(index: visit(node.index)) end
def visit_aref_field(node)
def visit_aref_field(node) node.copy(index: visit(node.index)) end
def visit_arg_block(node)
def visit_arg_block(node) node.copy(value: visit(node.value)) end
def visit_arg_paren(node)
def visit_arg_paren(node) node.copy(arguments: visit(node.arguments)) end
def visit_arg_star(node)
def visit_arg_star(node) node.copy(value: visit(node.value)) end
def visit_args(node)
def visit_args(node) node.copy(parts: visit_all(node.parts)) end
def visit_args_forward(node)
def visit_args_forward(node) node.copy end
def visit_array(node)
def visit_array(node) node.copy( lbracket: visit(node.lbracket), contents: visit(node.contents) ) end
def visit_aryptn(node)
def visit_aryptn(node) node.copy( constant: visit(node.constant), requireds: visit_all(node.requireds), rest: visit(node.rest), posts: visit_all(node.posts) ) end
def visit_assign(node)
def visit_assign(node) node.copy(target: visit(node.target)) end
def visit_assoc(node)
def visit_assoc(node) node.copy end
def visit_assoc_splat(node)
def visit_assoc_splat(node) node.copy end
def visit_backref(node)
def visit_backref(node) node.copy end
def visit_backtick(node)
def visit_backtick(node) node.copy end
def visit_bare_assoc_hash(node)
def visit_bare_assoc_hash(node) node.copy(assocs: visit_all(node.assocs)) end
def visit_begin(node)
def visit_begin(node) node.copy(bodystmt: visit(node.bodystmt)) end
def visit_binary(node)
def visit_binary(node) node.copy end
def visit_block(node)
def visit_block(node) node.copy( opening: visit(node.opening), block_var: visit(node.block_var), bodystmt: visit(node.bodystmt) ) end
def visit_block_var(node)
def visit_block_var(node) node.copy(params: visit(node.params), locals: visit_all(node.locals)) end
def visit_blockarg(node)
def visit_blockarg(node) node.copy(name: visit(node.name)) end
def visit_bodystmt(node)
def visit_bodystmt(node) node.copy( statements: visit(node.statements), rescue_clause: visit(node.rescue_clause), else_clause: visit(node.else_clause), ensure_clause: visit(node.ensure_clause) ) end
def visit_break(node)
def visit_break(node) node.copy(arguments: visit(node.arguments)) end
def visit_call(node)
def visit_call(node) node.copy( receiver: visit(node.receiver), operator: node.operator == :"::" ? :"::" : visit(node.operator), message: node.message == :call ? :call : visit(node.message), arguments: visit(node.arguments) ) end
def visit_case(node)
def visit_case(node) node.copy( keyword: visit(node.keyword), value: visit(node.value), consequent: visit(node.consequent) ) end
def visit_class(node)
def visit_class(node) node.copy( constant: visit(node.constant), superclass: visit(node.superclass), bodystmt: visit(node.bodystmt) ) end
def visit_comma(node)
def visit_comma(node) node.copy end
def visit_command(node)
def visit_command(node) node.copy( message: visit(node.message), arguments: visit(node.arguments), block: visit(node.block) ) end
def visit_command_call(node)
def visit_command_call(node) node.copy( operator: node.operator == :"::" ? :"::" : visit(node.operator), message: visit(node.message), arguments: visit(node.arguments), block: visit(node.block) ) end
def visit_comment(node)
def visit_comment(node) node.copy end
def visit_const(node)
def visit_const(node) node.copy end
def visit_const_path_field(node)
def visit_const_path_field(node) node.copy(constant: visit(node.constant)) end
def visit_const_path_ref(node)
def visit_const_path_ref(node) node.copy(constant: visit(node.constant)) end
def visit_const_ref(node)
def visit_const_ref(node) node.copy(constant: visit(node.constant)) end
def visit_cvar(node)
def visit_cvar(node) node.copy end
def visit_def(node)
def visit_def(node) node.copy( target: visit(node.target), operator: visit(node.operator), name: visit(node.name), params: visit(node.params), bodystmt: visit(node.bodystmt) ) end
def visit_defined(node)
def visit_defined(node) node.copy end
def visit_dyna_symbol(node)
def visit_dyna_symbol(node) node.copy(parts: visit_all(node.parts)) end
def visit_else(node)
def visit_else(node) node.copy( keyword: visit(node.keyword), statements: visit(node.statements) ) end
def visit_elsif(node)
def visit_elsif(node) node.copy( statements: visit(node.statements), consequent: visit(node.consequent) ) end
def visit_embdoc(node)
def visit_embdoc(node) node.copy end
def visit_embexpr_beg(node)
def visit_embexpr_beg(node) node.copy end
def visit_embexpr_end(node)
def visit_embexpr_end(node) node.copy end
def visit_embvar(node)
def visit_embvar(node) node.copy end
def visit_ensure(node)
def visit_ensure(node) node.copy( keyword: visit(node.keyword), statements: visit(node.statements) ) end
def visit_excessed_comma(node)
def visit_excessed_comma(node) node.copy end
def visit_field(node)
def visit_field(node) node.copy( operator: node.operator == :"::" ? :"::" : visit(node.operator), name: visit(node.name) ) end
def visit_float(node)
def visit_float(node) node.copy end
def visit_fndptn(node)
def visit_fndptn(node) node.copy( constant: visit(node.constant), left: visit(node.left), values: visit_all(node.values), right: visit(node.right) ) end
def visit_for(node)
def visit_for(node) node.copy(index: visit(node.index), statements: visit(node.statements)) end
def visit_gvar(node)
def visit_gvar(node) node.copy end
def visit_hash(node)
def visit_hash(node) node.copy(lbrace: visit(node.lbrace), assocs: visit_all(node.assocs)) end
def visit_heredoc(node)
def visit_heredoc(node) node.copy( beginning: visit(node.beginning), ending: visit(node.ending), parts: visit_all(node.parts) ) end
def visit_heredoc_beg(node)
def visit_heredoc_beg(node) node.copy end
def visit_heredoc_end(node)
def visit_heredoc_end(node) node.copy end
def visit_hshptn(node)
def visit_hshptn(node) node.copy( constant: visit(node.constant), keywords: node.keywords.map { |label, value| [visit(label), visit(value)] }, keyword_rest: visit(node.keyword_rest) ) end
def visit_ident(node)
def visit_ident(node) node.copy end
def visit_if(node)
def visit_if(node) node.copy( predicate: visit(node.predicate), statements: visit(node.statements), consequent: visit(node.consequent) ) end
def visit_if_op(node)
def visit_if_op(node) node.copy end
def visit_imaginary(node)
def visit_imaginary(node) node.copy end
def visit_in(node)
def visit_in(node) node.copy( statements: visit(node.statements), consequent: visit(node.consequent) ) end
def visit_int(node)
def visit_int(node) node.copy end
def visit_ivar(node)
def visit_ivar(node) node.copy end
def visit_kw(node)
def visit_kw(node) node.copy end
def visit_kwrest_param(node)
def visit_kwrest_param(node) node.copy(name: visit(node.name)) end
def visit_label(node)
def visit_label(node) node.copy end
def visit_label_end(node)
def visit_label_end(node) node.copy end
def visit_lambda(node)
def visit_lambda(node) node.copy( params: visit(node.params), statements: visit(node.statements) ) end
def visit_lambda_var(node)
def visit_lambda_var(node) node.copy(params: visit(node.params), locals: visit_all(node.locals)) end
def visit_lbrace(node)
def visit_lbrace(node) node.copy end
def visit_lbracket(node)
def visit_lbracket(node) node.copy end
def visit_lparen(node)
def visit_lparen(node) node.copy end
def visit_massign(node)
def visit_massign(node) node.copy(target: visit(node.target)) end
def visit_method_add_block(node)
def visit_method_add_block(node) node.copy(call: visit(node.call), block: visit(node.block)) end
def visit_mlhs(node)
def visit_mlhs(node) node.copy(parts: visit_all(node.parts)) end
def visit_mlhs_paren(node)
def visit_mlhs_paren(node) node.copy(contents: visit(node.contents)) end
def visit_module(node)
def visit_module(node) node.copy( constant: visit(node.constant), bodystmt: visit(node.bodystmt) ) end
def visit_mrhs(node)
def visit_mrhs(node) node.copy(parts: visit_all(node.parts)) end
def visit_next(node)
def visit_next(node) node.copy(arguments: visit(node.arguments)) end
def visit_not(node)
def visit_not(node) node.copy(statement: visit(node.statement)) end
def visit_op(node)
def visit_op(node) node.copy end
def visit_opassign(node)
def visit_opassign(node) node.copy(target: visit(node.target), operator: visit(node.operator)) end
def visit_params(node)
def visit_params(node) node.copy( requireds: visit_all(node.requireds), optionals: node.optionals.map { |ident, value| [visit(ident), visit(value)] }, rest: visit(node.rest), posts: visit_all(node.posts), keywords: node.keywords.map { |ident, value| [visit(ident), visit(value)] }, keyword_rest: node.keyword_rest == :nil ? :nil : visit(node.keyword_rest), block: visit(node.block) ) end
def visit_paren(node)
def visit_paren(node) node.copy(lparen: visit(node.lparen), contents: visit(node.contents)) end
def visit_period(node)
def visit_period(node) node.copy end
def visit_pinned_begin(node)
def visit_pinned_begin(node) node.copy end
def visit_pinned_var_ref(node)
def visit_pinned_var_ref(node) node.copy(value: visit(node.value)) end
def visit_program(node)
def visit_program(node) node.copy(statements: visit(node.statements)) end
def visit_qsymbols(node)
def visit_qsymbols(node) node.copy( beginning: visit(node.beginning), elements: visit_all(node.elements) ) end
def visit_qsymbols_beg(node)
def visit_qsymbols_beg(node) node.copy end
def visit_qwords(node)
def visit_qwords(node) node.copy( beginning: visit(node.beginning), elements: visit_all(node.elements) ) end
def visit_qwords_beg(node)
def visit_qwords_beg(node) node.copy end
def visit_range(node)
def visit_range(node) node.copy( left: visit(node.left), operator: visit(node.operator), right: visit(node.right) ) end
def visit_rassign(node)
def visit_rassign(node) node.copy(operator: visit(node.operator)) end
def visit_rational(node)
def visit_rational(node) node.copy end
def visit_rbrace(node)
def visit_rbrace(node) node.copy end
def visit_rbracket(node)
def visit_rbracket(node) node.copy end
def visit_redo(node)
def visit_redo(node) node.copy end
def visit_regexp_beg(node)
def visit_regexp_beg(node) node.copy end
def visit_regexp_content(node)
def visit_regexp_content(node) node.copy(parts: visit_all(node.parts)) end
def visit_regexp_end(node)
def visit_regexp_end(node) node.copy end
def visit_regexp_literal(node)
def visit_regexp_literal(node) node.copy(parts: visit_all(node.parts)) end
def visit_rescue(node)
def visit_rescue(node) node.copy( keyword: visit(node.keyword), exception: visit(node.exception), statements: visit(node.statements), consequent: visit(node.consequent) ) end
def visit_rescue_ex(node)
def visit_rescue_ex(node) node.copy(variable: visit(node.variable)) end
def visit_rescue_mod(node)
def visit_rescue_mod(node) node.copy end
def visit_rest_param(node)
def visit_rest_param(node) node.copy(name: visit(node.name)) end
def visit_retry(node)
def visit_retry(node) node.copy end
def visit_return(node)
def visit_return(node) node.copy(arguments: visit(node.arguments)) end
def visit_rparen(node)
def visit_rparen(node) node.copy end
def visit_sclass(node)
def visit_sclass(node) node.copy(bodystmt: visit(node.bodystmt)) end
def visit_statements(node)
def visit_statements(node) node.copy(body: visit_all(node.body)) end
def visit_string_concat(node)
def visit_string_concat(node) node.copy(left: visit(node.left), right: visit(node.right)) end
def visit_string_content(node)
def visit_string_content(node) node.copy(parts: visit_all(node.parts)) end
def visit_string_dvar(node)
def visit_string_dvar(node) node.copy(variable: visit(node.variable)) end
def visit_string_embexpr(node)
def visit_string_embexpr(node) node.copy(statements: visit(node.statements)) end
def visit_string_literal(node)
def visit_string_literal(node) node.copy(parts: visit_all(node.parts)) end
def visit_super(node)
def visit_super(node) node.copy(arguments: visit(node.arguments)) end
def visit_symbeg(node)
def visit_symbeg(node) node.copy end
def visit_symbol_content(node)
def visit_symbol_content(node) node.copy(value: visit(node.value)) end
def visit_symbol_literal(node)
def visit_symbol_literal(node) node.copy(value: visit(node.value)) end
def visit_symbols(node)
def visit_symbols(node) node.copy( beginning: visit(node.beginning), elements: visit_all(node.elements) ) end
def visit_symbols_beg(node)
def visit_symbols_beg(node) node.copy end
def visit_tlambda(node)
def visit_tlambda(node) node.copy end
def visit_tlambeg(node)
def visit_tlambeg(node) node.copy end
def visit_top_const_field(node)
def visit_top_const_field(node) node.copy(constant: visit(node.constant)) end
def visit_top_const_ref(node)
def visit_top_const_ref(node) node.copy(constant: visit(node.constant)) end
def visit_tstring_beg(node)
def visit_tstring_beg(node) node.copy end
def visit_tstring_content(node)
def visit_tstring_content(node) node.copy end
def visit_tstring_end(node)
def visit_tstring_end(node) node.copy end
def visit_unary(node)
def visit_unary(node) node.copy end
def visit_undef(node)
def visit_undef(node) node.copy(symbols: visit_all(node.symbols)) end
def visit_unless(node)
def visit_unless(node) node.copy( predicate: visit(node.predicate), statements: visit(node.statements), consequent: visit(node.consequent) ) end
def visit_until(node)
def visit_until(node) node.copy( predicate: visit(node.predicate), statements: visit(node.statements) ) end
def visit_var_field(node)
def visit_var_field(node) node.copy(value: visit(node.value)) end
def visit_var_ref(node)
def visit_var_ref(node) node.copy(value: visit(node.value)) end
def visit_vcall(node)
def visit_vcall(node) node.copy(value: visit(node.value)) end
def visit_void_stmt(node)
def visit_void_stmt(node) node.copy end
def visit_when(node)
def visit_when(node) node.copy( arguments: visit(node.arguments), statements: visit(node.statements), consequent: visit(node.consequent) ) end
def visit_while(node)
def visit_while(node) node.copy( predicate: visit(node.predicate), statements: visit(node.statements) ) end
def visit_word(node)
def visit_word(node) node.copy(parts: visit_all(node.parts)) end
def visit_words(node)
def visit_words(node) node.copy( beginning: visit(node.beginning), elements: visit_all(node.elements) ) end
def visit_words_beg(node)
def visit_words_beg(node) node.copy end
def visit_xstring(node)
def visit_xstring(node) node.copy(parts: visit_all(node.parts)) end
def visit_xstring_literal(node)
def visit_xstring_literal(node) node.copy(parts: visit_all(node.parts)) end
def visit_yield(node)
def visit_yield(node) node.copy(arguments: visit(node.arguments)) end
def visit_zsuper(node)
def visit_zsuper(node) node.copy end