2012-07-23 16:54:35 -04:00
|
|
|
module Mutant
|
|
|
|
class Matcher
|
|
|
|
class Method
|
2012-07-26 13:25:23 -04:00
|
|
|
# Matcher for singleton methods
|
2012-08-09 17:07:22 -04:00
|
|
|
class Singleton < self
|
2012-07-26 13:25:23 -04:00
|
|
|
|
2012-08-15 22:10:54 -04:00
|
|
|
# Return matcher enumerable
|
|
|
|
#
|
|
|
|
# @param [Class|Module] scope
|
|
|
|
#
|
|
|
|
# @return [Enumerable<Matcher::Method::Singleton>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def self.each(scope)
|
|
|
|
return to_enum unless block_given?
|
2012-08-16 13:42:32 -04:00
|
|
|
singleton_methods(scope).each do |name|
|
|
|
|
yield new(scope, name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Return singleton methods defined on scope
|
|
|
|
#
|
|
|
|
# @param [Class|Module] scope
|
|
|
|
#
|
|
|
|
# @return [Enumerable<Symbol>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def self.singleton_methods(scope)
|
2012-08-15 22:10:54 -04:00
|
|
|
scope.singleton_class.public_instance_methods(false).reject do |method|
|
2012-08-14 16:45:34 -04:00
|
|
|
method.to_sym == :__class_init__
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-15 22:10:54 -04:00
|
|
|
# Return identification
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def identification
|
|
|
|
"#{scope.name}.#{method_name}"
|
|
|
|
end
|
|
|
|
|
2012-07-23 16:54:35 -04:00
|
|
|
private
|
2012-07-26 13:25:23 -04:00
|
|
|
|
2012-07-23 19:41:08 -04:00
|
|
|
# Return method instance
|
2012-07-30 22:10:37 -04:00
|
|
|
#
|
2012-07-23 19:41:08 -04:00
|
|
|
# @return [UnboundMethod]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-07-23 16:54:35 -04:00
|
|
|
def method
|
2012-08-15 22:10:54 -04:00
|
|
|
scope.method(method_name)
|
2012-07-23 16:54:35 -04:00
|
|
|
end
|
|
|
|
|
2012-08-16 13:42:32 -04:00
|
|
|
# Test for node match
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
2012-08-16 13:10:24 -04:00
|
|
|
# @param [Rubinius::AST::Node] node
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
|
|
|
# @return [true]
|
2012-08-16 13:10:24 -04:00
|
|
|
# returns true if node matches method
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
|
|
|
# @return [false]
|
2012-08-16 13:10:24 -04:00
|
|
|
# returns false if node NOT matches method
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
|
|
|
# @api private
|
2012-08-16 13:10:24 -04:00
|
|
|
#
|
|
|
|
def match?(node)
|
|
|
|
node.class == Rubinius::AST::DefineSingleton &&
|
2012-08-16 13:42:32 -04:00
|
|
|
line?(node) &&
|
|
|
|
name?(node) &&
|
|
|
|
receiver?(node)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Test for line match
|
|
|
|
#
|
|
|
|
# @param [Rubinius::AST::Node] node
|
|
|
|
#
|
|
|
|
# @return [true]
|
|
|
|
# returns true if node matches source line
|
|
|
|
#
|
|
|
|
# @return [false]
|
|
|
|
# returns false otherwise
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def line?(node)
|
|
|
|
node.line == source_line
|
|
|
|
end
|
|
|
|
|
|
|
|
# Test for name match
|
|
|
|
#
|
|
|
|
# @param [Rubinius::AST::DefineSingleton] node
|
|
|
|
#
|
|
|
|
# @return [true]
|
|
|
|
# returns true if node name matches
|
|
|
|
#
|
|
|
|
# @return [false]
|
|
|
|
# returns false otherwise
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def name?(node)
|
|
|
|
node.body.name == method_name
|
2012-07-26 13:25:23 -04:00
|
|
|
end
|
|
|
|
|
2012-08-16 13:42:32 -04:00
|
|
|
# Test for receiver match
|
2012-07-30 22:10:37 -04:00
|
|
|
#
|
2012-07-26 13:25:23 -04:00
|
|
|
# @param [Rubinius::AST::DefineSingleton] node
|
|
|
|
#
|
|
|
|
# @return [true]
|
2012-08-15 22:10:54 -04:00
|
|
|
# returns true when receiver is self or scope from pattern
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
|
|
|
# @return [false]
|
|
|
|
# returns false otherwise
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-08-16 13:42:32 -04:00
|
|
|
def receiver?(node)
|
2012-07-26 13:25:23 -04:00
|
|
|
receiver = node.receiver
|
|
|
|
case receiver
|
|
|
|
when Rubinius::AST::Self
|
|
|
|
true
|
|
|
|
when Rubinius::AST::ConstantAccess
|
2012-08-16 13:42:32 -04:00
|
|
|
receiver_name?(receiver)
|
2012-07-26 13:25:23 -04:00
|
|
|
else
|
|
|
|
raise 'Can only match receiver on Rubinius::AST::Self or Rubinius::AST::ConstantAccess'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-08-16 13:42:32 -04:00
|
|
|
# Test if reciver name matches context
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
|
|
|
# @param [Rubinius::AST::Node] node
|
|
|
|
#
|
|
|
|
# @return [true]
|
2012-08-15 22:10:54 -04:00
|
|
|
# returns true when node name matches unqualified scope name
|
2012-07-26 13:25:23 -04:00
|
|
|
#
|
|
|
|
# @return [false]
|
|
|
|
# returns false otherwise
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-08-16 13:42:32 -04:00
|
|
|
def receiver_name?(node)
|
2012-07-26 13:25:23 -04:00
|
|
|
node.name.to_s == context.unqualified_name
|
|
|
|
end
|
|
|
|
|
2012-07-23 16:54:35 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|