<commit_before># encoding: utf-8
# frozen_string_literal: true

module RuboCop
  module Cop
    module Performance
      # This cop identifies places where a case-insensitive string comparison
      # can better be implemented using `casecmp`.
      #
      # @example
      #   @bad
      #   str.downcase == 'abc'
      #   str.upcase.eql? 'ABC'
      #   'abc' == str.downcase
      #   'ABC'.eql? str.upcase
      #   str.downcase == str.downcase
      #
      #   @good
      #   str.casecmp('ABC').zero?
      #   'abc'.casecmp(str).zero?
      class Casecmp < Cop
        MSG = 'Use `casecmp` instead of `%s %s`.'.freeze
        CASE_METHODS = [:downcase, :upcase].freeze

        def_node_matcher :downcase_eq, <<-END
          (send
            $(send _ ${:downcase :upcase})
            ${:== :eql? :!=}
            ${str (send _ {:downcase :upcase} ...) (begin str)})
        END

        def_node_matcher :eq_downcase, <<-END
          (send
            {str (send _ {:downcase :upcase} ...) (begin str)}
            ${:== :eql? :!=}
            $(send _ ${:downcase :upcase}))
        END

        def on_send(node)
          return if part_of_ignored_node?(node)

          downcase_eq(node) do |send_downcase, case_method, eq_method, other|
            *_, method = *other
            if CASE_METHODS.include?(method)
              range = node.loc.expression
              ignore_node(node)
            else
              range = node.loc.selector.join(send_downcase.loc.selector)
            end

            add_offense(node, range, format(MSG, case_method, eq_method))
            return
          end

          eq_downcase(node) do |eq_method, send_downcase, case_method|
            range = node.loc.selector.join(send_downcase.loc.selector)
            add_offense(node, range, format(MSG, eq_method, case_method))
          end
        end

        def autocorrect(node)
          downcase_eq(node) do
            receiver, method, arg = *node
            variable, = *receiver
            return correction(node, receiver, method, arg, variable)
          end

          eq_downcase(node) do
            arg, method, receiver = *node
            variable, = *receiver
            return correction(node, receiver, method, arg, variable)
          end
        end

        private

        def correction(node, _receiver, method, arg, variable)
          lambda do |corrector|
            corrector.insert_before(node.loc.expression, '!') if method == :!=<commit_msg>Reduce complexity in Casecmp<commit_after># encoding: utf-8
# frozen_string_literal: true

module RuboCop
  module Cop
    module Performance
      # This cop identifies places where a case-insensitive string comparison
      # can better be implemented using `casecmp`.
      #
      # @example
      #   @bad
      #   str.downcase == 'abc'
      #   str.upcase.eql? 'ABC'
      #   'abc' == str.downcase
      #   'ABC'.eql? str.upcase
      #   str.downcase == str.downcase
      #
      #   @good
      #   str.casecmp('ABC').zero?
      #   'abc'.casecmp(str).zero?
      class Casecmp < Cop
        MSG = 'Use `casecmp` instead of `%s %s`.'.freeze
        CASE_METHODS = [:downcase, :upcase].freeze

        def_node_matcher :downcase_eq, <<-END
          (send
            $(send _ ${:downcase :upcase})
            ${:== :eql? :!=}
            ${str (send _ {:downcase :upcase} ...) (begin str)})
        END

        def_node_matcher :eq_downcase, <<-END
          (send
            {str (send _ {:downcase :upcase} ...) (begin str)}
            ${:== :eql? :!=}
            $(send _ ${:downcase :upcase}))
        END

        def on_send(node)
          return if part_of_ignored_node?(node)

          inefficient_comparison(node) do |range, is_other_part, *methods|
            ignore_node(node) if is_other_part
            add_offense(node, range, format(MSG, *methods))
          end
        end

        def autocorrect(node)
          downcase_eq(node) do
            receiver, method, arg = *node
            variable, = *receiver
            return correction(node, receiver, method, arg, variable)
          end

          eq_downcase(node) do
            arg, method, receiver = *node
            variable, = *receiver
            return correction(node, receiver, method, arg, variable)
          end
        end

        private

        def inefficient_comparison(node)
          loc = node.loc

          downcase_eq(node) do |send_downcase, case_method, eq_method, other|
            *_, method = *other
            range, is_other_part = downcase_eq_range(method, loc, send_downcase)

            yield range, is_other_part, case_method, eq_method
            return
          end

          eq_downcase(node) do |eq_method, send_downcase, case_method|
            range = loc.selector.join(send_downcase.loc.selector)
            yield range, false, eq_method, case_method
          end
        end

        def downcase_eq_range(method, loc, send_downcase)
          if CASE_METHODS.include?(method)
            [loc.expression, true]
          else
            [loc.selector.join(send_downcase.loc.selector), false]
          end
        end

        def correction(node, _receiver, method, arg, variable)
          lambda do |corrector|
            corrector.insert_before(node.loc.expression, '!') if method == :!=
{'fraction_non_alphanumeric': 0.10938377973403259, 'fraction_numerical': 0.00037460198539052256, 'mean_word_length': 1.8253968253968254, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4996699', 'n_tokens_mistral': 1629, 'n_tokens_neox': 1584, 'n_words': 376}