diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bf6d801908..015c67d126e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * [#7779](https://github.com/rubocop-hq/rubocop/issues/7779): Fix a false positive for `Style/MultilineMethodCallIndentation` when using Ruby 2.7's numbered parameter. ([@koic][]) * [#7733](https://github.com/rubocop-hq/rubocop/issues/7733): Fix rubocop-junit-formatter imcompatibility XML for JUnit formatter. ([@koic][]) +* [#7767](https://github.com/rubocop-hq/rubocop/issues/7767): Skip array literals in `Style/HashTransformValues` and `Style/HashTransformKeys`. ([@tejasbubane][]) ## 0.80.1 (2020-02-29) diff --git a/lib/rubocop/cop/style/hash_transform_keys.rb b/lib/rubocop/cop/style/hash_transform_keys.rb index 84369a5847e..8920a022ebc 100644 --- a/lib/rubocop/cop/style/hash_transform_keys.rb +++ b/lib/rubocop/cop/style/hash_transform_keys.rb @@ -31,7 +31,9 @@ class HashTransformKeys < Cop def_node_matcher :on_bad_each_with_object, <<~PATTERN (block - ({send csend} !(send _ :each_with_index) :each_with_object (hash)) + ({send csend} + !{(send _ :each_with_index) (array ...)} + :each_with_object (hash)) (args (mlhs (arg $_) @@ -55,7 +57,9 @@ class HashTransformKeys < Cop def_node_matcher :on_bad_map_to_h, <<~PATTERN ({send csend} (block - ({send csend} !(send _ :each_with_index) {:map :collect}) + ({send csend} + !{(send _ :each_with_index) (array ...)} + {:map :collect}) (args (arg $_) (arg _val)) diff --git a/lib/rubocop/cop/style/hash_transform_values.rb b/lib/rubocop/cop/style/hash_transform_values.rb index 9c121d7f7b1..d77986cd63c 100644 --- a/lib/rubocop/cop/style/hash_transform_values.rb +++ b/lib/rubocop/cop/style/hash_transform_values.rb @@ -31,7 +31,9 @@ class HashTransformValues < Cop def_node_matcher :on_bad_each_with_object, <<~PATTERN (block - ({send csend} !(send _ :each_with_index) :each_with_object (hash)) + ({send csend} + !{(send _ :each_with_index) (array ...)} + :each_with_object (hash)) (args (mlhs (arg _key) @@ -55,7 +57,9 @@ class HashTransformValues < Cop def_node_matcher :on_bad_map_to_h, <<~PATTERN ({send csend} (block - ({send csend} !(send _ :each_with_index) {:map :collect}) + ({send csend} + !{(send _ :each_with_index) (array ...)} + {:map :collect}) (args (arg _key) (arg $_)) diff --git a/spec/rubocop/cop/style/hash_transform_keys_spec.rb b/spec/rubocop/cop/style/hash_transform_keys_spec.rb index 61e240e25f6..f75aacaded8 100644 --- a/spec/rubocop/cop/style/hash_transform_keys_spec.rb +++ b/spec/rubocop/cop/style/hash_transform_keys_spec.rb @@ -53,6 +53,12 @@ RUBY end + it 'does not flag each_with_object when its receiver is array literal' do + expect_no_offenses(<<~RUBY) + [1, 2, 3].each_with_object({}) {|(k, v), h| h[foo(k)] = v} + RUBY + end + it 'flags _.map{...}.to_h when transform_keys could be used' do expect_offense(<<~RUBY) x.map {|k, v| [k.to_sym, v]}.to_h @@ -79,6 +85,12 @@ expect_no_offenses('x.map {|k, v| [k.to_sym, v]}') end + it 'does not flag key transformation when receiver is array literal' do + expect_no_offenses(<<~RUBY) + [1, 2, 3].map {|k, v| [k.to_sym, v]}.to_h + RUBY + end + it 'correctly autocorrects each_with_object' do corrected = autocorrect_source(<<~RUBY) {a: 1, b: 2}.each_with_object({}) do |(k, v), h| diff --git a/spec/rubocop/cop/style/hash_transform_values_spec.rb b/spec/rubocop/cop/style/hash_transform_values_spec.rb index 2c7bdd0b416..6f57392cf05 100644 --- a/spec/rubocop/cop/style/hash_transform_values_spec.rb +++ b/spec/rubocop/cop/style/hash_transform_values_spec.rb @@ -53,6 +53,12 @@ RUBY end + it 'does not flag each_with_object when receiver is array literal' do + expect_no_offenses(<<~RUBY) + [1, 2, 3].each_with_object({}) {|(k, v), h| h[k] = foo(v)} + RUBY + end + it 'flags _.map {...}.to_h when transform_values could be used' do expect_offense(<<~RUBY) x.map {|k, v| [k, foo(v)]}.to_h @@ -79,6 +85,12 @@ expect_no_offenses('x.map {|k, v| [k, foo(v)]}') end + it 'does not flag value transformation when receiver is array literal' do + expect_no_offenses(<<~RUBY) + [1, 2, 3].map {|k, v| [k, foo(v)]}.to_h + RUBY + end + it 'correctly autocorrects each_with_object' do corrected = autocorrect_source(<<~RUBY) {a: 1, b: 2}.each_with_object({}) {|(k, v), h| h[k] = foo(v)}