lib/mutant/expression/method.rb in mutant-0.10.17 vs lib/mutant/expression/method.rb in mutant-0.10.18
- old
+ new
@@ -3,10 +3,12 @@
module Mutant
class Expression
# Explicit method expression
class Method < self
+ extend AST::Sexp
+
include Anima.new(
:method_name,
:scope_name,
:scope_symbol
)
@@ -16,14 +18,11 @@
MATCHERS = IceNine.deep_freeze(
'.' => [Matcher::Methods::Singleton, Matcher::Methods::Metaclass],
'#' => [Matcher::Methods::Instance]
)
- METHOD_NAME_PATTERN = Regexp.union(
- /(?<method_name>[A-Za-z_][A-Za-z\d_]*[!?=]?)/,
- *AST::Types::OPERATOR_METHODS.map(&:to_s)
- ).freeze
+ METHOD_NAME_PATTERN = /(?<method_name>.+)/.freeze
private_constant(*constants(false))
REGEXP = /\A#{SCOPE_NAME_PATTERN}#{SCOPE_SYMBOL_PATTERN}#{METHOD_NAME_PATTERN}\z/.freeze
@@ -44,9 +43,33 @@
methods_matcher = Matcher::Chain.new(matcher_candidates)
Matcher::Filter.new(methods_matcher, ->(subject) { subject.expression.eql?(self) })
end
+
+ def self.try_parse(input)
+ match = REGEXP.match(input) or return
+
+ from_match(match) if valid_method_name?(match[:method_name])
+ end
+
+ # Test if string is a valid Ruby method name
+ #
+ # Note that this crazyness is indeed the "correct" solution.
+ #
+ # See: https://github.com/whitequark/parser/issues/213
+ #
+ # @param [String]
+ #
+ # @return [Boolean]
+ def self.valid_method_name?(name)
+ buffer = ::Parser::Source::Buffer.new(nil, source: "def #{name}; end")
+
+ ::Parser::CurrentRuby
+ .new
+ .parse(buffer).eql?(s(:def, name.to_sym, s(:args), nil))
+ end
+ private_class_method :valid_method_name?
private
def scope
Object.const_get(scope_name)