Sha256: 4016a12df9c06271b0316489160ce6aa842fb87b7cba76d5790d34ce738f46c2

Contents?: true

Size: 1.85 KB

Versions: 1

Compression:

Stored size: 1.85 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 split_call_with_regexp?(node)
          return unless determinist_regexp?(node.first_argument)

          add_offense(node.first_argument) do |corrector|
            autocorrect(corrector, node)
          end
        end

        private

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

        def autocorrect(corrector, node)
          new_argument = replacement(node)

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

        def replacement(node)
          regexp_content = node.first_argument.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

1 entries across 1 versions & 1 rubygems

Version Path
rubocop-performance-1.10.0 lib/rubocop/cop/performance/redundant_split_regexp_argument.rb