Sha256: d4f083cfc80f54c45e34cbc728e00dc437682a0e2e2676a18864c84beb7b4a06

Contents?: true

Size: 1.84 KB

Versions: 32

Compression:

Stored size: 1.84 KB

Contents

# frozen_string_literal: true

module RuboCop
  module Cop
    module Style
      # Identifies usages of `arr[0]` and `arr[-1]` and suggests to change
      # them to use `arr.first` and `arr.last` instead.
      #
      # The cop is disabled by default due to safety concerns.
      #
      # @safety
      #   This cop is unsafe because `[0]` or `[-1]` can be called on a Hash,
      #   which returns a value for `0` or `-1` key, but changing these to use
      #   `.first` or `.last` will return first/last tuple instead. Also, String
      #   does not implement `first`/`last` methods.
      #
      # @example
      #   # bad
      #   arr[0]
      #   arr[-1]
      #
      #   # good
      #   arr.first
      #   arr.last
      #   arr[0] = 2
      #   arr[0][-2]
      #
      class ArrayFirstLast < Base
        extend AutoCorrector

        MSG = 'Use `%<preferred>s`.'
        RESTRICT_ON_SEND = %i[[]].freeze

        # rubocop:disable Metrics/AbcSize
        def on_send(node)
          return unless node.arguments.size == 1 && node.first_argument.int_type?

          value = node.first_argument.value
          return unless [0, -1].include?(value)

          node = innermost_braces_node(node)
          return if node.parent && brace_method?(node.parent)

          preferred = (value.zero? ? 'first' : 'last')
          add_offense(node.loc.selector, message: format(MSG, preferred: preferred)) do |corrector|
            corrector.replace(node.loc.selector, ".#{preferred}")
          end
        end
        # rubocop:enable Metrics/AbcSize

        private

        def innermost_braces_node(node)
          node = node.receiver while node.receiver.send_type? && node.receiver.method?(:[])
          node
        end

        def brace_method?(node)
          node.send_type? && (node.method?(:[]) || node.method?(:[]=))
        end
      end
    end
  end
end

Version data entries

32 entries across 32 versions & 7 rubygems

Version Path
rubocop-1.68.0 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.67.0 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.66.1 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.66.0 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.65.1 lib/rubocop/cop/style/array_first_last.rb
blacklight-spotlight-3.6.0.beta8 vendor/bundle/ruby/3.2.0/gems/rubocop-1.64.1/lib/rubocop/cop/style/array_first_last.rb
rubocop-1.65.0 lib/rubocop/cop/style/array_first_last.rb
katalyst-govuk-formbuilder-1.9.2 vendor/bundle/ruby/3.3.0/gems/rubocop-1.64.1/lib/rubocop/cop/style/array_first_last.rb
rubocop-1.64.1 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.63.4 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.63.3 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.63.2 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.63.1 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.63.0 lib/rubocop/cop/style/array_first_last.rb
bison-0.1.0 vendor/bundle/ruby/3.2.0/gems/rubocop-1.62.1/lib/rubocop/cop/style/array_first_last.rb
rubocop-1.62.1 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.62.0 lib/rubocop/cop/style/array_first_last.rb
rubocop-1.61.0 lib/rubocop/cop/style/array_first_last.rb
mlh-rubocop-config-1.0.3 vendor/bundle/ruby/3.2.0/gems/rubocop-1.60.2/lib/rubocop/cop/style/array_first_last.rb
rubocop-1.60.2 lib/rubocop/cop/style/array_first_last.rb