File: node.rb

package info (click to toggle)
ruby-js-regex 3.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 164 kB
  • sloc: ruby: 1,002; makefile: 3
file content (94 lines) | stat: -rw-r--r-- 2,310 bytes parent folder | download
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