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)

properties as the original node.
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)

each mutation in sequence and calls it if it finds a match.
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)

Visit a BEGINBlock node.
def visit_BEGIN(node)
  node.copy(
    lbrace: visit(node.lbrace),
    statements: visit(node.statements)
  )
end

def visit_CHAR(node)

Visit a CHAR node.
def visit_CHAR(node)
  node.copy
end

def visit_END(node)

Visit a ENDBlock node.
def visit_END(node)
  node.copy(
    lbrace: visit(node.lbrace),
    statements: visit(node.statements)
  )
end

def visit___end__(node)

Visit a EndContent node.
def visit___end__(node)
  node.copy
end

def visit_alias(node)

Visit a AliasNode node.
def visit_alias(node)
  node.copy(left: visit(node.left), right: visit(node.right))
end

def visit_aref(node)

Visit a ARef node.
def visit_aref(node)
  node.copy(index: visit(node.index))
end

def visit_aref_field(node)

Visit a ARefField node.
def visit_aref_field(node)
  node.copy(index: visit(node.index))
end

def visit_arg_block(node)

Visit a ArgBlock node.
def visit_arg_block(node)
  node.copy(value: visit(node.value))
end

def visit_arg_paren(node)

Visit a ArgParen node.
def visit_arg_paren(node)
  node.copy(arguments: visit(node.arguments))
end

def visit_arg_star(node)

Visit a ArgStar node.
def visit_arg_star(node)
  node.copy(value: visit(node.value))
end

def visit_args(node)

Visit a Args node.
def visit_args(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_args_forward(node)

Visit a ArgsForward node.
def visit_args_forward(node)
  node.copy
end

def visit_array(node)

Visit a ArrayLiteral node.
def visit_array(node)
  node.copy(
    lbracket: visit(node.lbracket),
    contents: visit(node.contents)
  )
end

def visit_aryptn(node)

Visit a 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)

Visit a Assign node.
def visit_assign(node)
  node.copy(target: visit(node.target))
end

def visit_assoc(node)

Visit a Assoc node.
def visit_assoc(node)
  node.copy
end

def visit_assoc_splat(node)

Visit a AssocSplat node.
def visit_assoc_splat(node)
  node.copy
end

def visit_backref(node)

Visit a Backref node.
def visit_backref(node)
  node.copy
end

def visit_backtick(node)

Visit a Backtick node.
def visit_backtick(node)
  node.copy
end

def visit_bare_assoc_hash(node)

Visit a BareAssocHash node.
def visit_bare_assoc_hash(node)
  node.copy(assocs: visit_all(node.assocs))
end

def visit_begin(node)

Visit a Begin node.
def visit_begin(node)
  node.copy(bodystmt: visit(node.bodystmt))
end

def visit_binary(node)

Visit a Binary node.
def visit_binary(node)
  node.copy
end

def visit_block(node)

Visit a 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)

Visit a BlockVar node.
def visit_block_var(node)
  node.copy(params: visit(node.params), locals: visit_all(node.locals))
end

def visit_blockarg(node)

Visit a BlockArg node.
def visit_blockarg(node)
  node.copy(name: visit(node.name))
end

def visit_bodystmt(node)

Visit a 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)

Visit a Break node.
def visit_break(node)
  node.copy(arguments: visit(node.arguments))
end

def visit_call(node)

Visit a 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)

Visit a 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)

Visit a ClassDeclaration node.
def visit_class(node)
  node.copy(
    constant: visit(node.constant),
    superclass: visit(node.superclass),
    bodystmt: visit(node.bodystmt)
  )
end

def visit_comma(node)

Visit a Comma node.
def visit_comma(node)
  node.copy
end

def visit_command(node)

Visit a 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)

Visit a CommandCall 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)

Visit a Comment node.
def visit_comment(node)
  node.copy
end

def visit_const(node)

Visit a Const node.
def visit_const(node)
  node.copy
end

def visit_const_path_field(node)

Visit a ConstPathField node.
def visit_const_path_field(node)
  node.copy(constant: visit(node.constant))
end

def visit_const_path_ref(node)

Visit a ConstPathRef node.
def visit_const_path_ref(node)
  node.copy(constant: visit(node.constant))
end

def visit_const_ref(node)

Visit a ConstRef node.
def visit_const_ref(node)
  node.copy(constant: visit(node.constant))
end

def visit_cvar(node)

Visit a CVar node.
def visit_cvar(node)
  node.copy
end

def visit_def(node)

Visit a 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)

Visit a Defined node.
def visit_defined(node)
  node.copy
end

def visit_dyna_symbol(node)

Visit a DynaSymbol node.
def visit_dyna_symbol(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_else(node)

Visit a Else node.
def visit_else(node)
  node.copy(
    keyword: visit(node.keyword),
    statements: visit(node.statements)
  )
end

def visit_elsif(node)

Visit a Elsif node.
def visit_elsif(node)
  node.copy(
    statements: visit(node.statements),
    consequent: visit(node.consequent)
  )
end

def visit_embdoc(node)

Visit a EmbDoc node.
def visit_embdoc(node)
  node.copy
end

def visit_embexpr_beg(node)

Visit a EmbExprBeg node.
def visit_embexpr_beg(node)
  node.copy
end

def visit_embexpr_end(node)

Visit a EmbExprEnd node.
def visit_embexpr_end(node)
  node.copy
end

def visit_embvar(node)

Visit a EmbVar node.
def visit_embvar(node)
  node.copy
end

def visit_ensure(node)

Visit a Ensure node.
def visit_ensure(node)
  node.copy(
    keyword: visit(node.keyword),
    statements: visit(node.statements)
  )
end

def visit_excessed_comma(node)

Visit a ExcessedComma node.
def visit_excessed_comma(node)
  node.copy
end

def visit_field(node)

Visit a Field node.
def visit_field(node)
  node.copy(
    operator: node.operator == :"::" ? :"::" : visit(node.operator),
    name: visit(node.name)
  )
end

def visit_float(node)

Visit a FloatLiteral node.
def visit_float(node)
  node.copy
end

def visit_fndptn(node)

Visit a 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)

Visit a For node.
def visit_for(node)
  node.copy(index: visit(node.index), statements: visit(node.statements))
end

def visit_gvar(node)

Visit a GVar node.
def visit_gvar(node)
  node.copy
end

def visit_hash(node)

Visit a HashLiteral node.
def visit_hash(node)
  node.copy(lbrace: visit(node.lbrace), assocs: visit_all(node.assocs))
end

def visit_heredoc(node)

Visit a 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)

Visit a HeredocBeg node.
def visit_heredoc_beg(node)
  node.copy
end

def visit_heredoc_end(node)

Visit a HeredocEnd node.
def visit_heredoc_end(node)
  node.copy
end

def visit_hshptn(node)

Visit a 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)

Visit a Ident node.
def visit_ident(node)
  node.copy
end

def visit_if(node)

Visit a IfNode 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)

Visit a IfOp node.
def visit_if_op(node)
  node.copy
end

def visit_imaginary(node)

Visit a Imaginary node.
def visit_imaginary(node)
  node.copy
end

def visit_in(node)

Visit a In node.
def visit_in(node)
  node.copy(
    statements: visit(node.statements),
    consequent: visit(node.consequent)
  )
end

def visit_int(node)

Visit a Int node.
def visit_int(node)
  node.copy
end

def visit_ivar(node)

Visit a IVar node.
def visit_ivar(node)
  node.copy
end

def visit_kw(node)

Visit a Kw node.
def visit_kw(node)
  node.copy
end

def visit_kwrest_param(node)

Visit a KwRestParam node.
def visit_kwrest_param(node)
  node.copy(name: visit(node.name))
end

def visit_label(node)

Visit a Label node.
def visit_label(node)
  node.copy
end

def visit_label_end(node)

Visit a LabelEnd node.
def visit_label_end(node)
  node.copy
end

def visit_lambda(node)

Visit a Lambda node.
def visit_lambda(node)
  node.copy(
    params: visit(node.params),
    statements: visit(node.statements)
  )
end

def visit_lambda_var(node)

Visit a LambdaVar node.
def visit_lambda_var(node)
  node.copy(params: visit(node.params), locals: visit_all(node.locals))
end

def visit_lbrace(node)

Visit a LBrace node.
def visit_lbrace(node)
  node.copy
end

def visit_lbracket(node)

Visit a LBracket node.
def visit_lbracket(node)
  node.copy
end

def visit_lparen(node)

Visit a LParen node.
def visit_lparen(node)
  node.copy
end

def visit_massign(node)

Visit a MAssign node.
def visit_massign(node)
  node.copy(target: visit(node.target))
end

def visit_method_add_block(node)

Visit a MethodAddBlock node.
def visit_method_add_block(node)
  node.copy(call: visit(node.call), block: visit(node.block))
end

def visit_mlhs(node)

Visit a MLHS node.
def visit_mlhs(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_mlhs_paren(node)

Visit a MLHSParen node.
def visit_mlhs_paren(node)
  node.copy(contents: visit(node.contents))
end

def visit_module(node)

Visit a ModuleDeclaration node.
def visit_module(node)
  node.copy(
    constant: visit(node.constant),
    bodystmt: visit(node.bodystmt)
  )
end

def visit_mrhs(node)

Visit a MRHS node.
def visit_mrhs(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_next(node)

Visit a Next node.
def visit_next(node)
  node.copy(arguments: visit(node.arguments))
end

def visit_not(node)

Visit a Not node.
def visit_not(node)
  node.copy(statement: visit(node.statement))
end

def visit_op(node)

Visit a Op node.
def visit_op(node)
  node.copy
end

def visit_opassign(node)

Visit a OpAssign node.
def visit_opassign(node)
  node.copy(target: visit(node.target), operator: visit(node.operator))
end

def visit_params(node)

Visit a 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)

Visit a Paren node.
def visit_paren(node)
  node.copy(lparen: visit(node.lparen), contents: visit(node.contents))
end

def visit_period(node)

Visit a Period node.
def visit_period(node)
  node.copy
end

def visit_pinned_begin(node)

Visit a PinnedBegin node.
def visit_pinned_begin(node)
  node.copy
end

def visit_pinned_var_ref(node)

Visit a PinnedVarRef node.
def visit_pinned_var_ref(node)
  node.copy(value: visit(node.value))
end

def visit_program(node)

Visit a Program node.
def visit_program(node)
  node.copy(statements: visit(node.statements))
end

def visit_qsymbols(node)

Visit a QSymbols node.
def visit_qsymbols(node)
  node.copy(
    beginning: visit(node.beginning),
    elements: visit_all(node.elements)
  )
end

def visit_qsymbols_beg(node)

Visit a QSymbolsBeg node.
def visit_qsymbols_beg(node)
  node.copy
end

def visit_qwords(node)

Visit a QWords node.
def visit_qwords(node)
  node.copy(
    beginning: visit(node.beginning),
    elements: visit_all(node.elements)
  )
end

def visit_qwords_beg(node)

Visit a QWordsBeg node.
def visit_qwords_beg(node)
  node.copy
end

def visit_range(node)

Visit a RangeNode node.
def visit_range(node)
  node.copy(
    left: visit(node.left),
    operator: visit(node.operator),
    right: visit(node.right)
  )
end

def visit_rassign(node)

Visit a RAssign node.
def visit_rassign(node)
  node.copy(operator: visit(node.operator))
end

def visit_rational(node)

Visit a RationalLiteral node.
def visit_rational(node)
  node.copy
end

def visit_rbrace(node)

Visit a RBrace node.
def visit_rbrace(node)
  node.copy
end

def visit_rbracket(node)

Visit a RBracket node.
def visit_rbracket(node)
  node.copy
end

def visit_redo(node)

Visit a Redo node.
def visit_redo(node)
  node.copy
end

def visit_regexp_beg(node)

Visit a RegexpBeg node.
def visit_regexp_beg(node)
  node.copy
end

def visit_regexp_content(node)

Visit a RegexpContent node.
def visit_regexp_content(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_regexp_end(node)

Visit a RegexpEnd node.
def visit_regexp_end(node)
  node.copy
end

def visit_regexp_literal(node)

Visit a RegexpLiteral node.
def visit_regexp_literal(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_rescue(node)

Visit a 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)

Visit a RescueEx node.
def visit_rescue_ex(node)
  node.copy(variable: visit(node.variable))
end

def visit_rescue_mod(node)

Visit a RescueMod node.
def visit_rescue_mod(node)
  node.copy
end

def visit_rest_param(node)

Visit a RestParam node.
def visit_rest_param(node)
  node.copy(name: visit(node.name))
end

def visit_retry(node)

Visit a Retry node.
def visit_retry(node)
  node.copy
end

def visit_return(node)

Visit a Return node.
def visit_return(node)
  node.copy(arguments: visit(node.arguments))
end

def visit_rparen(node)

Visit a RParen node.
def visit_rparen(node)
  node.copy
end

def visit_sclass(node)

Visit a SClass node.
def visit_sclass(node)
  node.copy(bodystmt: visit(node.bodystmt))
end

def visit_statements(node)

Visit a Statements node.
def visit_statements(node)
  node.copy(body: visit_all(node.body))
end

def visit_string_concat(node)

Visit a StringConcat node.
def visit_string_concat(node)
  node.copy(left: visit(node.left), right: visit(node.right))
end

def visit_string_content(node)

Visit a StringContent node.
def visit_string_content(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_string_dvar(node)

Visit a StringDVar node.
def visit_string_dvar(node)
  node.copy(variable: visit(node.variable))
end

def visit_string_embexpr(node)

Visit a StringEmbExpr node.
def visit_string_embexpr(node)
  node.copy(statements: visit(node.statements))
end

def visit_string_literal(node)

Visit a StringLiteral node.
def visit_string_literal(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_super(node)

Visit a Super node.
def visit_super(node)
  node.copy(arguments: visit(node.arguments))
end

def visit_symbeg(node)

Visit a SymBeg node.
def visit_symbeg(node)
  node.copy
end

def visit_symbol_content(node)

Visit a SymbolContent node.
def visit_symbol_content(node)
  node.copy(value: visit(node.value))
end

def visit_symbol_literal(node)

Visit a SymbolLiteral node.
def visit_symbol_literal(node)
  node.copy(value: visit(node.value))
end

def visit_symbols(node)

Visit a Symbols node.
def visit_symbols(node)
  node.copy(
    beginning: visit(node.beginning),
    elements: visit_all(node.elements)
  )
end

def visit_symbols_beg(node)

Visit a SymbolsBeg node.
def visit_symbols_beg(node)
  node.copy
end

def visit_tlambda(node)

Visit a TLambda node.
def visit_tlambda(node)
  node.copy
end

def visit_tlambeg(node)

Visit a TLamBeg node.
def visit_tlambeg(node)
  node.copy
end

def visit_top_const_field(node)

Visit a TopConstField node.
def visit_top_const_field(node)
  node.copy(constant: visit(node.constant))
end

def visit_top_const_ref(node)

Visit a TopConstRef node.
def visit_top_const_ref(node)
  node.copy(constant: visit(node.constant))
end

def visit_tstring_beg(node)

Visit a TStringBeg node.
def visit_tstring_beg(node)
  node.copy
end

def visit_tstring_content(node)

Visit a TStringContent node.
def visit_tstring_content(node)
  node.copy
end

def visit_tstring_end(node)

Visit a TStringEnd node.
def visit_tstring_end(node)
  node.copy
end

def visit_unary(node)

Visit a Unary node.
def visit_unary(node)
  node.copy
end

def visit_undef(node)

Visit a Undef node.
def visit_undef(node)
  node.copy(symbols: visit_all(node.symbols))
end

def visit_unless(node)

Visit a UnlessNode node.
def visit_unless(node)
  node.copy(
    predicate: visit(node.predicate),
    statements: visit(node.statements),
    consequent: visit(node.consequent)
  )
end

def visit_until(node)

Visit a UntilNode node.
def visit_until(node)
  node.copy(
    predicate: visit(node.predicate),
    statements: visit(node.statements)
  )
end

def visit_var_field(node)

Visit a VarField node.
def visit_var_field(node)
  node.copy(value: visit(node.value))
end

def visit_var_ref(node)

Visit a VarRef node.
def visit_var_ref(node)
  node.copy(value: visit(node.value))
end

def visit_vcall(node)

Visit a VCall node.
def visit_vcall(node)
  node.copy(value: visit(node.value))
end

def visit_void_stmt(node)

Visit a VoidStmt node.
def visit_void_stmt(node)
  node.copy
end

def visit_when(node)

Visit a 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)

Visit a WhileNode node.
def visit_while(node)
  node.copy(
    predicate: visit(node.predicate),
    statements: visit(node.statements)
  )
end

def visit_word(node)

Visit a Word node.
def visit_word(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_words(node)

Visit a Words node.
def visit_words(node)
  node.copy(
    beginning: visit(node.beginning),
    elements: visit_all(node.elements)
  )
end

def visit_words_beg(node)

Visit a WordsBeg node.
def visit_words_beg(node)
  node.copy
end

def visit_xstring(node)

Visit a XString node.
def visit_xstring(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_xstring_literal(node)

Visit a XStringLiteral node.
def visit_xstring_literal(node)
  node.copy(parts: visit_all(node.parts))
end

def visit_yield(node)

Visit a YieldNode node.
def visit_yield(node)
  node.copy(arguments: visit(node.arguments))
end

def visit_zsuper(node)

Visit a ZSuper node.
def visit_zsuper(node)
  node.copy
end