1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
class JsRegex
#
# Converter#convert result. Represents a branch or leaf node with an optional
# quantifier as well as type and reference annotations for SecondPass.
#
class Node
require_relative 'error'
attr_reader :children, :quantifier, :reference, :type
TYPES = %i[
backref
captured_group
conditional
dropped
keep_mark
plain
].freeze
def initialize(*children, reference: nil, type: :plain)
self.children = children
self.reference = reference
self.type = type
end
def initialize_copy(*)
self.children = children.map(&:clone)
end
def transform(&block)
children.map!(&block)
self
end
def <<(node)
children << node
self
end
def dropped?
# keep everything else, including empty or depleted capturing groups
# so as not to not mess with reference numbers (e.g. backrefs)
type.equal?(:dropped)
end
def to_s
case type
when :dropped
''
when :backref, :captured_group, :plain
children.join << quantifier.to_s
else
raise TypeError.new(
"#{type} must be substituted before stringification"
).extend(JsRegex::Error)
end
end
def update(attrs)
self.children = attrs.fetch(:children) if attrs.key?(:children)
self.quantifier = attrs.fetch(:quantifier) if attrs.key?(:quantifier)
self.type = attrs.fetch(:type) if attrs.key?(:type)
self
end
private
TypeError = Class.new(::TypeError).extend(JsRegex::Error)
def type=(arg)
arg.nil? || TYPES.include?(arg) ||
raise(TypeError, "unsupported type #{arg.class} for #{__method__}")
@type = arg
end
def children=(arg)
arg.class == Array ||
raise(TypeError, "unsupported type #{arg.class} for #{__method__}")
@children = arg
end
def quantifier=(arg)
arg.nil? || arg.class == Regexp::Expression::Quantifier ||
raise(TypeError, "unsupported type #{arg.class} for #{__method__}")
@quantifier = arg
end
def reference=(arg)
arg.nil? || arg.is_a?(Numeric) ||
raise(TypeError, "unsupported type #{arg.class} for #{__method__}")
@reference = arg
end
end
end
|