File: backreference_converter.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 (55 lines) | stat: -rw-r--r-- 1,690 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
require_relative 'base'

class JsRegex
  module Converter
    #
    # Template class implementation.
    #
    class BackreferenceConverter < JsRegex::Converter::Base
      private

      def convert_data
        case subtype
        when :name_ref then convert_name_ref
        when :number, :number_ref, :number_rel_ref then convert_to_plain_num_ref
        when :name_call, :number_call, :number_rel_call then convert_call
        else # name_recursion_ref, number_recursion_ref, ...
          warn_of_unsupported_feature
        end
      end

      def convert_name_ref
        if context.es_2018_or_higher?
          # ES 2018+ supports named backrefs, but only the angled-bracket syntax
          Node.new("\\k<#{expression.name}>", reference: new_position, type: :backref)
        else
          convert_to_plain_num_ref
        end
      end

      def convert_to_plain_num_ref
        position = new_position
        Node.new("\\#{position}", reference: position, type: :backref)
      end

      def new_position
        context.new_capturing_group_position(target_position)
      end

      def target_position
        expression.referenced_expression.number
      end

      def convert_call
        if expression.respond_to?(:number) && expression.number.equal?(0)
          return warn_of_unsupported_feature('whole-pattern recursion')
        end
        context.increment_local_capturing_group_count
        target_copy = expression.referenced_expression.unquantified_clone
        # avoid "Duplicate capture group name" error in JS
        target_copy.token = :capture if target_copy.is?(:named, :group)
        convert_expression(target_copy)
      end
    end
  end
end