Sha256: d68dec047f9020492f58fed58c494edde084f85a82cdc05ee1a5dea419eb6e95

Contents?: true

Size: 1.83 KB

Versions: 15

Compression:

Stored size: 1.83 KB

Contents

# frozen_string_literal: true

module RuboCop
  module Cop
    module Performance
      # This cop identifies places where `split` argument can be replaced from
      # a deterministic regexp to a string.
      #
      # @example
      #   # bad
      #   'a,b,c'.split(/,/)
      #
      #   # good
      #   'a,b,c'.split(',')
      class RedundantSplitRegexpArgument < Base
        extend AutoCorrector

        MSG = 'Use string as argument instead of regexp.'
        RESTRICT_ON_SEND = %i[split].freeze
        DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/.freeze
        STR_SPECIAL_CHARS = %w[\n \" \' \\\\ \t \b \f \r].freeze

        def_node_matcher :split_call_with_regexp?, <<~PATTERN
          {(send !nil? :split $regexp)}
        PATTERN

        def on_send(node)
          return unless (regexp_node = split_call_with_regexp?(node))
          return if regexp_node.ignore_case? || regexp_node.content == ' '
          return unless determinist_regexp?(regexp_node)

          add_offense(regexp_node) do |corrector|
            new_argument = replacement(regexp_node)

            corrector.replace(regexp_node, "\"#{new_argument}\"")
          end
        end

        private

        def determinist_regexp?(regexp_node)
          DETERMINISTIC_REGEX.match?(regexp_node.source)
        end

        def replacement(regexp_node)
          regexp_content = regexp_node.content
          stack = []
          chars = regexp_content.chars.each_with_object([]) do |char, strings|
            if stack.empty? && char == '\\'
              stack.push(char)
            else
              strings << "#{stack.pop}#{char}"
            end
          end
          chars.map do |char|
            char = char.dup
            char.delete!('\\') unless STR_SPECIAL_CHARS.include?(char)
            char
          end.join
        end
      end
    end
  end
end

Version data entries

15 entries across 15 versions & 3 rubygems

Version Path
scrapbook-0.3.2 vendor/ruby/2.7.0/gems/rubocop-performance-1.13.3/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
scrapbook-0.3.1 vendor/ruby/2.7.0/gems/rubocop-performance-1.13.3/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
op_connect-0.1.2 vendor/bundle/ruby/3.1.0/gems/rubocop-performance-1.13.3/lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.13.3 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.13.2 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.13.1 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.13.0 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.12.0 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.11.5 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.11.4 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.11.3 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.11.2 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.11.1 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.11.0 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb
rubocop-performance-1.10.2 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb