2012-07-26 13:25:23 -04:00
|
|
|
module Mutant
|
2012-07-30 22:00:05 -04:00
|
|
|
# Generator for mutations
|
2012-07-26 13:25:23 -04:00
|
|
|
class Mutator
|
2012-11-26 05:30:00 -05:00
|
|
|
include Adamantium::Flat, AbstractType
|
2012-07-27 16:39:31 -04:00
|
|
|
|
2012-12-06 15:30:28 -05:00
|
|
|
# Run mutator on input
|
2012-07-27 16:39:31 -04:00
|
|
|
#
|
2014-06-09 22:13:15 -04:00
|
|
|
# @param [Object] input
|
|
|
|
# the input to mutate
|
|
|
|
#
|
|
|
|
# @param [Mutator] parent
|
2012-07-27 16:39:31 -04:00
|
|
|
#
|
2012-07-30 22:00:05 -04:00
|
|
|
# @return [self]
|
2012-07-27 16:39:31 -04:00
|
|
|
#
|
|
|
|
# @api private
|
2013-12-07 15:11:04 -05:00
|
|
|
def self.each(input, parent = nil, &block)
|
|
|
|
return to_enum(__method__, input, parent) unless block_given?
|
2014-11-17 12:05:02 -05:00
|
|
|
REGISTRY.lookup(input).new(input, parent, block)
|
2012-07-30 22:00:05 -04:00
|
|
|
|
|
|
|
self
|
2012-07-27 16:39:31 -04:00
|
|
|
end
|
|
|
|
|
2012-07-31 13:45:46 -04:00
|
|
|
# Register node class handler
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
2013-06-04 04:25:13 -04:00
|
|
|
def self.handle(*types)
|
|
|
|
types.each do |type|
|
2014-11-17 12:05:02 -05:00
|
|
|
REGISTRY.register(type, self)
|
2013-06-04 09:27:16 -04:00
|
|
|
end
|
2012-07-27 16:39:31 -04:00
|
|
|
end
|
2012-07-31 13:45:46 -04:00
|
|
|
private_class_method :handle
|
2012-07-27 16:39:31 -04:00
|
|
|
|
2015-07-03 11:21:39 -04:00
|
|
|
# Mutation input
|
2012-10-26 05:24:29 -04:00
|
|
|
#
|
2012-12-06 15:30:28 -05:00
|
|
|
# @return [Object]
|
2012-10-26 05:24:29 -04:00
|
|
|
#
|
|
|
|
# @api private
|
2012-12-06 15:30:28 -05:00
|
|
|
attr_reader :input
|
2012-10-26 05:24:29 -04:00
|
|
|
|
2015-07-03 11:21:39 -04:00
|
|
|
# Parent context of input
|
2013-06-24 16:10:40 -04:00
|
|
|
#
|
|
|
|
# @return [Object]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
attr_reader :parent
|
|
|
|
|
2012-07-30 22:00:05 -04:00
|
|
|
private
|
|
|
|
|
2012-12-06 15:30:28 -05:00
|
|
|
# Initialize object
|
2012-07-30 22:00:05 -04:00
|
|
|
#
|
2012-12-06 15:30:28 -05:00
|
|
|
# @param [Object] input
|
2013-06-24 16:10:40 -04:00
|
|
|
# @param [Object] parent
|
2012-07-30 22:00:05 -04:00
|
|
|
# @param [#call(node)] block
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
2012-07-27 16:39:31 -04:00
|
|
|
#
|
|
|
|
# @api private
|
2013-06-24 16:10:40 -04:00
|
|
|
def initialize(input, parent, block)
|
|
|
|
@input, @parent, @block = input, parent, block
|
2012-12-10 18:17:19 -05:00
|
|
|
@seen = Set.new
|
|
|
|
guard(input)
|
2012-07-30 22:00:05 -04:00
|
|
|
dispatch
|
|
|
|
end
|
|
|
|
|
2014-08-07 12:00:31 -04:00
|
|
|
# Test if generated object is not guarded from emitting
|
2012-12-06 15:30:28 -05:00
|
|
|
#
|
|
|
|
# @param [Object] object
|
|
|
|
#
|
2014-06-15 15:27:57 -04:00
|
|
|
# @return [Boolean]
|
2012-12-06 15:30:28 -05:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
def new?(object)
|
2014-04-11 21:12:49 -04:00
|
|
|
!@seen.include?(object)
|
2012-12-10 18:17:19 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Add object to guarded values
|
|
|
|
#
|
|
|
|
# @param [Object] object
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
def guard(object)
|
2014-04-11 21:12:49 -04:00
|
|
|
@seen << object
|
2012-12-06 15:30:28 -05:00
|
|
|
end
|
|
|
|
|
2012-07-30 22:00:05 -04:00
|
|
|
# Dispatch node generations
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
2012-08-02 19:28:15 -04:00
|
|
|
abstract_method :dispatch
|
2012-07-30 22:00:05 -04:00
|
|
|
|
2012-12-06 15:30:28 -05:00
|
|
|
# Emit generated mutation if object is not equivalent to input
|
2012-07-30 22:00:05 -04:00
|
|
|
#
|
2012-12-06 15:30:28 -05:00
|
|
|
# @param [Object] object
|
2012-07-30 22:00:05 -04:00
|
|
|
#
|
2012-12-06 15:30:28 -05:00
|
|
|
# @return [undefined]
|
2012-07-30 22:00:05 -04:00
|
|
|
#
|
|
|
|
# @api private
|
2012-12-06 15:30:28 -05:00
|
|
|
def emit(object)
|
2013-06-15 11:15:37 -04:00
|
|
|
return unless new?(object)
|
2012-12-06 15:30:28 -05:00
|
|
|
|
2012-12-10 18:17:19 -05:00
|
|
|
guard(object)
|
|
|
|
|
2012-12-06 15:30:28 -05:00
|
|
|
emit!(object)
|
2012-07-27 16:39:31 -04:00
|
|
|
end
|
|
|
|
|
2012-07-30 22:00:05 -04:00
|
|
|
# Call block with node
|
2012-07-30 22:10:37 -04:00
|
|
|
#
|
2013-06-04 04:25:13 -04:00
|
|
|
# @param [Parser::AST::Node] node
|
2012-07-30 22:00:05 -04:00
|
|
|
#
|
|
|
|
# @return [self]
|
|
|
|
#
|
|
|
|
# @api private
|
2012-08-15 22:10:54 -04:00
|
|
|
def emit!(node)
|
2012-07-30 22:00:05 -04:00
|
|
|
@block.call(node)
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2012-12-29 10:53:52 -05:00
|
|
|
# Run input with mutator
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
def run(mutator)
|
2013-06-24 16:10:40 -04:00
|
|
|
mutator.new(input, self, method(:emit))
|
2012-12-29 10:53:52 -05:00
|
|
|
end
|
|
|
|
|
2012-12-06 15:30:28 -05:00
|
|
|
# Shortcut to create a new unfrozen duplicate of input
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
2012-12-06 15:30:28 -05:00
|
|
|
# @return [Object]
|
2012-07-30 22:00:05 -04:00
|
|
|
#
|
2012-07-26 13:25:23 -04:00
|
|
|
# @api private
|
2012-12-06 15:30:28 -05:00
|
|
|
def dup_input
|
2013-07-02 13:11:39 -04:00
|
|
|
input.dup
|
2012-07-26 13:25:23 -04:00
|
|
|
end
|
|
|
|
|
2013-06-04 04:25:13 -04:00
|
|
|
end # Mutator
|
|
|
|
end # Mutant
|