2012-07-26 19:25:23 +02:00
|
|
|
module Mutant
|
2012-07-31 04:10:37 +02:00
|
|
|
class Context
|
2012-08-16 04:10:54 +02:00
|
|
|
# Scope context for mutation (Class or Module)
|
|
|
|
class Scope < self
|
2014-06-28 20:47:46 +00:00
|
|
|
include Adamantium::Flat, Concord::Public.new(:scope, :source_path)
|
2014-06-29 21:25:17 +00:00
|
|
|
extend AST::Sexp
|
2012-07-26 19:25:23 +02:00
|
|
|
|
2014-06-28 20:47:46 +00:00
|
|
|
NAMESPACE_DELIMITER = '::'.freeze
|
|
|
|
|
2012-12-12 22:11:35 +01:00
|
|
|
# Return AST wrapping mutated node
|
|
|
|
#
|
2013-06-04 10:25:13 +02:00
|
|
|
# @return [Parser::AST::Node]
|
2012-12-12 22:11:35 +01:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def root(node)
|
2013-07-28 12:16:45 -07:00
|
|
|
nesting.reverse.reduce(node) do |current, scope|
|
2012-12-12 22:11:35 +01:00
|
|
|
self.class.wrap(scope, current)
|
|
|
|
end
|
2012-08-14 12:26:56 +02:00
|
|
|
end
|
2012-07-26 19:25:23 +02:00
|
|
|
|
2013-01-13 22:27:03 +01:00
|
|
|
# Return identification
|
|
|
|
#
|
|
|
|
# @return [String]
|
|
|
|
#
|
2013-08-01 22:53:51 -07:00
|
|
|
# @api private
|
2013-01-13 22:27:03 +01:00
|
|
|
#
|
|
|
|
def identification
|
|
|
|
scope.name
|
|
|
|
end
|
|
|
|
|
2012-12-12 22:11:35 +01:00
|
|
|
# Wrap node into ast node
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
2013-04-17 20:31:21 -07:00
|
|
|
# @param [Class, Module] scope
|
2013-06-04 10:25:13 +02:00
|
|
|
# @param [Parser::AST::Node] node
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
2013-06-04 10:25:13 +02:00
|
|
|
# @return [Parser::AST::Class]
|
2012-12-12 22:11:35 +01:00
|
|
|
# if scope is of kind Class
|
2012-08-14 12:26:56 +02:00
|
|
|
#
|
2013-06-04 10:25:13 +02:00
|
|
|
# @return [Parser::AST::Module]
|
2012-12-12 22:11:35 +01:00
|
|
|
# if scope is of kind module
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-12-12 22:11:35 +01:00
|
|
|
def self.wrap(scope, node)
|
2014-06-28 20:47:46 +00:00
|
|
|
name = s(:const, nil, scope.name.split(NAMESPACE_DELIMITER).last.to_sym)
|
2012-12-12 22:11:35 +01:00
|
|
|
case scope
|
2014-11-17 19:50:02 +00:00
|
|
|
when Class
|
2013-06-04 19:22:33 +02:00
|
|
|
s(:class, name, nil, node)
|
2014-11-17 19:50:02 +00:00
|
|
|
when Module
|
2013-06-04 19:22:33 +02:00
|
|
|
s(:module, name, node)
|
2012-12-12 22:11:35 +01:00
|
|
|
else
|
2014-11-17 17:00:05 +00:00
|
|
|
fail "Cannot wrap scope: #{scope.inspect}"
|
2012-12-12 22:11:35 +01:00
|
|
|
end
|
2012-07-26 19:25:23 +02:00
|
|
|
end
|
|
|
|
|
2012-12-12 22:11:35 +01:00
|
|
|
# Return nesting
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
2012-12-12 22:11:35 +01:00
|
|
|
# @return [Enumerable<Class,Module>]
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-12-12 22:11:35 +01:00
|
|
|
def nesting
|
|
|
|
const = ::Object
|
|
|
|
name_nesting.each_with_object([]) do |name, nesting|
|
|
|
|
const = const.const_get(name)
|
|
|
|
nesting << const
|
|
|
|
end
|
2012-07-26 19:25:23 +02:00
|
|
|
end
|
2012-12-12 22:11:35 +01:00
|
|
|
memoize :nesting
|
2012-07-26 19:25:23 +02:00
|
|
|
|
2012-08-16 04:10:54 +02:00
|
|
|
# Return unqualified name of scope
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
2012-07-31 04:10:37 +02:00
|
|
|
# @return [String]
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def unqualified_name
|
|
|
|
name_nesting.last
|
|
|
|
end
|
|
|
|
|
2014-06-28 20:47:46 +00:00
|
|
|
# Return match expressions
|
2013-08-04 18:49:42 +02:00
|
|
|
#
|
2014-06-28 20:47:46 +00:00
|
|
|
# @return [Enumerable<Expression>]
|
2013-08-04 18:49:42 +02:00
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2014-06-28 20:47:46 +00:00
|
|
|
def match_expressions
|
2013-08-05 09:18:37 +02:00
|
|
|
name_nesting.each_index.reverse_each.map do |index|
|
2014-06-29 23:16:34 +00:00
|
|
|
Expression.parse("#{name_nesting.take(index.succ).join(NAMESPACE_DELIMITER)}*")
|
2013-08-04 19:30:34 +02:00
|
|
|
end
|
2013-08-04 18:49:42 +02:00
|
|
|
end
|
2014-06-28 20:47:46 +00:00
|
|
|
memoize :match_expressions
|
2013-08-04 18:49:42 +02:00
|
|
|
|
2012-08-16 04:10:54 +02:00
|
|
|
# Return scope wrapped by context
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
|
|
|
# @return [::Module|::Class]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2012-10-26 11:24:29 +02:00
|
|
|
attr_reader :scope
|
2012-08-20 17:53:41 +02:00
|
|
|
|
|
|
|
private
|
2012-07-26 19:25:23 +02:00
|
|
|
|
2012-08-16 04:10:54 +02:00
|
|
|
# Return nesting of names of scope
|
2012-07-26 19:25:23 +02:00
|
|
|
#
|
|
|
|
# @return [Array<String>]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def name_nesting
|
2014-06-28 20:47:46 +00:00
|
|
|
scope.name.split(NAMESPACE_DELIMITER)
|
2012-07-26 19:25:23 +02:00
|
|
|
end
|
2012-10-26 11:24:29 +02:00
|
|
|
memoize :name_nesting
|
2013-06-04 10:25:13 +02:00
|
|
|
|
|
|
|
end # Scope
|
|
|
|
end # Context
|
|
|
|
end # Mutant
|