2012-08-01 07:27:35 -04:00
|
|
|
module Mutant
|
|
|
|
class Mutator
|
2012-09-10 19:00:18 -04:00
|
|
|
# Class for mutations where messages are send to objects
|
2012-08-09 17:07:22 -04:00
|
|
|
class Call < self
|
2012-08-01 07:27:35 -04:00
|
|
|
|
2012-08-01 08:38:12 -04:00
|
|
|
handle(Rubinius::AST::Send)
|
2012-08-01 07:27:35 -04:00
|
|
|
|
2012-08-01 08:38:12 -04:00
|
|
|
private
|
2012-08-01 07:27:35 -04:00
|
|
|
|
|
|
|
# Return receiver AST node
|
|
|
|
#
|
|
|
|
# @return [Rubinius::AST::Node]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def receiver
|
|
|
|
node.receiver
|
|
|
|
end
|
|
|
|
|
|
|
|
# Return name of call
|
|
|
|
#
|
|
|
|
# @return [Symbol]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def name
|
|
|
|
node.name
|
|
|
|
end
|
|
|
|
|
|
|
|
# Check if receiver is self
|
|
|
|
#
|
|
|
|
# @return [true]
|
|
|
|
# returns true when receiver is a Rubinius::AST::Self node
|
|
|
|
#
|
|
|
|
# @return [false]
|
|
|
|
# return false otherwise
|
|
|
|
#
|
2012-08-01 07:31:56 -04:00
|
|
|
# @api private
|
|
|
|
#
|
2012-08-01 07:27:35 -04:00
|
|
|
def self?
|
|
|
|
receiver.kind_of?(Rubinius::AST::Self)
|
|
|
|
end
|
2012-08-01 07:53:28 -04:00
|
|
|
|
2012-08-01 09:55:49 -04:00
|
|
|
# Emit mutation that replaces explicit send to self with implicit send to self
|
2012-08-01 08:54:49 -04:00
|
|
|
#
|
|
|
|
# @example:
|
|
|
|
#
|
|
|
|
# # This class does use Foo#a with explicitly specifing the receiver self.
|
|
|
|
# # But an implicit (privately) call should be used as there is no need for
|
|
|
|
# # specifing en explicit receiver.
|
|
|
|
#
|
|
|
|
# class Foo # Mutation
|
|
|
|
# def print_a # def print_a
|
|
|
|
# puts self.a # puts a
|
|
|
|
# end # end
|
|
|
|
#
|
|
|
|
# def a
|
|
|
|
# :bar
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# There will not be any exception so the mutant is not killed and such calls where
|
|
|
|
# implicit receiver should be used will be spotted.
|
|
|
|
#
|
2012-08-01 08:59:37 -04:00
|
|
|
# @return [undefined]
|
2012-08-01 08:54:49 -04:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def emit_implicit_self_receiver
|
2012-12-04 13:38:58 -05:00
|
|
|
return;
|
2012-08-21 08:19:44 -04:00
|
|
|
# FIXME: Edge case that is currently not very well undestood
|
|
|
|
return if name == :block_given?
|
2012-08-01 08:54:49 -04:00
|
|
|
return unless self?
|
2012-08-01 08:38:48 -04:00
|
|
|
mutant = dup_node
|
2012-08-01 08:54:49 -04:00
|
|
|
mutant.privately = true
|
2012-08-01 08:38:12 -04:00
|
|
|
# TODO: Fix rubinius to allow this as an attr_accessor
|
2012-08-21 08:19:44 -04:00
|
|
|
mutant.instance_variable_set(:@vcall_style, true)
|
2012-08-15 15:13:05 -04:00
|
|
|
emit(mutant)
|
2012-08-01 08:38:12 -04:00
|
|
|
end
|
2012-08-01 07:53:28 -04:00
|
|
|
|
2012-08-01 08:38:12 -04:00
|
|
|
# Emit mutations
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def dispatch
|
2012-08-01 08:54:49 -04:00
|
|
|
emit_implicit_self_receiver
|
2012-08-01 08:13:57 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
class SendWithArguments < Call
|
|
|
|
|
|
|
|
handle(Rubinius::AST::SendWithArguments)
|
|
|
|
|
2012-08-01 08:38:12 -04:00
|
|
|
private
|
2012-08-01 08:13:57 -04:00
|
|
|
|
|
|
|
# Emut mutations
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def dispatch
|
2012-08-01 08:54:49 -04:00
|
|
|
super
|
2012-08-01 08:13:57 -04:00
|
|
|
end
|
2012-08-01 07:53:28 -04:00
|
|
|
end
|
2012-08-01 07:27:35 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|