lib/regexp_parser/syntax/base.rb in regexp_parser-2.2.1 vs lib/regexp_parser/syntax/base.rb in regexp_parser-2.3.0
- old
+ new
@@ -1,93 +1,120 @@
module Regexp::Syntax
class NotImplementedError < Regexp::Syntax::SyntaxError
def initialize(syntax, type, token)
- super "#{syntax.class.name} does not implement: [#{type}:#{token}]"
+ super "#{syntax} does not implement: [#{type}:#{token}]"
end
end
# A lookup map of supported types and tokens in a given syntax
class Base
include Regexp::Syntax::Token
- def initialize
- @implements = {}
+ class << self
+ attr_accessor :features
- implements Token::Literal::Type, Token::Literal::All
- implements Token::FreeSpace::Type, Token::FreeSpace::All
- end
+ # automatically inherit features through the syntax class hierarchy
+ def inherited(subclass)
+ super
+ subclass.features = features.to_h.map { |k, v| [k, v.dup] }.to_h
+ end
- def features
- @implements
- end
+ def implements(type, tokens)
+ (features[type] ||= []).concat(tokens)
+ added_features[type] = tokens
+ end
- def implementations(type)
- @implements[type] ||= []
- end
+ def excludes(type, tokens)
+ tokens.each { |tok| features[type].delete(tok) }
+ removed_features[type] = tokens
+ end
- def implements(type, tokens)
- implementations(type).concat(Array(tokens))
- end
+ def implements?(type, token)
+ implementations(type).include?(token)
+ end
+ alias :check? :implements?
- def excludes(type, tokens)
- Array(tokens).each { |tok| implementations(type).delete(tok) }
- end
+ def implementations(type)
+ features[type] || []
+ end
- def implements?(type, token)
- implementations(type).include?(token)
- end
- alias :check? :implements?
+ def implements!(type, token)
+ raise NotImplementedError.new(self, type, token) unless
+ implements?(type, token)
+ end
+ alias :check! :implements!
- def implements!(type, token)
- raise NotImplementedError.new(self, type, token) unless
- implements?(type, token)
- end
- alias :check! :implements!
+ def added_features
+ @added_features ||= {}
+ end
- def normalize(type, token)
- case type
- when :group
- normalize_group(type, token)
- when :backref
- normalize_backref(type, token)
- else
- [type, token]
+ def removed_features
+ @removed_features ||= {}
end
- end
- def normalize_group(type, token)
- case token
- when :named_ab, :named_sq
- %i[group named]
- else
- [type, token]
+ def normalize(type, token)
+ case type
+ when :group
+ normalize_group(type, token)
+ when :backref
+ normalize_backref(type, token)
+ else
+ [type, token]
+ end
end
+
+ def normalize_group(type, token)
+ case token
+ when :named_ab, :named_sq
+ %i[group named]
+ else
+ [type, token]
+ end
+ end
+
+ def normalize_backref(type, token)
+ case token
+ when :name_ref_ab, :name_ref_sq
+ %i[backref name_ref]
+ when :name_call_ab, :name_call_sq
+ %i[backref name_call]
+ when :name_recursion_ref_ab, :name_recursion_ref_sq
+ %i[backref name_recursion_ref]
+ when :number_ref_ab, :number_ref_sq
+ %i[backref number_ref]
+ when :number_call_ab, :number_call_sq
+ %i[backref number_call]
+ when :number_rel_ref_ab, :number_rel_ref_sq
+ %i[backref number_rel_ref]
+ when :number_rel_call_ab, :number_rel_call_sq
+ %i[backref number_rel_call]
+ when :number_recursion_ref_ab, :number_recursion_ref_sq
+ %i[backref number_recursion_ref]
+ else
+ [type, token]
+ end
+ end
end
- def normalize_backref(type, token)
- case token
- when :name_ref_ab, :name_ref_sq
- %i[backref name_ref]
- when :name_call_ab, :name_call_sq
- %i[backref name_call]
- when :name_recursion_ref_ab, :name_recursion_ref_sq
- %i[backref name_recursion_ref]
- when :number_ref_ab, :number_ref_sq
- %i[backref number_ref]
- when :number_call_ab, :number_call_sq
- %i[backref number_call]
- when :number_rel_ref_ab, :number_rel_ref_sq
- %i[backref number_rel_ref]
- when :number_rel_call_ab, :number_rel_call_sq
- %i[backref number_rel_call]
- when :number_recursion_ref_ab, :number_recursion_ref_sq
- %i[backref number_recursion_ref]
+ # TODO: drop this backwards compatibility code in v3.0.0, do `private :new`
+ def initialize
+ warn 'Using instances of Regexp::Parser::Syntax is deprecated ' \
+ "and will no longer be supported in v3.0.0."
+ end
+
+ def method_missing(name, *args)
+ if self.class.respond_to?(name)
+ warn 'Using instances of Regexp::Parser::Syntax is deprecated ' \
+ "and will no longer be supported in v3.0.0. Please call "\
+ "methods on the class directly, e.g.: #{self.class}.#{name}"
+ self.class.send(name, *args)
else
- [type, token]
+ super
end
end
- def self.inspect
- "#{super} (feature set of #{ancestors[1].to_s.split('::').last})"
+ def respond_to_missing?(name, include_private = false)
+ self.class.respond_to?(name) || super
end
+ # end of backwards compatibility code
end
end