Sha256: 63c362422a97a6bf5bf7f98e0eeb9f6e0c547876acc0e43471a9d92e2b3e4e28

Contents?: true

Size: 1.6 KB

Versions: 3

Compression:

Stored size: 1.6 KB

Contents

# frozen_string_literal: true

module RuboCop
  module Ext
    # Extensions to AST::RegexpNode for our cached parsed regexp info
    module RegexpNode
      ANY = Object.new
      def ANY.==(_)
        true
      end
      private_constant :ANY

      class << self
        attr_reader :parsed_cache
      end
      @parsed_cache = {}

      # @return [Regexp::Expression::Root, nil]
      def parsed_tree
        str = with_interpolations_blanked
        Ext::RegexpNode.parsed_cache[str] ||= begin
          Regexp::Parser.parse(str, options: options)
        rescue StandardError
          nil
        end
      end

      def each_capture(named: ANY)
        return enum_for(__method__, named: named) unless block_given?

        parsed_tree&.traverse do |event, exp, _index|
          yield(exp) if event == :enter &&
                        named == exp.respond_to?(:name) &&
                        exp.respond_to?(:capturing?) &&
                        exp.capturing?
        end

        self
      end

      private

      def with_interpolations_blanked
        # Ignore the trailing regopt node
        children[0...-1].map do |child|
          source = child.source

          # We don't want to consider the contents of interpolations as part of the pattern source,
          # but need to preserve their width, to allow offsets to correctly line up with the
          # original source: spaces have no effect, and preserve width.
          if child.begin_type?
            ' ' * source.length
          else
            source
          end
        end.join
      end

      AST::RegexpNode.include self
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
rubocop-1.0.0 lib/rubocop/ext/regexp_node.rb
rubocop-0.93.1 lib/rubocop/ext/regexp_node.rb
rubocop-0.93.0 lib/rubocop/ext/regexp_node.rb