2013-07-28 19:03:06 -04:00
|
|
|
# encoding: utf-8
|
|
|
|
|
2012-11-21 16:28:08 -05:00
|
|
|
module Mutant
|
|
|
|
class Matcher
|
2013-07-28 13:59:25 -04:00
|
|
|
# Abstract base class for matcher that returns method subjects from scope
|
2013-01-21 14:08:30 -05:00
|
|
|
class Methods < self
|
2013-06-27 16:18:07 -04:00
|
|
|
include AbstractType, Concord::Public.new(:cache, :scope)
|
2013-01-21 16:56:52 -05:00
|
|
|
|
2012-11-21 16:28:08 -05:00
|
|
|
# Enumerate subjects
|
|
|
|
#
|
|
|
|
# @return [self]
|
|
|
|
# if block given
|
|
|
|
#
|
2013-04-17 23:31:21 -04:00
|
|
|
# @return [Enumerator<Subject>]
|
2012-11-21 16:28:08 -05:00
|
|
|
# otherwise
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def each(&block)
|
|
|
|
return to_enum unless block_given?
|
2012-12-07 17:27:21 -05:00
|
|
|
|
2012-11-21 16:28:08 -05:00
|
|
|
methods.each do |method|
|
|
|
|
emit_matches(method, &block)
|
|
|
|
end
|
|
|
|
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2013-01-21 16:56:52 -05:00
|
|
|
# Return method matcher class
|
|
|
|
#
|
|
|
|
# @return [Class:Matcher::Method]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def matcher
|
|
|
|
self.class::MATCHER
|
|
|
|
end
|
|
|
|
|
2013-04-27 12:21:38 -04:00
|
|
|
# Return methods
|
2012-11-21 16:28:08 -05:00
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
# @return [Enumerable<Method, UnboundMethod>]
|
2012-11-21 16:28:08 -05:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
def methods
|
|
|
|
candidate_names.each_with_object([]) do |name, methods|
|
|
|
|
method = access(name)
|
|
|
|
methods << method if method.owner == candidate_scope
|
2012-11-21 16:28:08 -05:00
|
|
|
end
|
|
|
|
end
|
2013-04-27 12:21:38 -04:00
|
|
|
memoize :methods
|
2012-11-21 16:28:08 -05:00
|
|
|
|
2013-04-27 12:21:38 -04:00
|
|
|
private
|
|
|
|
|
|
|
|
# Emit matches for method
|
2013-04-27 09:52:49 -04:00
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
# @param [UnboundMethod, Method] method
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
2013-04-27 09:52:49 -04:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
def emit_matches(method)
|
2013-07-04 18:54:50 -04:00
|
|
|
matcher.build(cache, scope, method).each do |subject|
|
2013-04-27 12:21:38 -04:00
|
|
|
yield subject
|
2013-04-27 09:52:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Return candidate names
|
|
|
|
#
|
|
|
|
# @param [Object] object
|
2012-11-21 16:28:08 -05:00
|
|
|
#
|
2013-04-17 23:31:21 -04:00
|
|
|
# @return [Enumerable<Symbol>]
|
2012-11-21 16:28:08 -05:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
def candidate_names
|
2013-06-14 14:54:02 -04:00
|
|
|
names =
|
2013-06-15 11:14:33 -04:00
|
|
|
candidate_scope.public_instance_methods(false) +
|
|
|
|
candidate_scope.private_instance_methods(false) +
|
|
|
|
candidate_scope.protected_instance_methods(false)
|
2013-04-27 09:52:49 -04:00
|
|
|
names.sort
|
|
|
|
end
|
2012-11-21 16:28:08 -05:00
|
|
|
|
2013-04-27 12:21:38 -04:00
|
|
|
# Return candidate scope
|
|
|
|
#
|
|
|
|
# @return [Class, Module]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
abstract_method :candidate_scope
|
|
|
|
|
2013-06-15 11:13:01 -04:00
|
|
|
# Matcher for singleton methods
|
2012-11-21 16:28:08 -05:00
|
|
|
class Singleton < self
|
2013-01-03 17:55:30 -05:00
|
|
|
MATCHER = Matcher::Method::Singleton
|
2012-11-21 16:28:08 -05:00
|
|
|
|
2013-04-27 12:21:38 -04:00
|
|
|
private
|
|
|
|
|
2012-12-07 17:27:21 -05:00
|
|
|
# Return method for name
|
|
|
|
#
|
|
|
|
# @param [Symbol] method_name
|
|
|
|
#
|
|
|
|
# @return [Method]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def access(method_name)
|
|
|
|
scope.method(method_name)
|
|
|
|
end
|
|
|
|
|
2013-04-27 12:21:38 -04:00
|
|
|
# Return candidate scope
|
2012-11-21 16:28:08 -05:00
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
# @return [Class]
|
2012-11-21 16:28:08 -05:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
def candidate_scope
|
|
|
|
scope.singleton_class
|
2012-11-21 16:28:08 -05:00
|
|
|
end
|
2013-09-07 14:27:06 -04:00
|
|
|
memoize :candidate_scope, freezer: :noop
|
2013-04-27 12:21:38 -04:00
|
|
|
|
2013-06-14 14:54:02 -04:00
|
|
|
end # Singleton
|
2012-11-21 16:28:08 -05:00
|
|
|
|
2013-06-15 11:13:01 -04:00
|
|
|
# Matcher for instance methods
|
2012-11-21 16:28:08 -05:00
|
|
|
class Instance < self
|
2013-01-03 17:55:30 -05:00
|
|
|
MATCHER = Matcher::Method::Instance
|
2012-11-21 16:28:08 -05:00
|
|
|
|
2013-04-27 12:21:38 -04:00
|
|
|
private
|
|
|
|
|
2012-12-07 17:27:21 -05:00
|
|
|
# Return method for name
|
|
|
|
#
|
|
|
|
# @param [Symbol] method_name
|
|
|
|
#
|
|
|
|
# @return [UnboundMethod]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def access(method_name)
|
|
|
|
scope.instance_method(method_name)
|
|
|
|
end
|
|
|
|
|
2013-04-27 12:21:38 -04:00
|
|
|
# Return candidate scope
|
2012-11-21 16:28:08 -05:00
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
# @return [Class, Module]
|
2013-06-14 14:54:02 -04:00
|
|
|
#
|
2012-12-12 16:31:14 -05:00
|
|
|
# @api private
|
|
|
|
#
|
2013-04-27 12:21:38 -04:00
|
|
|
def candidate_scope
|
|
|
|
scope
|
2012-11-21 16:28:08 -05:00
|
|
|
end
|
2013-04-27 12:21:38 -04:00
|
|
|
|
2013-06-14 14:54:02 -04:00
|
|
|
end # Instance
|
|
|
|
|
|
|
|
end # Methods
|
|
|
|
end # Matcher
|
|
|
|
end # Mutant
|