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)