2012-12-06 15:30:28 -05:00
|
|
|
module Mutant
|
|
|
|
# Generator for mutations
|
|
|
|
class Mutator
|
|
|
|
# Abstract base class for node mutators
|
|
|
|
class Node < self
|
|
|
|
include AbstractType
|
|
|
|
|
2012-12-10 18:17:19 -05:00
|
|
|
# Return identity of node
|
2012-12-06 15:30:28 -05:00
|
|
|
#
|
2012-12-10 18:17:19 -05:00
|
|
|
# @param [Rubinius::AST::Node] node
|
2012-12-06 15:30:28 -05:00
|
|
|
#
|
2012-12-10 18:17:19 -05:00
|
|
|
# @return [String]
|
2012-12-06 15:30:28 -05:00
|
|
|
#
|
2012-12-12 16:31:14 -05:00
|
|
|
# @api private
|
|
|
|
#
|
2012-12-10 18:17:19 -05:00
|
|
|
def self.identity(node)
|
2012-12-06 15:30:28 -05:00
|
|
|
ToSource.to_source(node)
|
|
|
|
end
|
|
|
|
|
2012-12-29 10:34:39 -05:00
|
|
|
private
|
2012-12-10 18:17:19 -05:00
|
|
|
|
2012-12-12 16:31:14 -05:00
|
|
|
# Return mutated node
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-12-10 18:17:19 -05:00
|
|
|
alias_method :node, :input
|
2012-12-12 16:31:14 -05:00
|
|
|
|
|
|
|
# Return duplicated node
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-12-10 18:17:19 -05:00
|
|
|
alias_method :dup_node, :dup_input
|
2012-12-06 15:30:28 -05:00
|
|
|
|
|
|
|
# Emit a new AST node
|
|
|
|
#
|
|
|
|
# @param [Rubinis::AST::Node:Class] node_class
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def emit_node(node_class, *arguments)
|
|
|
|
emit(new(node_class, *arguments))
|
|
|
|
end
|
|
|
|
|
|
|
|
# Create a new AST node with same class as wrapped node
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def new_self(*arguments)
|
|
|
|
new(node.class, *arguments)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Create a new AST node with Rubnius::AST::NilLiteral class
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def new_nil
|
|
|
|
new(Rubinius::AST::NilLiteral)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Create a new AST node with the same line as wrapped node
|
|
|
|
#
|
|
|
|
# @param [Class:Rubinius::AST::Node] node_class
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def new(node_class, *arguments)
|
|
|
|
node_class.new(node.line, *arguments)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Emit a new AST node with same class as wrapped node
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def emit_self(*arguments)
|
|
|
|
emit(new_self(*arguments))
|
|
|
|
end
|
|
|
|
|
|
|
|
# Emit body mutations
|
|
|
|
#
|
2012-12-06 16:30:57 -05:00
|
|
|
# @param [Symbol] name
|
|
|
|
#
|
2012-12-06 15:30:28 -05:00
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-12-29 10:53:52 -05:00
|
|
|
def emit_attribute_mutations(name, mutator = Mutator)
|
2012-12-29 10:34:39 -05:00
|
|
|
value = node.public_send(name)
|
2012-12-06 15:54:18 -05:00
|
|
|
|
2012-12-29 10:53:52 -05:00
|
|
|
mutator.each(value) do |mutation|
|
2012-12-06 15:54:18 -05:00
|
|
|
dup = dup_node
|
2012-12-06 16:30:57 -05:00
|
|
|
dup.public_send(:"#{name}=", mutation)
|
2013-01-09 14:43:06 -05:00
|
|
|
if block_given?
|
|
|
|
dup = yield(dup)
|
|
|
|
end
|
2012-12-06 15:54:18 -05:00
|
|
|
emit(dup)
|
2012-12-06 15:30:28 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Emit a new AST node with NilLiteral class
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::NilLiteral]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def emit_nil
|
|
|
|
emit(new_nil)
|
|
|
|
end
|
|
|
|
|
2013-01-04 16:16:03 -05:00
|
|
|
# Return new Rubiinius::AST::SendWithArguments node
|
|
|
|
#
|
|
|
|
# @param [Rubnius::AST::Node] receiver
|
|
|
|
# @param [Symbol] name
|
|
|
|
# @param [Object] arguments
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::SendWithArguments]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def new_send_with_arguments(receiver, name, arguments)
|
|
|
|
new(Rubinius::AST::SendWithArguments, receiver, name, arguments)
|
|
|
|
end
|
|
|
|
|
2012-12-06 15:30:28 -05:00
|
|
|
# Return AST representing send
|
|
|
|
#
|
|
|
|
# @param [Rubinius::AST::Node] receiver
|
|
|
|
# @param [Symbol] name
|
|
|
|
#
|
2013-01-04 16:16:03 -05:00
|
|
|
# @return [Rubnius::AST::Send]
|
2012-12-06 15:30:28 -05:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2013-01-04 16:16:03 -05:00
|
|
|
def new_send(receiver, name)
|
|
|
|
new(Rubinius::AST::Send, receiver, name)
|
2012-12-06 15:30:28 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Return duplicated (unfrozen) node each call
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-12-10 18:17:19 -05:00
|
|
|
alias_method :dup_node, :dup_input
|
2012-12-29 14:12:48 -05:00
|
|
|
|
2012-12-06 15:30:28 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|