# frozen_string_literal: true module RuboCop module Cop module Lint # Checks that there are no repeated patterns used in `in` keywords. # # @example # # # bad # case x # in 'first' # do_something # in 'first' # do_something_else # end # # # good # case x # in 'first' # do_something # in 'second' # do_something_else # end # # # bad - repeated alternate patterns with the same conditions don't depend on the order # case x # in foo | bar # first_method # in bar | foo # second_method # end # # # good # case x # in foo | bar # first_method # in bar | baz # second_method # end # # # bad - repeated hash patterns with the same conditions don't depend on the order # case x # in foo: a, bar: b # first_method # in bar: b, foo: a # second_method # end # # # good # case x # in foo: a, bar: b # first_method # in bar: b, baz: c # second_method # end # # # bad - repeated array patterns with elements in the same order # case x # in [foo, bar] # first_method # in [foo, bar] # second_method # end # # # good # case x # in [foo, bar] # first_method # in [bar, foo] # second_method # end # class DuplicateMatchPattern < Base extend TargetRubyVersion MSG = 'Duplicate `in` pattern detected.' minimum_target_ruby_version 2.7 def on_case_match(case_node) case_node.in_pattern_branches.each_with_object(Set.new) do |in_pattern_node, previous| pattern = in_pattern_node.pattern next if previous.add?(pattern_identity(pattern)) add_offense(pattern) end end private def pattern_identity(pattern) if pattern.hash_pattern_type? || pattern.match_alt_type? pattern.children.map(&:source).sort else pattern.source end end end end end end