lib/rubocop/cop/lint/duplicate_set_element.rb in rubocop-1.69.2 vs lib/rubocop/cop/lint/duplicate_set_element.rb in rubocop-1.70.0

- old
+ new

@@ -1,11 +1,11 @@ # frozen_string_literal: true module RuboCop module Cop module Lint - # Checks for duplicate literal, constant, or variable elements in Set. + # Checks for duplicate literal, constant, or variable elements in Set and SortedSet. # # @example # # # bad # Set[:foo, :bar, :foo] @@ -23,21 +23,32 @@ # [:foo, :bar, :foo].to_set # # # good # [:foo, :bar].to_set # + # # bad + # SortedSet[:foo, :bar, :foo] + # + # # good + # SortedSet[:foo, :bar] + # + # # bad + # SortedSet.new([:foo, :bar, :foo]) + # + # # good + # SortedSet.new([:foo, :bar]) class DuplicateSetElement < Base extend AutoCorrector - MSG = 'Remove the duplicate element in Set.' + MSG = 'Remove the duplicate element in %<class_name>s.' RESTRICT_ON_SEND = %i[\[\] new to_set].freeze # @!method set_init_elements(node) def_node_matcher :set_init_elements, <<~PATTERN { - (send (const {nil? cbase} :Set) :[] $...) - (send (const {nil? cbase} :Set) :new (array $...)) + (send (const {nil? cbase} {:Set :SortedSet}) :[] $...) + (send (const {nil? cbase} {:Set :SortedSet}) :new (array $...)) (call (array $...) :to_set) } PATTERN def on_send(node) @@ -49,21 +60,23 @@ # NOTE: Skip due to the possibility of corner cases where Set elements # may have changing return values if they are not literals, constants, or variables. next if !set_element.literal? && !set_element.const_type? && !set_element.variable? if seen_elements.include?(set_element) - register_offense(set_element, set_elements[index - 1]) + register_offense(set_element, set_elements[index - 1], node) else seen_elements << set_element end end end alias on_csend on_send private - def register_offense(current_element, prev_element) - add_offense(current_element) do |corrector| + def register_offense(current_element, prev_element, node) + class_name = node.receiver.const_type? ? node.receiver.const_name : 'Set' + + add_offense(current_element, message: format(MSG, class_name: class_name)) do |corrector| range = prev_element.source_range.end.join(current_element.source_range.end) corrector.remove(range) end end