lib/mutant/mutator.rb in mutant-0.8.10 vs lib/mutant/mutator.rb in mutant-0.8.11
- old
+ new
@@ -1,79 +1,64 @@
module Mutant
# Generator for mutations
class Mutator
- include Adamantium::Flat, AbstractType
- # Run mutator on input
+ REGISTRY = Registry.new
+
+ include Adamantium::Flat, Concord.new(:input, :parent), AbstractType, Procto.call(:output)
+
+ # Lookup and invoke dedicated AST mutator
#
- # @param [Object] input
- # the input to mutate
+ # @param node [Parser::AST::Node]
+ # @param parent [nil,Mutant::Mutator::Node]
#
- # @param [Mutator] parent
- #
- # @return [self]
- def self.each(input, parent = nil, &block)
- return to_enum(__method__, input, parent) unless block_given?
- REGISTRY.lookup(input).new(input, parent, block)
-
- self
+ # @return [Set<Parser::AST::Node>]
+ def self.mutate(node, parent = nil)
+ self::REGISTRY.lookup(node.type).call(node, parent)
end
# Register node class handler
#
# @return [undefined]
def self.handle(*types)
types.each do |type|
- REGISTRY.register(type, self)
+ self::REGISTRY.register(type, self)
end
end
private_class_method :handle
- # Mutation input
+ # Return output
#
- # @return [Object]
- attr_reader :input
+ # @return [Set<Parser::AST::Node>]
+ attr_reader :output
- # Parent context of input
- #
- # @return [Object]
- attr_reader :parent
-
private
# Initialize object
#
# @param [Object] input
# @param [Object] parent
# @param [#call(node)] block
#
# @return [undefined]
- def initialize(input, parent, block)
- @input, @parent, @block = input, parent, block
- @seen = Set.new
- guard(input)
+ def initialize(_input, _parent = nil)
+ super
+
+ @output = Set.new
+
dispatch
end
# Test if generated object is not guarded from emitting
#
# @param [Object] object
#
# @return [Boolean]
def new?(object)
- !@seen.include?(object)
+ !object.eql?(input)
end
- # Add object to guarded values
- #
- # @param [Object] object
- #
- # @return [undefined]
- def guard(object)
- @seen << object
- end
-
# Dispatch node generations
#
# @return [undefined]
abstract_method :dispatch
@@ -83,29 +68,17 @@
#
# @return [undefined]
def emit(object)
return unless new?(object)
- guard(object)
-
- emit!(object)
+ output << object
end
- # Call block with node
- #
- # @param [Parser::AST::Node] node
- #
- # @return [self]
- def emit!(node)
- @block.call(node)
- self
- end
-
# Run input with mutator
#
# @return [undefined]
def run(mutator)
- mutator.new(input, self, method(:emit))
+ mutator.call(input).each(&method(:emit))
end
# Shortcut to create a new unfrozen duplicate of input
#
# @return [Object]