From e0c22a3a1714556fd505897435acf31f81185663 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 28 Sep 2023 15:07:04 +0300 Subject: [PATCH 0001/1411] Switch back the docs version --- docs/antora.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/antora.yml b/docs/antora.yml index b4de30cfda13..9c897ea03d1d 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop title: RuboCop # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: '1.56' +version: ~ nav: - modules/ROOT/nav.adoc From 32968e195ad0d9d171e4f6d4528dbf784b8e75f2 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 20 Sep 2023 19:17:41 +0900 Subject: [PATCH 0002/1411] [Fix #12210] Mark `Style/RedundantFilterChain` as unsafe autocorrect Fixes #12210. This PR marks `Style/RedundantFilterChain` as unsafe autocorrect. --- ...rk_style_redundant_filter_chain_as_unsafe_autocorrect.md | 1 + config/default.yml | 2 ++ lib/rubocop/cop/style/redundant_filter_chain.rb | 6 ++++++ 3 files changed, 9 insertions(+) create mode 100644 changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md diff --git a/changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md b/changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md new file mode 100644 index 000000000000..b68c257fae93 --- /dev/null +++ b/changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md @@ -0,0 +1 @@ +* [#12210](https://github.com/rubocop/rubocop/issues/12210): Mark `Style/RedundantFilterChain` as unsafe autocorrect. ([@koic][]) diff --git a/config/default.yml b/config/default.yml index 09fd3e6e8178..b5ca3e3c2c4b 100644 --- a/config/default.yml +++ b/config/default.yml @@ -4920,7 +4920,9 @@ Style/RedundantFilterChain: Identifies usages of `any?`, `empty?`, `none?` or `one?` predicate methods chained to `select`/`filter`/`find_all` and change them to use predicate method instead. Enabled: pending + SafeAutoCorrect: false VersionAdded: '1.52' + VersionChanged: '<>' Style/RedundantFreeze: Description: "Checks usages of Object#freeze on immutable objects." diff --git a/lib/rubocop/cop/style/redundant_filter_chain.rb b/lib/rubocop/cop/style/redundant_filter_chain.rb index 07469537b348..ca5f5173cac1 100644 --- a/lib/rubocop/cop/style/redundant_filter_chain.rb +++ b/lib/rubocop/cop/style/redundant_filter_chain.rb @@ -6,6 +6,12 @@ module Style # Identifies usages of `any?`, `empty?` or `none?` predicate methods # chained to `select`/`filter`/`find_all` and change them to use predicate method instead. # + # @safety + # This cop's autocorrection is unsafe because `array.select.any?` evaluates all elements + # through the `select` method, while `array.any?` uses short-circuit evaluation. + # In other words, `array.select.any?` guarantees the evaluation of every element, + # but `array.any?` does not necessarily evaluate all of them. + # # @example # # bad # arr.select { |x| x > 1 }.any? From 5537b0c1eb7613e38cbb35a59259596efbfc8a2c Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 18 Aug 2023 01:22:32 +0900 Subject: [PATCH 0003/1411] [Fix #12128] Make `Style/GuardClause` aware of `define_method` Fixes #12128. This PR makes `Style/GuardClause` aware of `define_method`. --- ...yle_guard_clause_aware_of_define_method.md | 1 + lib/rubocop/cop/style/guard_clause.rb | 26 ++++ spec/rubocop/cop/style/guard_clause_spec.rb | 126 ++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 changelog/change_make_style_guard_clause_aware_of_define_method.md diff --git a/changelog/change_make_style_guard_clause_aware_of_define_method.md b/changelog/change_make_style_guard_clause_aware_of_define_method.md new file mode 100644 index 000000000000..dd24fbafdaf8 --- /dev/null +++ b/changelog/change_make_style_guard_clause_aware_of_define_method.md @@ -0,0 +1 @@ +* [#12128](https://github.com/rubocop/rubocop/issues/12128): Make `Style/GuardClause` aware of `define_method`. ([@koic][]) diff --git a/lib/rubocop/cop/style/guard_clause.rb b/lib/rubocop/cop/style/guard_clause.rb index ab380992a4fd..10c50f1b87d5 100644 --- a/lib/rubocop/cop/style/guard_clause.rb +++ b/lib/rubocop/cop/style/guard_clause.rb @@ -55,6 +55,25 @@ module Style # foo || raise('exception') if something # ok # + # # bad + # define_method(:test) do + # if something + # work + # end + # end + # + # # good + # define_method(:test) do + # return unless something + # + # work + # end + # + # # also good + # define_method(:test) do + # work if something + # end + # # @example AllowConsecutiveConditionals: false (default) # # bad # def test @@ -110,6 +129,13 @@ def on_def(node) end alias on_defs on_def + def on_block(node) + return unless node.method?(:define_method) || node.method?(:define_singleton_method) + + on_def(node) + end + alias on_numblock on_block + def on_if(node) return if accepted_form?(node) diff --git a/spec/rubocop/cop/style/guard_clause_spec.rb b/spec/rubocop/cop/style/guard_clause_spec.rb index 4b317e71a019..69625365b576 100644 --- a/spec/rubocop/cop/style/guard_clause_spec.rb +++ b/spec/rubocop/cop/style/guard_clause_spec.rb @@ -79,6 +79,120 @@ def func end RUBY end + + it 'reports an offense if `define_method` block body is if / unless without else' do + expect_offense(<<~RUBY) + define_method(:func) do + if _1 + ^^ Use a guard clause (`return unless _1`) instead of wrapping the code inside a conditional expression. + #{body} + end + end + + define_method(:func) do + unless _1 + ^^^^^^ Use a guard clause (`return if _1`) instead of wrapping the code inside a conditional expression. + #{body} + end + end + RUBY + + expect_correction(<<~RUBY) + define_method(:func) do + return unless _1 + #{body} + #{trailing_whitespace} + end + + define_method(:func) do + return if _1 + #{body} + #{trailing_whitespace} + end + RUBY + end + + it 'reports an offense if `define_singleton_method` block body is if / unless without else' do + expect_offense(<<~RUBY) + define_singleton_method(:func) do + if _1 + ^^ Use a guard clause (`return unless _1`) instead of wrapping the code inside a conditional expression. + #{body} + end + end + + define_singleton_method(:func) do + unless _1 + ^^^^^^ Use a guard clause (`return if _1`) instead of wrapping the code inside a conditional expression. + #{body} + end + end + RUBY + + expect_correction(<<~RUBY) + define_singleton_method(:func) do + return unless _1 + #{body} + #{trailing_whitespace} + end + + define_singleton_method(:func) do + return if _1 + #{body} + #{trailing_whitespace} + end + RUBY + end + + it 'reports an offense if `define_method` numblock body is if / unless without else' do + expect_offense(<<~RUBY) + define_method(:func) do + if something + ^^ Use a guard clause (`return unless something`) instead of wrapping the code inside a conditional expression. + #{body} + end + end + + define_method(:func) do + unless something + ^^^^^^ Use a guard clause (`return if something`) instead of wrapping the code inside a conditional expression. + #{body} + end + end + RUBY + + expect_correction(<<~RUBY) + define_method(:func) do + return unless something + #{body} + #{trailing_whitespace} + end + + define_method(:func) do + return if something + #{body} + #{trailing_whitespace} + end + RUBY + end + + it 'accepts an offense if block body ends with if / unless without else' do + expect_no_offenses(<<~RUBY) + foo do + test + if something + #{body} + end + end + + foo do + test + unless something + #{body} + end + end + RUBY + end end it_behaves_like('reports offense', 'work') @@ -97,6 +211,18 @@ def func RUBY end + it 'does not report an offense if block body is if..elsif..end' do + expect_no_offenses(<<~RUBY) + define_method(:func) do + if something + a + elsif something_else + b + end + end + RUBY + end + it "doesn't report an offense if condition has multiple lines" do expect_no_offenses(<<~RUBY) def func From 4bec69e32bad3068fca1abe8f5f8d9a02547ae57 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 17 Aug 2023 01:18:04 +0900 Subject: [PATCH 0004/1411] Make `Style/RedundantFilterChain` aware of `select.present?` Resolves: rubocop/rubocop-rails#1048. This PR makes `Style/RedundantFilterChain` aware of `select.present?` when `AllCops/ActiveSupportExtensionsEnabled: true`. --- ...dant_filter_chain_aware_of_select_present.md | 1 + lib/rubocop/cop/style/redundant_filter_chain.rb | 14 ++++++++++++-- .../cop/style/redundant_filter_chain_spec.rb | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md diff --git a/changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md b/changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md new file mode 100644 index 000000000000..29bf1baccfa5 --- /dev/null +++ b/changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md @@ -0,0 +1 @@ +* [#12126](https://github.com/rubocop/rubocop/pull/12126): Make `Style/RedundantFilterChain` aware of `select.present?` when `ActiveSupportExtensionsEnabled` config is `true`. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_filter_chain.rb b/lib/rubocop/cop/style/redundant_filter_chain.rb index ca5f5173cac1..41c3943e513b 100644 --- a/lib/rubocop/cop/style/redundant_filter_chain.rb +++ b/lib/rubocop/cop/style/redundant_filter_chain.rb @@ -34,6 +34,9 @@ module Style # # good # arr.select { |x| x > 1 }.many? # + # # good + # arr.select { |x| x > 1 }.present? + # # @example AllCops:ActiveSupportExtensionsEnabled: true # # bad # arr.select { |x| x > 1 }.many? @@ -41,12 +44,18 @@ module Style # # good # arr.many? { |x| x > 1 } # + # # bad + # arr.select { |x| x > 1 }.present? + # + # # good + # arr.any? { |x| x > 1 } + # class RedundantFilterChain < Base extend AutoCorrector MSG = 'Use `%s` instead of `%s.%s`.' - RAILS_METHODS = %i[many?].freeze + RAILS_METHODS = %i[many? present?].freeze RESTRICT_ON_SEND = (%i[any? empty? none? one?] + RAILS_METHODS).freeze # @!method select_predicate?(node) @@ -64,7 +73,8 @@ class RedundantFilterChain < Base empty?: :none?, none?: :none?, one?: :one?, - many?: :many? + many?: :many?, + present?: :any? }.freeze private_constant :REPLACEMENT_METHODS diff --git a/spec/rubocop/cop/style/redundant_filter_chain_spec.rb b/spec/rubocop/cop/style/redundant_filter_chain_spec.rb index 97b37d2654a5..546530f00c8f 100644 --- a/spec/rubocop/cop/style/redundant_filter_chain_spec.rb +++ b/spec/rubocop/cop/style/redundant_filter_chain_spec.rb @@ -56,6 +56,12 @@ RUBY end + it "does not register an offense when using `##{method}` followed by `#present?`" do + expect_no_offenses(<<~RUBY) + arr.#{method} { |x| x > 1 }.present? + RUBY + end + it "does not register an offense when using `##{method}` without a block followed by `#any?`" do expect_no_offenses(<<~RUBY) relation.#{method}(:name).any? @@ -92,5 +98,16 @@ arr.many? { |x| x > 1 } RUBY end + + it 'registers an offense when using `#select` followed by `#present?`' do + expect_offense(<<~RUBY) + arr.select { |x| x > 1 }.present? + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `any?` instead of `select.present?`. + RUBY + + expect_correction(<<~RUBY) + arr.any? { |x| x > 1 } + RUBY + end end end From 91d3a8138fb27e285c6a08c9e10f3128aa5af4ef Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 11 Aug 2023 01:53:52 +0900 Subject: [PATCH 0005/1411] [Fix #12097] Mark unsafe autocorrect for `Style/ClassEqualityComparison` Fixes #12097. This PR marks unsafe autocorrect for `Style/ClassEqualityComparison` because there is no guarantee that the constant `Foo` exists when autocorrecting `var.class.name == 'Foo'` to `var.instance_of?(Foo)`. --- ...yle_class_equality_comparison_as_unsafe_autocorrection.md | 1 + config/default.yml | 2 ++ lib/rubocop/cop/style/class_equality_comparison.rb | 5 +++++ 3 files changed, 8 insertions(+) create mode 100644 changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md diff --git a/changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md b/changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md new file mode 100644 index 000000000000..9b07c7fd611d --- /dev/null +++ b/changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md @@ -0,0 +1 @@ +* [#12097](https://github.com/rubocop/rubocop/issues/12097): Mark unsafe autocorrect for `Style/ClassEqualityComparison`. ([@koic][]) diff --git a/config/default.yml b/config/default.yml index b5ca3e3c2c4b..8bb508a3ad41 100644 --- a/config/default.yml +++ b/config/default.yml @@ -3354,7 +3354,9 @@ Style/ClassEqualityComparison: Description: 'Enforces the use of `Object#instance_of?` instead of class comparison for equality.' StyleGuide: '#instance-of-vs-class-comparison' Enabled: true + SafeAutoCorrect: false VersionAdded: '0.93' + VersionChanged: '<>' AllowedMethods: - == - equal? diff --git a/lib/rubocop/cop/style/class_equality_comparison.rb b/lib/rubocop/cop/style/class_equality_comparison.rb index a242a8578be1..bd448ced6b32 100644 --- a/lib/rubocop/cop/style/class_equality_comparison.rb +++ b/lib/rubocop/cop/style/class_equality_comparison.rb @@ -8,6 +8,11 @@ module Style # `==`, `equal?`, and `eql?` custom method definitions are allowed by default. # These are customizable with `AllowedMethods` option. # + # @safety + # This cop's autocorrection is unsafe because there is no guarantee that + # the constant `Foo` exists when autocorrecting `var.class.name == 'Foo'` to + # `var.instance_of?(Foo)`. + # # @example # # bad # var.class == Date From 3bc4ebe50c666f8687d3a3ce6a37cbd398152cf4 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 29 Sep 2023 15:55:52 +0900 Subject: [PATCH 0006/1411] Fix false negatives for `Style/MultilineBlockChain` This PR fixes false negatives for `Style/MultilineBlockChain` when using multiline block chain with safe navigation operator. --- ...false_negatives_for_style_multiline_block_chain.md | 1 + lib/rubocop/cop/style/multiline_block_chain.rb | 2 +- spec/rubocop/cop/style/multiline_block_chain_spec.rb | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_false_negatives_for_style_multiline_block_chain.md diff --git a/changelog/fix_false_negatives_for_style_multiline_block_chain.md b/changelog/fix_false_negatives_for_style_multiline_block_chain.md new file mode 100644 index 000000000000..1bbd5dea4712 --- /dev/null +++ b/changelog/fix_false_negatives_for_style_multiline_block_chain.md @@ -0,0 +1 @@ +* [#12228](https://github.com/rubocop/rubocop/pull/12228): Fix false negatives for `Style/MultilineBlockChain` when using multiline block chain with safe navigation operator. ([@koic][]) diff --git a/lib/rubocop/cop/style/multiline_block_chain.rb b/lib/rubocop/cop/style/multiline_block_chain.rb index 7f9de566ae38..e35eca2edf5b 100644 --- a/lib/rubocop/cop/style/multiline_block_chain.rb +++ b/lib/rubocop/cop/style/multiline_block_chain.rb @@ -28,7 +28,7 @@ class MultilineBlockChain < Base MSG = 'Avoid multi-line chains of blocks.' def on_block(node) - node.send_node.each_node(:send) do |send_node| + node.send_node.each_node(:send, :csend) do |send_node| receiver = send_node.receiver next unless (receiver&.block_type? || receiver&.numblock_type?) && receiver&.multiline? diff --git a/spec/rubocop/cop/style/multiline_block_chain_spec.rb b/spec/rubocop/cop/style/multiline_block_chain_spec.rb index 2e8330fa9937..d997b8bd6228 100644 --- a/spec/rubocop/cop/style/multiline_block_chain_spec.rb +++ b/spec/rubocop/cop/style/multiline_block_chain_spec.rb @@ -13,6 +13,17 @@ RUBY end + it 'registers an offense for a simple case with safe navigation operator' do + expect_offense(<<~RUBY) + a do + b + end&.c do + ^^^^^^ Avoid multi-line chains of blocks. + d + end + RUBY + end + it 'registers an offense for a slightly more complicated case' do expect_offense(<<~RUBY) a do From 08f475dc46585ee6d8f9afd609a9e36f7b9758e2 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 29 Sep 2023 01:02:48 +0900 Subject: [PATCH 0007/1411] Add new `Style/SingleLineDoEndBlock` cop This PR adds new `Style/SingleLineDoEndBlock` cop that checks for single-line `do`...`end` blocks. ```ruby # bad foo do |arg| bar(arg) end # good foo do |arg| bar(arg) end # bad ->(arg) do bar(arg) end # good ->(arg) { bar(arg) } ``` In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic` in `Style/BlockDelimiters`. It can also be detected by this cop if it is written by handcraft. So I decided to introduce this new cop instead of an autocorrect extension of `Style/BlockDelimiters`. --- ..._add_new_style_single_line_do_end_block.md | 1 + config/default.yml | 5 + lib/rubocop.rb | 1 + .../cop/style/single_line_do_end_block.rb | 65 ++++++++++++ .../style/single_line_do_end_block_spec.rb | 99 +++++++++++++++++++ spec/rubocop/cop/team_spec.rb | 2 +- 6 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 changelog/new_add_new_style_single_line_do_end_block.md create mode 100644 lib/rubocop/cop/style/single_line_do_end_block.rb create mode 100644 spec/rubocop/cop/style/single_line_do_end_block_spec.rb diff --git a/changelog/new_add_new_style_single_line_do_end_block.md b/changelog/new_add_new_style_single_line_do_end_block.md new file mode 100644 index 000000000000..13b36be51c5d --- /dev/null +++ b/changelog/new_add_new_style_single_line_do_end_block.md @@ -0,0 +1 @@ +* [#12227](https://github.com/rubocop/rubocop/pull/12227): Add new `Style/SingleLineDoEndBlock` cop. ([@koic][]) diff --git a/config/default.yml b/config/default.yml index 8bb508a3ad41..fa0a197ee65c 100644 --- a/config/default.yml +++ b/config/default.yml @@ -5186,6 +5186,11 @@ Style/SingleLineBlockParams: - acc - elem +Style/SingleLineDoEndBlock: + Description: 'Checks for single-line `do`...`end` blocks.' + Enabled: pending + VersionAdded: '<>' + Style/SingleLineMethods: Description: 'Avoid single-line methods.' StyleGuide: '#no-single-line-methods' diff --git a/lib/rubocop.rb b/lib/rubocop.rb index 725a1daaba6f..5f62fc32166e 100644 --- a/lib/rubocop.rb +++ b/lib/rubocop.rb @@ -580,6 +580,7 @@ require_relative 'rubocop/cop/style/redundant_self_assignment' require_relative 'rubocop/cop/style/redundant_self_assignment_branch' require_relative 'rubocop/cop/style/require_order' +require_relative 'rubocop/cop/style/single_line_do_end_block' require_relative 'rubocop/cop/style/sole_nested_conditional' require_relative 'rubocop/cop/style/static_class' require_relative 'rubocop/cop/style/map_compact_with_conditional_block' diff --git a/lib/rubocop/cop/style/single_line_do_end_block.rb b/lib/rubocop/cop/style/single_line_do_end_block.rb new file mode 100644 index 000000000000..4d738a69c406 --- /dev/null +++ b/lib/rubocop/cop/style/single_line_do_end_block.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Style + # Checks for single-line `do`...`end` block. + # + # In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic` + # in `Style/BlockDelimiters`. The autocorrection maintains the `do` ... `end` syntax to + # preserve semantics and does not change it to `{`...`}` block. + # + # @example + # + # # bad + # foo do |arg| bar(arg) end + # + # # good + # foo do |arg| + # bar(arg) + # end + # + # # bad + # ->(arg) do bar(arg) end + # + # # good + # ->(arg) { bar(arg) } + # + class SingleLineDoEndBlock < Base + extend AutoCorrector + + MSG = 'Prefer multiline `do`...`end` block.' + + def on_block(node) + return if !node.single_line? || node.braces? + + add_offense(node) do |corrector| + corrector.insert_after(do_line(node), "\n") + + node_body = node.body + + if node_body.respond_to?(:heredoc?) && node_body.heredoc? + corrector.remove(node.loc.end) + corrector.insert_after(node_body.loc.heredoc_end, "\nend") + else + corrector.insert_after(node_body, "\n") + end + end + end + alias on_numblock on_block + + private + + def do_line(node) + if node.numblock_type? || node.arguments.children.empty? || node.send_node.lambda_literal? + node.loc.begin + else + node.arguments + end + end + + def x(corrector, node); end + end + end + end +end diff --git a/spec/rubocop/cop/style/single_line_do_end_block_spec.rb b/spec/rubocop/cop/style/single_line_do_end_block_spec.rb new file mode 100644 index 000000000000..cff9d124a0ef --- /dev/null +++ b/spec/rubocop/cop/style/single_line_do_end_block_spec.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +RSpec.describe RuboCop::Cop::Style::SingleLineDoEndBlock, :config do + it 'registers an offense when using single line `do`...`end`' do + expect_offense(<<~RUBY) + foo do bar end + ^^^^^^^^^^^^^^ Prefer multiline `do`...`end` block. + RUBY + + expect_correction(<<~RUBY) + foo do + bar + end + RUBY + end + + it 'registers an offense when using single line `do`...`end` with block argument' do + expect_offense(<<~RUBY) + foo do |arg| bar(arg) end + ^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer multiline `do`...`end` block. + RUBY + + expect_correction(<<~RUBY) + foo do |arg| + bar(arg) + end + RUBY + end + + it 'registers an offense when using single line `do`...`end` with numbered block argument' do + expect_offense(<<~RUBY) + foo do bar(_1) end + ^^^^^^^^^^^^^^^^^^ Prefer multiline `do`...`end` block. + RUBY + + expect_correction(<<~RUBY) + foo do + bar(_1) + end + RUBY + end + + it 'registers an offense when using single line `do`...`end` with heredoc body' do + expect_offense(<<~RUBY) + foo do <<~EOS end + ^^^^^^^^^^^^^^^^^ Prefer multiline `do`...`end` block. + text + EOS + RUBY + + expect_correction(<<~RUBY) + foo do + <<~EOS#{' '} + text + EOS + end + RUBY + end + + it 'registers an offense when using single line `do`...`end` with `->` block' do + expect_offense(<<~RUBY) + ->(arg) do foo arg end + ^^^^^^^^^^^^^^^^^^^^^^ Prefer multiline `do`...`end` block. + RUBY + + expect_correction(<<~RUBY) + ->(arg) do + foo arg + end + RUBY + end + + it 'registers an offense when using single line `do`...`end` with `lambda` block' do + expect_offense(<<~RUBY) + lambda do |arg| foo(arg) end + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer multiline `do`...`end` block. + RUBY + + expect_correction(<<~RUBY) + lambda do |arg| + foo(arg) + end + RUBY + end + + it 'does not register an offense when using multiline `do`...`end`' do + expect_no_offenses(<<~RUBY) + foo do + bar + end + RUBY + end + + it 'does not register an offense when using single line `{`...`}`' do + expect_no_offenses(<<~RUBY) + foo { bar } + RUBY + end +end diff --git a/spec/rubocop/cop/team_spec.rb b/spec/rubocop/cop/team_spec.rb index c779bedf4bce..2b373d5a8e63 100644 --- a/spec/rubocop/cop/team_spec.rb +++ b/spec/rubocop/cop/team_spec.rb @@ -200,7 +200,7 @@ def a let(:file_path) { 'Gemfile' } - let(:buggy_correction) { ->(_corrector) do raise cause end } + let(:buggy_correction) { ->(_corrector) { raise cause } } let(:options) { { autocorrect: true } } let(:cause) { StandardError.new('cause') } From 5f1774992f434654503c5e71a4b91725a5fa10c6 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 30 Sep 2023 00:31:58 +0900 Subject: [PATCH 0008/1411] [Fix #12226] Fix false positives for `Layout/MultilineMethodCallIndentation` Fixes #12226. This PR fixes false positives for `Layout/MultilineMethodCallIndentation` when aligning methods in multiline block chain. --- ...ayout_multiline_method_call_indentation.md | 1 + .../multiline_method_call_indentation.rb | 11 +++++ .../multiline_method_call_indentation_spec.rb | 40 +++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md diff --git a/changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md b/changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md new file mode 100644 index 000000000000..e40246963b90 --- /dev/null +++ b/changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md @@ -0,0 +1 @@ +* [#12226](https://github.com/rubocop/rubocop/issues/12226): Fix false positives for `Layout/MultilineMethodCallIndentation` when aligning methods in multiline block chain. ([@koic][]) diff --git a/lib/rubocop/cop/layout/multiline_method_call_indentation.rb b/lib/rubocop/cop/layout/multiline_method_call_indentation.rb index 5e6a825316d2..aaaeea54c946 100644 --- a/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +++ b/lib/rubocop/cop/layout/multiline_method_call_indentation.rb @@ -204,6 +204,10 @@ def semantic_alignment_node(node) dot_right_above = get_dot_right_above(node) return dot_right_above if dot_right_above + if (multiline_block_chain_node = find_multiline_block_chain_node(node)) + return multiline_block_chain_node + end + node = first_call_has_a_dot(node) return if node.loc.dot.line != node.first_line @@ -219,6 +223,13 @@ def get_dot_right_above(node) end end + def find_multiline_block_chain_node(node) + return unless (block_node = node.each_descendant(:block, :numblock).first) + return unless block_node.multiline? && block_node.parent.call_type? + + block_node.parent + end + def first_call_has_a_dot(node) # descend to root of method chain node = node.receiver while node.receiver diff --git a/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb b/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb index a4f646796917..f141d037fd67 100644 --- a/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb +++ b/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb @@ -693,6 +693,46 @@ def a RUBY end + it 'registers an offense and corrects misaligned methods in multiline block chain' do + expect_offense(<<~RUBY) + do_something.foo do + end.bar + .baz + ^^^^ Align `.baz` with `.bar` on line 2. + RUBY + + expect_correction(<<~RUBY) + do_something.foo do + end.bar + .baz + RUBY + end + + it 'accepts aligned methods in multiline block chain' do + expect_no_offenses(<<~RUBY) + do_something.foo do + end.bar + .baz + RUBY + end + + it 'accepts aligned methods in multiline numbered block chain' do + expect_no_offenses(<<~RUBY) + do_something.foo do + bar(_1) + end.baz + .qux + RUBY + end + + it 'accepts aligned methods in multiline block chain with safe navigation operator' do + expect_no_offenses(<<~RUBY) + do_something.foo do + end&.bar + &.baz + RUBY + end + it 'registers an offense and corrects misaligned methods in local variable assignment' do expect_offense(<<~RUBY) a = b.c. From c9819f1ea4f4ec0361dcfc874844233253e56cb4 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 30 Sep 2023 14:37:35 +0900 Subject: [PATCH 0009/1411] Tweak autocorrection for `Style/RedundantBegin` This PR tweaks autocorrection for `Style/RedundantBegin` when using endless method definition with redundant `begin`. ```ruby def foo = begin bar end ``` ## Before ```console % bundle exec rubocop --only Style/RedundantBegin -a (snip) example.rb:1:11: C: [Corrected] Style/RedundantBegin: Redundant begin block detected. def foo = begin ^^^^^ 1 file inspected, 1 offense detected, 1 offense corrected ``` ```ruby def foo = bar ``` ## After ```ruby def foo = bar ``` This would be more closer to a one-liner endless idiom. --- lib/rubocop/cop/style/redundant_begin.rb | 10 +++++++++- spec/rubocop/cop/style/redundant_begin_spec.rb | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/rubocop/cop/style/redundant_begin.rb b/lib/rubocop/cop/style/redundant_begin.rb index d603112fe1fe..efb1b70d7de7 100644 --- a/lib/rubocop/cop/style/redundant_begin.rb +++ b/lib/rubocop/cop/style/redundant_begin.rb @@ -114,7 +114,7 @@ def register_offense(node) if node.parent&.assignment? replace_begin_with_statement(corrector, offense_range, node) else - corrector.remove(offense_range) + remove_begin(corrector, offense_range, node) end if use_modifier_form_after_multiline_begin_block?(node) @@ -136,6 +136,14 @@ def replace_begin_with_statement(corrector, offense_range, node) restore_removed_comments(corrector, offense_range, node, first_child) end + def remove_begin(corrector, offense_range, node) + if node.parent.respond_to?(:endless?) && node.parent.endless? + offense_range = range_with_surrounding_space(offense_range, newlines: true) + end + + corrector.remove(offense_range) + end + # Restore comments that occur between "begin" and "first_child". # These comments will be moved to above the assignment line. def restore_removed_comments(corrector, offense_range, node, first_child) diff --git a/spec/rubocop/cop/style/redundant_begin_spec.rb b/spec/rubocop/cop/style/redundant_begin_spec.rb index f6c67afb1f97..a37bde8049cc 100644 --- a/spec/rubocop/cop/style/redundant_begin_spec.rb +++ b/spec/rubocop/cop/style/redundant_begin_spec.rb @@ -579,7 +579,7 @@ def foo = begin end RUBY - expect_correction("def foo = \n bar\n\n") + expect_correction("def foo = bar\n\n") end it 'accepts when `begin` block has multiple statements' do From 80de379af60a4df60a9e6707da1c3056e9d233ea Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 1 Oct 2023 18:41:32 +0900 Subject: [PATCH 0010/1411] [Docs] Tweak docs for `Metrics/BlockLength` and `Metrics/ClassLength` Move `NOTE:` above `@example`. --- lib/rubocop/cop/metrics/block_length.rb | 2 +- lib/rubocop/cop/metrics/class_length.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/rubocop/cop/metrics/block_length.rb b/lib/rubocop/cop/metrics/block_length.rb index 11c9957cff3f..29c413ddb8a3 100644 --- a/lib/rubocop/cop/metrics/block_length.rb +++ b/lib/rubocop/cop/metrics/block_length.rb @@ -12,6 +12,7 @@ module Metrics # Available are: 'array', 'hash', 'heredoc', and 'method_call'. Each construct # will be counted as one line regardless of its actual size. # + # NOTE: This cop does not apply for `Struct` definitions. # # NOTE: The `ExcludedMethods` configuration is deprecated and only kept # for backwards compatibility. Please use `AllowedMethods` and `AllowedPatterns` @@ -40,7 +41,6 @@ module Metrics # ) # end # 6 points # - # NOTE: This cop does not apply for `Struct` definitions. class BlockLength < Base include CodeLength include AllowedMethods diff --git a/lib/rubocop/cop/metrics/class_length.rb b/lib/rubocop/cop/metrics/class_length.rb index 3aedb63a4fb7..d6b937579819 100644 --- a/lib/rubocop/cop/metrics/class_length.rb +++ b/lib/rubocop/cop/metrics/class_length.rb @@ -11,6 +11,8 @@ module Metrics # Available are: 'array', 'hash', 'heredoc', and 'method_call'. Each construct # will be counted as one line regardless of its actual size. # + # NOTE: This cop also applies for `Struct` definitions. + # # @example CountAsOne: ['array', 'heredoc', 'method_call'] # # class Foo @@ -34,8 +36,6 @@ module Metrics # ) # end # 6 points # - # - # NOTE: This cop also applies for `Struct` definitions. class ClassLength < Base include CodeLength From 948d64106d2eaa4058a3dde452c58b4728a24c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Nisbl=C3=A9?= Date: Sun, 1 Oct 2023 13:29:29 +0200 Subject: [PATCH 0011/1411] Enable auto parallel inspection when config file is specified --- ...to_parallel_inspection_when_config_file.md | 1 + lib/rubocop/cli.rb | 2 +- spec/rubocop/cli_spec.rb | 19 ++++++++++++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 changelog/change_enable_auto_parallel_inspection_when_config_file.md diff --git a/changelog/change_enable_auto_parallel_inspection_when_config_file.md b/changelog/change_enable_auto_parallel_inspection_when_config_file.md new file mode 100644 index 000000000000..ca4ecca89c30 --- /dev/null +++ b/changelog/change_enable_auto_parallel_inspection_when_config_file.md @@ -0,0 +1 @@ +* [#12235](https://github.com/rubocop/rubocop/pull/12235): Enable auto parallel inspection when config file is specified. ([@aboutNisblee][]) diff --git a/lib/rubocop/cli.rb b/lib/rubocop/cli.rb index e595149cbac4..8d5711b5dced 100644 --- a/lib/rubocop/cli.rb +++ b/lib/rubocop/cli.rb @@ -11,7 +11,7 @@ class CLI STATUS_ERROR = 2 STATUS_INTERRUPTED = Signal.list['INT'] + 128 DEFAULT_PARALLEL_OPTIONS = %i[ - color debug display_style_guide display_time display_only_fail_level_offenses + color config debug display_style_guide display_time display_only_fail_level_offenses display_only_failed except extra_details fail_level fix_layout format ignore_disable_comments lint only only_guide_cops require safe autocorrect safe_autocorrect autocorrect_all diff --git a/spec/rubocop/cli_spec.rb b/spec/rubocop/cli_spec.rb index 8857f7d1bd6c..2725b21f1803 100644 --- a/spec/rubocop/cli_spec.rb +++ b/spec/rubocop/cli_spec.rb @@ -220,7 +220,7 @@ def and_with_args # In other words, even if no option is specified, it will be parallelized by default. describe 'when parallel static by default' do context 'when specifying `--debug` option only`' do - it 'fails with an error message' do + it 'uses parallel inspection' do create_file('example1.rb', <<~RUBY) # frozen_string_literal: true @@ -231,6 +231,19 @@ def and_with_args end end + context 'when specifying configuration file' do + it 'uses parallel inspection' do + create_file('example1.rb', <<~RUBY) + # frozen_string_literal: true + + puts 'hello' + RUBY + create_empty_file('.rubocop.yml') + expect(cli.run(['--debug', '--config', '.rubocop.yml'])).to eq(0) + expect($stdout.string.include?('Use parallel by default.')).to be(true) + end + end + context 'when specifying `--debug` and `-a` options`' do it 'uses parallel inspection when correcting the file' do create_file('example1.rb', <<~RUBY) @@ -249,7 +262,7 @@ def and_with_args end context 'when setting `UseCache: true`' do - it 'fails with an error message' do + it 'uses parallel inspection' do create_file('example.rb', <<~RUBY) # frozen_string_literal: true @@ -265,7 +278,7 @@ def and_with_args end context 'when setting `UseCache: false`' do - it 'fails with an error message' do + it 'does not use parallel inspection' do create_file('example.rb', <<~RUBY) # frozen_string_literal: true From 5344c784a9a89be116fb3f7c447baa1188d5a239 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Mon, 2 Oct 2023 17:37:44 +0900 Subject: [PATCH 0012/1411] [Fix #12237] Fix an error for `Style/NestedTernaryOperator` Fixes #12237. This PR fixes an error for `Style/NestedTernaryOperator` when a ternary operator has a nested ternary operator within an `if`. --- ...error_for_style_nested_ternary_operator.md | 1 + .../cop/style/nested_ternary_operator.rb | 14 +++-------- .../cop/style/nested_ternary_operator_spec.rb | 23 +++++++++++++++++++ 3 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 changelog/fix_an_error_for_style_nested_ternary_operator.md diff --git a/changelog/fix_an_error_for_style_nested_ternary_operator.md b/changelog/fix_an_error_for_style_nested_ternary_operator.md new file mode 100644 index 000000000000..41b33fb4f5f7 --- /dev/null +++ b/changelog/fix_an_error_for_style_nested_ternary_operator.md @@ -0,0 +1 @@ +* [#12237](https://github.com/rubocop/rubocop/issues/12237): Fix an error for `Style/NestedTernaryOperator` when a ternary operator has a nested ternary operator within an `if`. ([@koic][]) diff --git a/lib/rubocop/cop/style/nested_ternary_operator.rb b/lib/rubocop/cop/style/nested_ternary_operator.rb index 9ee729fd44bf..757dd97273b5 100644 --- a/lib/rubocop/cop/style/nested_ternary_operator.rb +++ b/lib/rubocop/cop/style/nested_ternary_operator.rb @@ -27,24 +27,16 @@ def on_if(node) node.each_descendant(:if).select(&:ternary?).each do |nested_ternary| add_offense(nested_ternary) do |corrector| - if_node = if_node(nested_ternary) - next if part_of_ignored_node?(if_node) + next if part_of_ignored_node?(node) - autocorrect(corrector, if_node) - ignore_node(if_node) + autocorrect(corrector, node) + ignore_node(node) end end end private - def if_node(node) - node = node.parent - return node if node.if_type? - - if_node(node) - end - def autocorrect(corrector, if_node) replace_loc_and_whitespace(corrector, if_node.loc.question, "\n") replace_loc_and_whitespace(corrector, if_node.loc.colon, "\nelse\n") diff --git a/spec/rubocop/cop/style/nested_ternary_operator_spec.rb b/spec/rubocop/cop/style/nested_ternary_operator_spec.rb index c5983e9dce49..7380451cab61 100644 --- a/spec/rubocop/cop/style/nested_ternary_operator_spec.rb +++ b/spec/rubocop/cop/style/nested_ternary_operator_spec.rb @@ -47,6 +47,29 @@ RUBY end + it 'registers an offense when a ternary operator has a nested ternary operator within an `if`' do + expect_offense(<<~RUBY) + a ? ( + if b + c ? 1 : 2 + ^^^^^^^^^ Ternary operators must not be nested. Prefer `if` or `else` constructs instead. + end + ) : 3 + RUBY + + expect_correction(<<~RUBY) + if a + + if b + c ? 1 : 2 + end + + else + 3 + end + RUBY + end + it 'accepts a non-nested ternary operator within an if' do expect_no_offenses(<<~RUBY) a = if x From 65f10c1146aa52b4b12ee6623e84a5d881176acb Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 3 Oct 2023 12:56:31 +0900 Subject: [PATCH 0013/1411] Fix a build error This PR fixes the following build error in the codespell: ```console Resulting CLI options --check-filenames --check-hidden --skip ./.git --ignore-words codespell.txt Error: ./CHANGELOG.md:3178: Mange ==> Manage Error: ./CHANGELOG.md:7143: Mange ==> Manage Error: ./CHANGELOG.md:7143: Mange ==> Manage Error: ./relnotes/v0.68.0.md:7: Mange ==> Manage Error: ./relnotes/v0.68.0.md:49: Mange ==> Manage Error: ./relnotes/v0.68.0.md:49: Mange ==> Manage Codespell found one or more problems ``` https://github.com/rubocop/rubocop/actions/runs/6388440493/job/17338272269 `Mange` is a account name, not a typo. --- codespell.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/codespell.txt b/codespell.txt index d8d7bcd5bd7a..70c149a49703 100644 --- a/codespell.txt +++ b/codespell.txt @@ -4,6 +4,7 @@ enviromnent filetest fo irregardless +mange ofo thi upto From 45174dc6170b63e9ed812149cc49993712b1afa7 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 3 Oct 2023 12:46:20 +0900 Subject: [PATCH 0014/1411] [Fix #12231] Fix a false negative for `Metrics/ModuleLength` Fixes #12231. This PR fixes a false negative for `Metrics/ModuleLength` when defining a singleton class in a module. --- ...alse_negative_for_metrics_module_length.md | 1 + .../metrics/utils/code_length_calculator.rb | 4 +- .../rubocop/cop/metrics/module_length_spec.rb | 37 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 changelog/fix_a_false_negative_for_metrics_module_length.md diff --git a/changelog/fix_a_false_negative_for_metrics_module_length.md b/changelog/fix_a_false_negative_for_metrics_module_length.md new file mode 100644 index 000000000000..4684fda6bd43 --- /dev/null +++ b/changelog/fix_a_false_negative_for_metrics_module_length.md @@ -0,0 +1 @@ +* [#12231](https://github.com/rubocop/rubocop/issues/12231): Fix a false negative for `Metrics/ModuleLength` when defining a singleton class in a module. ([@koic][]) diff --git a/lib/rubocop/cop/metrics/utils/code_length_calculator.rb b/lib/rubocop/cop/metrics/utils/code_length_calculator.rb index 28c5466d496a..2ae7897d0daf 100644 --- a/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +++ b/lib/rubocop/cop/metrics/utils/code_length_calculator.rb @@ -10,7 +10,7 @@ class CodeLengthCalculator include Util FOLDABLE_TYPES = %i[array hash heredoc send csend].freeze - CLASSLIKE_TYPES = %i[class module sclass].freeze + CLASSLIKE_TYPES = %i[class module].freeze private_constant :FOLDABLE_TYPES, :CLASSLIKE_TYPES def initialize(node, processed_source, count_comments: false, foldable_types: []) @@ -145,7 +145,7 @@ def foldable_node?(node) def extract_body(node) case node.type - when :class, :module, :block, :numblock, :def, :defs + when :class, :module, :sclass, :block, :numblock, :def, :defs node.body when :casgn _scope, _name, value = *node diff --git a/spec/rubocop/cop/metrics/module_length_spec.rb b/spec/rubocop/cop/metrics/module_length_spec.rb index f6633494a65b..46f1555473ff 100644 --- a/spec/rubocop/cop/metrics/module_length_spec.rb +++ b/spec/rubocop/cop/metrics/module_length_spec.rb @@ -160,6 +160,43 @@ class TestTwo RUBY end + it 'rejects a module with more than 5 lines including its singleton class' do + expect_offense(<<~RUBY) + module Test + ^^^^^^^^^^^ Module has too many lines. [8/5] + class << self + a = 1 + a = 2 + a = 3 + a = 4 + a = 5 + a = 6 + end + end + RUBY + end + + it 'rejects a module with more than 5 lines that belong to the module directly and including its singleton class' do + expect_offense(<<~RUBY) + module NamespaceModule + ^^^^^^^^^^^^^^^^^^^^^^ Module has too many lines. [13/5] + class << self + a = 1 + a = 2 + a = 3 + a = 4 + a = 5 + end + a = 1 + a = 2 + a = 3 + a = 4 + a = 5 + a = 6 + end + RUBY + end + it 'rejects a module with 6 lines that belong to the module directly' do expect_offense(<<~RUBY) module NamespaceModule From 76c2bc551d1b08a9e34eec1d29d22536d8ba1991 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 4 Oct 2023 19:14:33 +0900 Subject: [PATCH 0015/1411] [Fix #12198] Fix an error for flip-flop with beginless or endless ranges Fixes #12198. Parser 3.2.2.4 includes https://github.com/whitequark/parser/pull/946. This PR requires Parser 3.2.2.4+ to fix an error for flip-flop with beginless or endless ranges. --- ...x_an_error_for_flip_flop_with_beginless_or_endless_ranges.md | 1 + rubocop.gemspec | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md diff --git a/changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md b/changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md new file mode 100644 index 000000000000..2a4c1e803eee --- /dev/null +++ b/changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md @@ -0,0 +1 @@ +* [#12198](https://github.com/rubocop/rubocop/issues/12198): Fix an error for flip-flop with beginless or endless ranges. ([@koic][]) diff --git a/rubocop.gemspec b/rubocop.gemspec index 09720b1c27ab..d0c1add6994e 100644 --- a/rubocop.gemspec +++ b/rubocop.gemspec @@ -35,7 +35,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency('json', '~> 2.3') s.add_runtime_dependency('language_server-protocol', '>= 3.17.0') s.add_runtime_dependency('parallel', '~> 1.10') - s.add_runtime_dependency('parser', '>= 3.2.2.3') + s.add_runtime_dependency('parser', '>= 3.2.2.4') s.add_runtime_dependency('rainbow', '>= 2.2.2', '< 4.0') s.add_runtime_dependency('regexp_parser', '>= 1.8', '< 3.0') s.add_runtime_dependency('rexml', '>= 3.2.5', '< 4.0') From bd214bd9e9c4ead369b4a20ec329897e8dbb288c Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 5 Oct 2023 00:42:14 +0900 Subject: [PATCH 0016/1411] [Fix #12244] Fix a false negative for `Lint/Debugger` Fixes #12244. This PR fixes a false negative for `Lint/Debugger` when using debugger method inside block. --- .../fix_a_false_negative_for_lint_debugger.md | 1 + lib/rubocop/cop/lint/debugger.rb | 11 +++++++- spec/rubocop/cop/lint/debugger_spec.rb | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_a_false_negative_for_lint_debugger.md diff --git a/changelog/fix_a_false_negative_for_lint_debugger.md b/changelog/fix_a_false_negative_for_lint_debugger.md new file mode 100644 index 000000000000..ef3f8be44e35 --- /dev/null +++ b/changelog/fix_a_false_negative_for_lint_debugger.md @@ -0,0 +1 @@ +* [#12244](https://github.com/rubocop/rubocop/issues/12244): Fix a false negative for `Lint/Debugger` when using debugger method inside block. ([@koic][]) diff --git a/lib/rubocop/cop/lint/debugger.rb b/lib/rubocop/cop/lint/debugger.rb index 2bbb25317334..d29e6074fd6e 100644 --- a/lib/rubocop/cop/lint/debugger.rb +++ b/lib/rubocop/cop/lint/debugger.rb @@ -95,8 +95,11 @@ def debugger_method?(send_node) def assumed_usage_context?(node) # Basically, debugger methods are not used as a method argument without arguments. return false unless node.arguments.empty? && node.each_ancestor(:send, :csend).any? + return true if assumed_argument?(node) - node.each_ancestor.none?(&:lambda_or_proc?) + node.each_ancestor.none? do |ancestor| + ancestor.block_type? || ancestor.numblock_type? || ancestor.lambda_or_proc? + end end def chained_method_name(send_node) @@ -109,6 +112,12 @@ def chained_method_name(send_node) end chained_method_name end + + def assumed_argument?(node) + parent = node.parent + + parent.call_type? || parent.literal? || parent.pair_type? + end end end end diff --git a/spec/rubocop/cop/lint/debugger_spec.rb b/spec/rubocop/cop/lint/debugger_spec.rb index d71949429ca4..d2d1c2d16200 100644 --- a/spec/rubocop/cop/lint/debugger_spec.rb +++ b/spec/rubocop/cop/lint/debugger_spec.rb @@ -23,6 +23,23 @@ RUBY end + it 'registers an offense for a `custom_debugger` call when used in block' do + expect_offense(<<~RUBY) + x.y = do_something { custom_debugger } + ^^^^^^^^^^^^^^^ Remove debugger entry point `custom_debugger`. + RUBY + end + + it 'registers an offense for a `custom_debugger` call when used in numbered block' do + expect_offense(<<~RUBY) + x.y = do_something do + z(_1) + custom_debugger + ^^^^^^^^^^^^^^^ Remove debugger entry point `custom_debugger`. + end + RUBY + end + it 'registers an offense for a `custom_debugger` call when used in lambda literal' do expect_offense(<<~RUBY) x.y = -> { custom_debugger } @@ -172,6 +189,14 @@ it { expect(do_something(k: p)).to eq bar } RUBY end + + it 'does not register an offense when `p` is a array argument of method call' do + expect_no_offenses(<<~RUBY) + let(:p) { foo } + + it { expect(do_something([k, p])).to eq bar } + RUBY + end end context 'byebug' do From 59021624ce276edaca12812c39943116de7ee763 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 5 Oct 2023 14:15:30 +0900 Subject: [PATCH 0017/1411] Make `Lint/RedundantSafeNavigation` aware of constant receiver Fixes https://github.com/rubocop/rubocop-rails/issues/1104. This is an issue with RuboCop Rails, but it can likely be addressed as a generic issue. So, this PR makes `Lint/RedundantSafeNavigation` aware of constant receiver. Because use cases where a constant is `nil` are rare and an offense is detected when the receiver is a constant. And this cop is already marked as unsafe. --- ...safe_navigation_aware_of_const_receiver.md | 1 + .../cop/lint/redundant_safe_navigation.rb | 20 +++++++++++++++---- .../lint/redundant_safe_navigation_spec.rb | 11 ++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md diff --git a/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md b/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md new file mode 100644 index 000000000000..d63d33b0be05 --- /dev/null +++ b/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md @@ -0,0 +1 @@ +* [#12299](https://github.com/rubocop/rubocop/issues/12299): Make `Lint/RedundantSafeNavigation` aware of constant receiver. ([@koic][]) diff --git a/lib/rubocop/cop/lint/redundant_safe_navigation.rb b/lib/rubocop/cop/lint/redundant_safe_navigation.rb index 349e3bd29b79..0629fb213bee 100644 --- a/lib/rubocop/cop/lint/redundant_safe_navigation.rb +++ b/lib/rubocop/cop/lint/redundant_safe_navigation.rb @@ -4,8 +4,12 @@ module RuboCop module Cop module Lint # Checks for redundant safe navigation calls. - # `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, and `equal?` methods - # are checked by default. These are customizable with `AllowedMethods` option. + # Use cases where a constant is `nil` are rare and an offense is detected + # when the receiver is a constant. + # + # For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, + # and `equal?` methods are checked by default. + # These are customizable with `AllowedMethods` option. # # The `AllowedMethods` option specifies nil-safe methods, # in other words, it is a method that is allowed to skip safe navigation. @@ -22,6 +26,9 @@ module Lint # # @example # # bad + # Const&.do_something + # + # # bad # do_something if attrs&.respond_to?(:[]) # # # good @@ -33,6 +40,9 @@ module Lint # end # # # good + # Const.do_something + # + # # good # while node.is_a?(BeginNode) # node = node.parent # end @@ -63,8 +73,10 @@ class RedundantSafeNavigation < Base PATTERN def on_csend(node) - return unless check?(node) && allowed_method?(node.method_name) - return if respond_to_nil_specific_method?(node) + unless node.receiver.const_type? + return unless check?(node) && allowed_method?(node.method_name) + return if respond_to_nil_specific_method?(node) + end range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos) add_offense(range) { |corrector| corrector.replace(node.loc.dot, '.') } diff --git a/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb b/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb index 6f96d4d972a4..74430a016ccf 100644 --- a/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb +++ b/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb @@ -3,6 +3,17 @@ RSpec.describe RuboCop::Cop::Lint::RedundantSafeNavigation, :config do let(:cop_config) { { 'AllowedMethods' => %w[respond_to?] } } + it 'registers an offense and corrects when `&.` is used for const receiver' do + expect_offense(<<~RUBY) + Foo&.do_something + ^^^^^^^^^^^^^^ Redundant safe navigation detected. + RUBY + + expect_correction(<<~RUBY) + Foo.do_something + RUBY + end + it 'registers an offense and corrects when `&.` is used inside `if` condition' do expect_offense(<<~RUBY) if foo&.respond_to?(:bar) From 26681f70adf4cfdf9e4daa429bea00adbffbd467 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 5 Oct 2023 16:14:37 +0900 Subject: [PATCH 0018/1411] Fix a link address for #12246 --- ...ke_lint_redundant_safe_navigation_aware_of_const_receiver.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md b/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md index d63d33b0be05..e10b49c0ef93 100644 --- a/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md +++ b/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md @@ -1 +1 @@ -* [#12299](https://github.com/rubocop/rubocop/issues/12299): Make `Lint/RedundantSafeNavigation` aware of constant receiver. ([@koic][]) +* [#12246](https://github.com/rubocop/rubocop/pull/12246): Make `Lint/RedundantSafeNavigation` aware of constant receiver. ([@koic][]) From b9a90b5d7f18576eff235a43441fa2d8536f6fd6 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 1 Oct 2023 01:07:27 +0900 Subject: [PATCH 0019/1411] Enhance `Style/FormatString`'s autocorrection This PR enhances `Style/FormatString`'s autocorrection when using known conversion methods whose return value is not an array. --- ...ance_style_format_string_autocorrection.md | 1 + lib/rubocop/cop/style/format_string.rb | 27 ++- spec/rubocop/cop/style/format_string_spec.rb | 158 ++++++++++++++++++ 3 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 changelog/change_enhance_style_format_string_autocorrection.md diff --git a/changelog/change_enhance_style_format_string_autocorrection.md b/changelog/change_enhance_style_format_string_autocorrection.md new file mode 100644 index 000000000000..271d1dcecfe6 --- /dev/null +++ b/changelog/change_enhance_style_format_string_autocorrection.md @@ -0,0 +1 @@ +* [#12234](https://github.com/rubocop/rubocop/pull/12234): Enhance `Style/FormatString`'s autocorrection when using known conversion methods whose return value is not an array. ([@koic][]) diff --git a/lib/rubocop/cop/style/format_string.rb b/lib/rubocop/cop/style/format_string.rb index 2ec0a578df4f..e19af828063d 100644 --- a/lib/rubocop/cop/style/format_string.rb +++ b/lib/rubocop/cop/style/format_string.rb @@ -4,13 +4,25 @@ module RuboCop module Cop module Style # Enforces the use of a single string formatting utility. - # Valid options include Kernel#format, Kernel#sprintf and String#%. + # Valid options include `Kernel#format`, `Kernel#sprintf`, and `String#%`. # - # The detection of String#% cannot be implemented in a reliable + # The detection of `String#%` cannot be implemented in a reliable # manner for all cases, so only two scenarios are considered - # if the first argument is a string literal and if the second # argument is an array literal. # + # Autocorrection will be applied when using argument is a literal or known built-in conversion + # methods such as `to_d`, `to_f`, `to_h`, `to_i`, `to_r`, `to_s`, and `to_sym` on variables, + # provided that their return value is not an array. For example, when using `to_s`, + # `'%s' % [1, 2, 3].to_s` can be autocorrected without any incompatibility: + # + # [source,ruby] + # ---- + # '%s' % [1, 2, 3] #=> '1' + # format('%s', [1, 2, 3]) #=> '[1, 2, 3]' + # '%s' % [1, 2, 3].to_s #=> '[1, 2, 3]' + # ---- + # # @example EnforcedStyle: format (default) # # bad # puts sprintf('%10s', 'hoge') @@ -42,6 +54,9 @@ class FormatString < Base MSG = 'Favor `%s` over `%s`.' RESTRICT_ON_SEND = %i[format sprintf %].freeze + # Known conversion methods whose return value is not an array. + AUTOCORRECTABLE_METHODS = %i[to_d to_f to_h to_i to_r to_s to_sym].freeze + # @!method formatter(node) def_node_matcher :formatter, <<~PATTERN { @@ -53,7 +68,7 @@ class FormatString < Base # @!method variable_argument?(node) def_node_matcher :variable_argument?, <<~PATTERN - (send {str dstr} :% {send_type? lvar_type?}) + (send {str dstr} :% #autocorrectable?) PATTERN def on_send(node) @@ -70,6 +85,12 @@ def on_send(node) private + def autocorrectable?(node) + return true if node.lvar_type? + + node.send_type? && !AUTOCORRECTABLE_METHODS.include?(node.method_name) + end + def message(detected_style) format(MSG, prefer: method_name(style), current: method_name(detected_style)) end diff --git a/spec/rubocop/cop/style/format_string_spec.rb b/spec/rubocop/cop/style/format_string_spec.rb index 8880fa68a31b..704470514681 100644 --- a/spec/rubocop/cop/style/format_string_spec.rb +++ b/spec/rubocop/cop/style/format_string_spec.rb @@ -37,6 +37,85 @@ RUBY end + context 'when using a known autocorrectable method that does not convert to an array' do + it 'registers an offense for `to_s`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_s + ^ Favor `sprintf` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts sprintf("%s", a.to_s) + RUBY + end + + it 'registers an offense for `to_h`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_h + ^ Favor `sprintf` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts sprintf("%s", a.to_h) + RUBY + end + + it 'registers an offense for `to_i`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_i + ^ Favor `sprintf` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts sprintf("%s", a.to_i) + RUBY + end + + it 'registers an offense for `to_f`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_f + ^ Favor `sprintf` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts sprintf("%s", a.to_f) + RUBY + end + + it 'registers an offense for `to_r`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_r + ^ Favor `sprintf` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts sprintf("%s", a.to_r) + RUBY + end + + it 'registers an offense for `to_d`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_d + ^ Favor `sprintf` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts sprintf("%s", a.to_d) + RUBY + end + + it 'registers an offense for `to_sym`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_sym + ^ Favor `sprintf` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts sprintf("%s", a.to_sym) + RUBY + end + end + it 'registers an offense for variable argument but does not autocorrect' do expect_offense(<<~RUBY) puts "%f" % a @@ -134,6 +213,85 @@ RUBY end + context 'when using a known conversion method that does not convert to an array' do + it 'registers an offense for `to_s`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_s + ^ Favor `format` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts format("%s", a.to_s) + RUBY + end + + it 'registers an offense for `to_h`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_h + ^ Favor `format` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts format("%s", a.to_h) + RUBY + end + + it 'registers an offense for `to_i`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_i + ^ Favor `format` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts format("%s", a.to_i) + RUBY + end + + it 'registers an offense for `to_f`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_f + ^ Favor `format` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts format("%s", a.to_f) + RUBY + end + + it 'registers an offense for `to_r`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_r + ^ Favor `format` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts format("%s", a.to_r) + RUBY + end + + it 'registers an offense for `to_d`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_d + ^ Favor `format` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts format("%s", a.to_d) + RUBY + end + + it 'registers an offense for `to_sym`' do + expect_offense(<<~RUBY) + puts "%s" % a.to_sym + ^ Favor `format` over `String#%`. + RUBY + + expect_correction(<<~RUBY) + puts format("%s", a.to_sym) + RUBY + end + end + it 'registers an offense for variable argument but does not autocorrect' do expect_offense(<<~RUBY) puts "%f" % a From b5683e47f9cadf22cd0ab9ff6b58bfe2cdfa0e62 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 7 Oct 2023 15:24:05 +0900 Subject: [PATCH 0020/1411] Remove an unused `include Alignment` --- lib/rubocop/cop/lint/non_atomic_file_operation.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/rubocop/cop/lint/non_atomic_file_operation.rb b/lib/rubocop/cop/lint/non_atomic_file_operation.rb index 248f61620df5..553287f34726 100644 --- a/lib/rubocop/cop/lint/non_atomic_file_operation.rb +++ b/lib/rubocop/cop/lint/non_atomic_file_operation.rb @@ -43,7 +43,6 @@ module Lint # class NonAtomicFileOperation < Base extend AutoCorrector - include Alignment MSG_REMOVE_FILE_EXIST_CHECK = 'Remove unnecessary existence check ' \ '`%s.%s`.' From aee06d058b7b242f9043bf9678514f288fd894dc Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 8 Oct 2023 13:02:00 +0900 Subject: [PATCH 0021/1411] Mark `Lint/RedundantRequireStatement` as unsafe autocorrect Follow up https://github.com/rubocop/rubocop/pull/11931#issuecomment-1603717583. This PR marks `Lint/RedundantRequireStatement` as unsafe autocorrect because if `require 'pp'` is removed from one file, `NameError` can be encountered when another file uses `PP.pp`. --- ..._lint_redundant_require_statement_as_unsafe_autocorrect.md | 1 + config/default.yml | 2 ++ lib/rubocop/cop/lint/redundant_require_statement.rb | 4 ++++ 3 files changed, 7 insertions(+) create mode 100644 changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md diff --git a/changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md b/changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md new file mode 100644 index 000000000000..405f77d88633 --- /dev/null +++ b/changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md @@ -0,0 +1 @@ +* [#12250](https://github.com/rubocop/rubocop/pull/12250): Mark `Lint/RedundantRequireStatement` as unsafe autocorrect. ([@koic][]) diff --git a/config/default.yml b/config/default.yml index fa0a197ee65c..6d9d613776c2 100644 --- a/config/default.yml +++ b/config/default.yml @@ -2170,7 +2170,9 @@ Lint/RedundantRegexpQuantifiers: Lint/RedundantRequireStatement: Description: 'Checks for unnecessary `require` statement.' Enabled: true + SafeAutoCorrect: false VersionAdded: '0.76' + VersionChanged: '<>' Lint/RedundantSafeNavigation: Description: 'Checks for redundant safe navigation calls.' diff --git a/lib/rubocop/cop/lint/redundant_require_statement.rb b/lib/rubocop/cop/lint/redundant_require_statement.rb index 0be0cbe0687e..95133baf5c1a 100644 --- a/lib/rubocop/cop/lint/redundant_require_statement.rb +++ b/lib/rubocop/cop/lint/redundant_require_statement.rb @@ -24,6 +24,10 @@ module Lint # # This cop target those features. # + # @safety + # This cop's autocorrection is unsafe because if `require 'pp'` is removed from one file, + # `NameError` can be encountered when another file uses `PP.pp`. + # # @example # # bad # require 'unloaded_feature' From 706b625e47fcd67bba199c71e2fc8cbe9d4e1094 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 7 Oct 2023 00:50:46 +0900 Subject: [PATCH 0022/1411] Fix false negatives for `Style/RedundantParentheses` This PR fix false negatives for `Style/RedundantParentheses` when using logical or comparison expressions with redundant parentheses. e.g. `assert(('rubocop-minitest' == actual))` --- ...gatives_for_style_redundant_parentheses.md | 1 + .../cop/style/redundant_parentheses.rb | 26 ++++++++++++--- .../cop/style/redundant_parentheses_spec.rb | 32 ++++++++++++++++++- 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 changelog/fix_false_negatives_for_style_redundant_parentheses.md diff --git a/changelog/fix_false_negatives_for_style_redundant_parentheses.md b/changelog/fix_false_negatives_for_style_redundant_parentheses.md new file mode 100644 index 000000000000..4e253873933e --- /dev/null +++ b/changelog/fix_false_negatives_for_style_redundant_parentheses.md @@ -0,0 +1 @@ +* [#12247](https://github.com/rubocop/rubocop/pull/12247): Fix false negatives for `Style/RedundantParentheses` when using logical or comparison expressions with redundant parentheses. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_parentheses.rb b/lib/rubocop/cop/style/redundant_parentheses.rb index eff07b6cc266..abee3585f8e5 100644 --- a/lib/rubocop/cop/style/redundant_parentheses.rb +++ b/lib/rubocop/cop/style/redundant_parentheses.rb @@ -126,16 +126,32 @@ def method_chain_begins_with_hash_literal?(node) def check(begin_node) node = begin_node.children.first - return offense(begin_node, 'a keyword') if keyword_with_redundant_parentheses?(node) - return offense(begin_node, 'a literal') if disallowed_literal?(begin_node, node) - return offense(begin_node, 'a variable') if node.variable? - return offense(begin_node, 'a constant') if node.const_type? - return offense(begin_node, 'an interpolated expression') if interpolation?(begin_node) + if (message = find_offense_message(begin_node, node)) + return offense(begin_node, message) + end check_send(begin_node, node) if node.call_type? end + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + def find_offense_message(begin_node, node) + return 'a keyword' if keyword_with_redundant_parentheses?(node) + return 'a literal' if disallowed_literal?(begin_node, node) + return 'a variable' if node.variable? + return 'a constant' if node.const_type? + return 'an interpolated expression' if interpolation?(begin_node) + + return if begin_node.chained? || !begin_node.parent.nil? + + if node.and_type? || node.or_type? + 'a logical expression' + elsif node.respond_to?(:comparison_method?) && node.comparison_method? + 'a comparison expression' + end + end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # @!method interpolation?(node) def_node_matcher :interpolation?, '[^begin ^^dstr]' diff --git a/spec/rubocop/cop/style/redundant_parentheses_spec.rb b/spec/rubocop/cop/style/redundant_parentheses_spec.rb index f9ad0f180fda..613d8089f879 100644 --- a/spec/rubocop/cop/style/redundant_parentheses_spec.rb +++ b/spec/rubocop/cop/style/redundant_parentheses_spec.rb @@ -160,6 +160,19 @@ it_behaves_like 'redundant', '({0 => :a}[0])', '{0 => :a}[0]', 'a method call' it_behaves_like 'redundant', '(x; y)', 'x; y', 'a method call' + it_behaves_like 'redundant', '(x && y)', 'x && y', 'a logical expression' + it_behaves_like 'redundant', '(x || y)', 'x || y', 'a logical expression' + it_behaves_like 'redundant', '(x and y)', 'x and y', 'a logical expression' + it_behaves_like 'redundant', '(x or y)', 'x or y', 'a logical expression' + + it_behaves_like 'redundant', '(x == y)', 'x == y', 'a comparison expression' + it_behaves_like 'redundant', '(x === y)', 'x === y', 'a comparison expression' + it_behaves_like 'redundant', '(x != y)', 'x != y', 'a comparison expression' + it_behaves_like 'redundant', '(x > y)', 'x > y', 'a comparison expression' + it_behaves_like 'redundant', '(x >= y)', 'x >= y', 'a comparison expression' + it_behaves_like 'redundant', '(x < y)', 'x < y', 'a comparison expression' + it_behaves_like 'redundant', '(x <= y)', 'x <= y', 'a comparison expression' + it_behaves_like 'redundant', '(!x)', '!x', 'a unary operation' it_behaves_like 'redundant', '(~x)', '~x', 'a unary operation' it_behaves_like 'redundant', '(-x)', '-x', 'a unary operation' @@ -480,10 +493,27 @@ def x expect_no_offenses('(a...b)') end - it 'accepts parentheses around operator keywords' do + it 'accepts parentheses around logical operator keywords' do expect_no_offenses('(1 and 2) and (3 or 4)') end + it 'accepts parentheses around comparison operator keywords' do + # Parentheses are redundant, but respect user's intentions for readability. + expect_no_offenses('x && (y == z)') + end + + it 'accepts parentheses around a method call with parenthesized logical expression receiver' do + expect_no_offenses('(x || y).z') + end + + it 'accepts parentheses around a method call with parenthesized comparison expression receiver' do + expect_no_offenses('(x == y).zero?') + end + + it 'accepts parentheses around single argument separated by semicolon' do + expect_no_offenses('x((prepare; perform))') + end + it 'registers an offense when there is space around the parentheses' do expect_offense(<<~RUBY) if x; y else (1) end From bc1b6a89ecc5873932313451fb8acc487255a2db Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Mon, 9 Oct 2023 21:28:46 +0900 Subject: [PATCH 0023/1411] Update `Lint/LiteralInInterpolation` to accept an empty string literal interpolated in %W[]/%I[] An empty string in those words literals is significant and must not be expanded. e.g. ```ruby system(*%W[git commit -m #{""} file]) ``` --- ...pt_empty_string_literal_interpolated_in_words_literal.md | 1 + lib/rubocop/cop/lint/literal_in_interpolation.rb | 2 +- spec/rubocop/cop/lint/literal_in_interpolation_spec.rb | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md diff --git a/changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md b/changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md new file mode 100644 index 000000000000..e733fb103ce5 --- /dev/null +++ b/changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md @@ -0,0 +1 @@ +* [#12253](https://github.com/rubocop/rubocop/pull/12253): Fix `Lint/LiteralInInterpolation` to accept an empty string literal interpolated in words literal. ([@knu][]) diff --git a/lib/rubocop/cop/lint/literal_in_interpolation.rb b/lib/rubocop/cop/lint/literal_in_interpolation.rb index ab2e2539d066..e1d18ba8a91c 100644 --- a/lib/rubocop/cop/lint/literal_in_interpolation.rb +++ b/lib/rubocop/cop/lint/literal_in_interpolation.rb @@ -34,7 +34,7 @@ def on_interpolation(begin_node) # interpolation should not be removed if the expanded value # contains a space character. expanded_value = autocorrected_value(final_node) - return if in_array_percent_literal?(begin_node) && /\s/.match?(expanded_value) + return if in_array_percent_literal?(begin_node) && /\s|\A\z/.match?(expanded_value) add_offense(final_node) do |corrector| return if final_node.dstr_type? # nested, fixed in next iteration diff --git a/spec/rubocop/cop/lint/literal_in_interpolation_spec.rb b/spec/rubocop/cop/lint/literal_in_interpolation_spec.rb index eea80174b724..7a9df5327f48 100644 --- a/spec/rubocop/cop/lint/literal_in_interpolation_spec.rb +++ b/spec/rubocop/cop/lint/literal_in_interpolation_spec.rb @@ -206,6 +206,12 @@ RUBY end + it "accepts interpolation of an empty string literal in #{prefix}[]" do + expect_no_offenses(<<~RUBY) + #{prefix}[\#{""} is significant] + RUBY + end + it "accepts interpolation of a symbol literal with space in #{prefix}[]" do expect_no_offenses(<<~RUBY) #{prefix}[\#{:"this interpolation"} is significant] From ab72b2b0b1e76f6738c51a4b0c1b253f77735e94 Mon Sep 17 00:00:00 2001 From: Joe Siewert Date: Mon, 9 Oct 2023 22:00:13 -0500 Subject: [PATCH 0024/1411] Edit empty block overview text --- lib/rubocop/cop/lint/empty_block.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rubocop/cop/lint/empty_block.rb b/lib/rubocop/cop/lint/empty_block.rb index b401efd5d02a..87073ba113d9 100644 --- a/lib/rubocop/cop/lint/empty_block.rb +++ b/lib/rubocop/cop/lint/empty_block.rb @@ -5,7 +5,7 @@ module Cop module Lint # Checks for blocks without a body. # Such empty blocks are typically an oversight or we should provide a comment - # be clearer what we're aiming for. + # to clarify what we're aiming for. # # Empty lambdas and procs are ignored by default. # From fb3415206c8fcc8c1a856a8529b5e94069782115 Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Tue, 10 Oct 2023 13:42:30 +0900 Subject: [PATCH 0025/1411] Remove redundant true/false returns Follow up: https://github.com/rubocop/rubocop/pull/12176#issuecomment-1752002311 --- lib/rubocop/cop/layout/indentation_width.rb | 2 +- lib/rubocop/cop/layout/space_inside_parens.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rubocop/cop/layout/indentation_width.rb b/lib/rubocop/cop/layout/indentation_width.rb index e8f3fbefa958..415f2311b203 100644 --- a/lib/rubocop/cop/layout/indentation_width.rb +++ b/lib/rubocop/cop/layout/indentation_width.rb @@ -354,7 +354,7 @@ def skip_check?(base_loc, body_node) # Don't check indentation if the line doesn't start with the body. # For example, lines like "else do_something". first_char_pos_on_line = body_node.source_range.source_line =~ /\S/ - true unless body_node.loc.column == first_char_pos_on_line + body_node.loc.column != first_char_pos_on_line end def offending_range(body_node, indentation) diff --git a/lib/rubocop/cop/layout/space_inside_parens.rb b/lib/rubocop/cop/layout/space_inside_parens.rb index 7396fc5d511f..2d577cf5e15f 100644 --- a/lib/rubocop/cop/layout/space_inside_parens.rb +++ b/lib/rubocop/cop/layout/space_inside_parens.rb @@ -168,7 +168,7 @@ def can_be_ignored?(token1, token2) # follows, and that the rules for space inside don't apply. return true if token2.comment? - true unless same_line?(token1, token2) && !token1.space_after? + !same_line?(token1, token2) || token1.space_after? end end end From 86c0e8daf5f30c8745e79ff1fff12c2a8b950376 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 8 Oct 2023 16:50:02 +0900 Subject: [PATCH 0026/1411] [Fix #12249] Fix a false positive `Style/IdenticalConditionalBranches` Fixes #12249. This PR fixes a false positive `Style/IdenticalConditionalBranches` when `if`..`else` with identical leading lines and assign to condition value. --- ...or_style_identical_conditional_branches.md | 1 + .../style/identical_conditional_branches.rb | 20 +++- .../identical_conditional_branches_spec.rb | 97 +++++++++++++++++++ 3 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_a_false_positive_for_style_identical_conditional_branches.md diff --git a/changelog/fix_a_false_positive_for_style_identical_conditional_branches.md b/changelog/fix_a_false_positive_for_style_identical_conditional_branches.md new file mode 100644 index 000000000000..ef98b448c1af --- /dev/null +++ b/changelog/fix_a_false_positive_for_style_identical_conditional_branches.md @@ -0,0 +1 @@ +* [#12249](https://github.com/rubocop/rubocop/issues/12249): Fix a false positive `Style/IdenticalConditionalBranches` when `if`..`else` with identical leading lines and assign to condition value. ([@koic][]) diff --git a/lib/rubocop/cop/style/identical_conditional_branches.rb b/lib/rubocop/cop/style/identical_conditional_branches.rb index ea04d4ad9906..d852af4b37b9 100644 --- a/lib/rubocop/cop/style/identical_conditional_branches.rb +++ b/lib/rubocop/cop/style/identical_conditional_branches.rb @@ -136,7 +136,7 @@ def on_case_match(node) private - # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def check_branches(node, branches) # return if any branch is empty. An empty branch can be an `if` # without an `else` or a branch that contains only comments. @@ -149,9 +149,15 @@ def check_branches(node, branches) branches.any? { |branch| single_child_branch?(branch) } heads = branches.map { |branch| head(branch) } - check_expressions(node, heads, :before_condition) if duplicated_expressions?(node, heads) + + return unless duplicated_expressions?(node, heads) + + condition_variable = assignable_condition_value(node) + return if heads.first.assignment? && condition_variable == heads.first.name.to_s + + check_expressions(node, heads, :before_condition) end - # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def duplicated_expressions?(node, expressions) unique_expressions = expressions.uniq @@ -164,6 +170,14 @@ def duplicated_expressions?(node, expressions) node.condition.child_nodes.none? { |n| n.source == lhs.source if n.variable? } end + def assignable_condition_value(node) + if node.condition.call_type? + (receiver = node.condition.receiver) ? receiver.source : node.condition.source + elsif node.condition.variable? + node.condition.source + end + end + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity def check_expressions(node, expressions, insert_position) return if expressions.any?(&:nil?) diff --git a/spec/rubocop/cop/style/identical_conditional_branches_spec.rb b/spec/rubocop/cop/style/identical_conditional_branches_spec.rb index f70951e4d37e..915807c25546 100644 --- a/spec/rubocop/cop/style/identical_conditional_branches_spec.rb +++ b/spec/rubocop/cop/style/identical_conditional_branches_spec.rb @@ -72,6 +72,103 @@ end end + context 'on if..else with identical leading lines and assign to condition value of method call receiver' do + it "doesn't register an offense" do + expect_no_offenses(<<~RUBY) + if x.condition + x = do_something + foo + else + x = do_something + bar + end + RUBY + end + end + + context 'on if..else with identical leading lines and assign to condition value of safe navigation call receiver' do + it "doesn't register an offense" do + expect_no_offenses(<<~RUBY) + if x&.condition + x = do_something + foo + else + x = do_something + bar + end + RUBY + end + end + + context 'on if..else with identical leading lines and assign to condition value of method call' do + it "doesn't register an offense" do + expect_no_offenses(<<~RUBY) + if x + x = do_something + foo + else + x = do_something + bar + end + RUBY + end + end + + context 'on if..else with identical leading lines and assign to condition local variable' do + it "doesn't register an offense" do + expect_no_offenses(<<~RUBY) + x = 42 + + if x + x = do_something + foo + else + x = do_something + bar + end + RUBY + end + end + + context 'on if..else with identical leading lines and assign to condition instance variable' do + it "doesn't register an offense" do + expect_no_offenses(<<~RUBY) + if @x + @x = do_something + foo + else + @x = do_something + bar + end + RUBY + end + end + + context 'on if..else with identical trailing lines and assign to condition value' do + it 'registers and corrects an offense' do + expect_offense(<<~RUBY) + if x.condition + foo + x = do_something + ^^^^^^^^^^^^^^^^ Move `x = do_something` out of the conditional. + else + bar + x = do_something + ^^^^^^^^^^^^^^^^ Move `x = do_something` out of the conditional. + end + RUBY + + expect_correction(<<~RUBY) + if x.condition + foo + else + bar + end + x = do_something + RUBY + end + end + context 'on if..else with identical leading lines, single child branch and last node of the parent' do it "doesn't register an offense" do expect_no_offenses(<<~RUBY) From 81ef51ea121989cdf756c6e1c016fc2b5414bf4b Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 11 Oct 2023 11:55:34 +0900 Subject: [PATCH 0027/1411] [Fix #12257] Make `Style/RedundantDoubleSplatHashBraces` aware of `merge` Resolves #12257. This PR makes `Style/RedundantDoubleSplatHashBraces` aware of `merge` methods. Instead of introducing a new cop, this `Style/RedundantDoubleSplatHashBraces` cop can be extended. --- ...double_splat_hash_braces_aware_of_merge.md | 1 + .../redundant_double_splat_hash_braces.rb | 73 +++++++++++++++-- ...redundant_double_splat_hash_braces_spec.rb | 81 ++++++++++++++++++- 3 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md diff --git a/changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md b/changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md new file mode 100644 index 000000000000..43e220599059 --- /dev/null +++ b/changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md @@ -0,0 +1 @@ +* [#12257](https://github.com/rubocop/rubocop/issues/12257): Make `Style/RedundantDoubleSplatHashBraces` aware of `merge` methods. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index ea70e78cd681..a1d23ac49dbe 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -13,25 +13,50 @@ module Style # # good # do_something(foo: bar, baz: qux) # + # # bad + # do_something(**{foo: bar, baz: qux}.merge(options)) + # + # # good + # do_something(foo: bar, baz: qux, **options) + # class RedundantDoubleSplatHashBraces < Base extend AutoCorrector MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.' + MERGE_METHODS = %i[merge merge!].freeze + # rubocop:disable Metrics/CyclomaticComplexity def on_hash(node) return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?) return unless (parent = node.parent) - return unless parent.kwsplat_type? + return unless (kwsplat = node.each_ancestor(:kwsplat).first) + return if parent.call_type? && !merge_method?(parent) - add_offense(parent) do |corrector| - corrector.remove(parent.loc.operator) - corrector.remove(opening_brace(node)) - corrector.remove(closing_brace(node)) + add_offense(kwsplat) do |corrector| + autocorrect(corrector, node, kwsplat) end end + # rubocop:enable Metrics/CyclomaticComplexity private + def autocorrect(corrector, node, kwsplat) + corrector.remove(kwsplat.loc.operator) + corrector.remove(opening_brace(node)) + corrector.remove(closing_brace(node)) + + merge_methods = select_merge_method_nodes(kwsplat) + return if merge_methods.empty? + + autocorrect_merge_methods(corrector, merge_methods, kwsplat) + end + + def select_merge_method_nodes(kwsplat) + extract_send_methods(kwsplat).select do |node| + merge_method?(node) + end + end + def opening_brace(node) node.loc.begin.join(node.children.first.source_range.begin) end @@ -39,6 +64,44 @@ def opening_brace(node) def closing_brace(node) node.children.last.source_range.end.join(node.loc.end) end + + def autocorrect_merge_methods(corrector, merge_methods, kwsplat) + range = range_of_merge_methods(merge_methods) + + new_kwsplat_arguments = extract_send_methods(kwsplat).map do |descendant| + convert_to_new_arguments(descendant) + end + new_source = new_kwsplat_arguments.compact.reverse.unshift('').join(', ') + + corrector.replace(range, new_source) + end + + def range_of_merge_methods(merge_methods) + begin_merge_method = merge_methods.last + end_merge_method = merge_methods.first + + begin_merge_method.loc.dot.begin.join(end_merge_method.source_range.end) + end + + def extract_send_methods(kwsplat) + @extract_send_methods ||= kwsplat.each_descendant(:send, :csend) + end + + def convert_to_new_arguments(node) + return unless merge_method?(node) + + node.arguments.map do |arg| + if arg.hash_type? + arg.source + else + "**#{arg.source}" + end + end + end + + def merge_method?(node) + MERGE_METHODS.include?(node.method_name) + end end end end diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index e83a74220491..5b53e3a7ea55 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -35,6 +35,83 @@ RUBY end + it 'registers an offense when using double splat hash braces with `merge` method call' do + expect_offense(<<~RUBY) + do_something(**{foo: bar, baz: qux}.merge(options)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, baz: qux, **options) + RUBY + end + + it 'registers an offense when using double splat hash braces with `merge!` method call' do + expect_offense(<<~RUBY) + do_something(**{foo: bar, baz: qux}.merge!(options)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, baz: qux, **options) + RUBY + end + + it 'registers an offense when using double splat hash braces with `merge` pair arguments method call' do + expect_offense(<<~RUBY) + do_something(**{foo: bar, baz: qux}.merge(x: y)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, baz: qux, x: y) + RUBY + end + + it 'registers an offense when using double splat hash braces with `merge` safe navigation method call' do + expect_offense(<<~RUBY) + do_something(**{foo: bar, baz: qux}&.merge(options)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, baz: qux, **options) + RUBY + end + + it 'registers an offense when using double splat hash braces with `merge` multiple arguments method call' do + expect_offense(<<~RUBY) + do_something(**{foo: bar, baz: qux}.merge(options1, options2)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, baz: qux, **options1, **options2) + RUBY + end + + it 'registers an offense when using double splat hash braces with `merge` method chain' do + expect_offense(<<~RUBY) + do_something(**{foo: bar, baz: qux}.merge(options1, options2).merge(options3)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, baz: qux, **options1, **options2, **options3) + RUBY + end + + it 'registers an offense when using double splat hash braces with complex `merge` method chain' do + expect_offense(<<~RUBY) + do_something(**{foo: bar, baz: qux}.merge(options1, options2)&.merge!(options3)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, baz: qux, **options1, **options2, **options3) + RUBY + end + it 'does not register an offense when using keyword arguments' do expect_no_offenses(<<~RUBY) do_something(foo: bar, baz: qux) @@ -59,9 +136,9 @@ RUBY end - it 'does not register an offense when using method call for double splat hash braces arguments' do + it 'does not register an offense when using method call that is not `merge` for double splat hash braces arguments' do expect_no_offenses(<<~RUBY) - do_something(**{foo: bar}.merge(options)) + do_something(**{foo: bar}.invert) RUBY end From 986d047b8a6d4163329cdd4925726eae7885b6e6 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 11 Oct 2023 16:22:16 +0900 Subject: [PATCH 0028/1411] Fix an error for `Style/RedundantDoubleSplatHashBraces` Follow up #12258. This PR fixes the following error for `Style/RedundantDoubleSplatHashBraces`: ```console $ echo 'do_something(**options.merge(foo: bar, baz: qux))' | bundle exec rubocop --stdin test.rb -d -a --only Style/RedundantDoubleSplatHashBraces (snip) An error occurred while Style/RedundantDoubleSplatHashBraces cop was inspecting /Users/koic/src/github.com/rubocop/rubocop/test.rb:1:29. undefined method `join' for nil /Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb:61:in `opening_brace' /Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb:45:in `autocorrect' ``` --- lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb | 6 +++--- .../cop/style/redundant_double_splat_hash_braces_spec.rb | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index a1d23ac49dbe..6e3466877747 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -25,9 +25,9 @@ class RedundantDoubleSplatHashBraces < Base MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.' MERGE_METHODS = %i[merge merge!].freeze - # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def on_hash(node) - return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?) + return if !node.braces? || node.pairs.empty? || node.pairs.any?(&:hash_rocket?) return unless (parent = node.parent) return unless (kwsplat = node.each_ancestor(:kwsplat).first) return if parent.call_type? && !merge_method?(parent) @@ -36,7 +36,7 @@ def on_hash(node) autocorrect(corrector, node, kwsplat) end end - # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity private diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index 5b53e3a7ea55..c0a3f4e4f8bf 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -118,6 +118,12 @@ RUBY end + it 'does not register an offense when using no hash brace' do + expect_no_offenses(<<~RUBY) + do_something(**options.merge(foo: bar, baz: qux)) + RUBY + end + it 'does not register an offense when using empty double splat hash braces arguments' do expect_no_offenses(<<~RUBY) do_something(**{}) From b4e2bdd0718e00bc0346717091d94f22b33e5510 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 11 Oct 2023 18:58:04 +0900 Subject: [PATCH 0029/1411] [Fix #12259] Fix an error for `Lint/MixedCaseRange` Fixes #12259. This PR fixes an error for `Lint/MixedCaseRange` when using nested character class in regexp. --- changelog/fix_an_error_for_lint_mixed_case_range.md | 1 + lib/rubocop/cop/lint/mixed_case_range.rb | 2 +- spec/rubocop/cop/lint/mixed_case_range_spec.rb | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_an_error_for_lint_mixed_case_range.md diff --git a/changelog/fix_an_error_for_lint_mixed_case_range.md b/changelog/fix_an_error_for_lint_mixed_case_range.md new file mode 100644 index 000000000000..3efbeb724d36 --- /dev/null +++ b/changelog/fix_an_error_for_lint_mixed_case_range.md @@ -0,0 +1 @@ +* [#12259](https://github.com/rubocop/rubocop/issues/12259): Fix an error for `Lint/MixedCaseRange` when using nested character class in regexp. ([@koic][]) diff --git a/lib/rubocop/cop/lint/mixed_case_range.rb b/lib/rubocop/cop/lint/mixed_case_range.rb index ed31f079c4ae..b7817981483f 100644 --- a/lib/rubocop/cop/lint/mixed_case_range.rb +++ b/lib/rubocop/cop/lint/mixed_case_range.rb @@ -95,7 +95,7 @@ def skip_expression?(expr) def skip_range?(range_start, range_end) [range_start, range_end].any? do |bound| - bound.type == :escape + bound.type != :literal end end diff --git a/spec/rubocop/cop/lint/mixed_case_range_spec.rb b/spec/rubocop/cop/lint/mixed_case_range_spec.rb index b333882d2a8c..cd063ff26c3a 100644 --- a/spec/rubocop/cop/lint/mixed_case_range_spec.rb +++ b/spec/rubocop/cop/lint/mixed_case_range_spec.rb @@ -221,4 +221,10 @@ foo = /[A\-z]/ RUBY end + + it 'does not register an offense with nested character class' do + expect_no_offenses(<<~RUBY) + foo = /[a-[bc]]/ + RUBY + end end From 402542229238227ca9e1655efd210f3f8f0a1e1b Mon Sep 17 00:00:00 2001 From: sergey Date: Sat, 7 Oct 2023 00:43:37 +0300 Subject: [PATCH 0030/1411] [Fix #12076] Explicitly require fileutils in RuboCop::Server::Cache The "fileutils.rb" item is dynamically added to the `$LOADED_FEATURES` due to the autoloading when calling the `RuboCop::Server::Cache.dir`. Explicit require is added to achieve idempotency when initializing the `RuboCop::ResultCache.rubocop_required_features`. This change resolves the issue where the top level cache folder was named differently during two consecutive runs of rubocop. --- .../fix_inconsistent_cache_key_caused_by_fileutils_require.md | 1 + lib/rubocop/server/cache.rb | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md diff --git a/changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md b/changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md new file mode 100644 index 000000000000..e39cff7f1090 --- /dev/null +++ b/changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md @@ -0,0 +1 @@ +* [#12076](https://github.com/rubocop/rubocop/issues/12076): Fixed an issue where the top-level cache folder was named differently during two consecutive rubocop runs. ([@K-S-A][]) diff --git a/lib/rubocop/server/cache.rb b/lib/rubocop/server/cache.rb index 6c7515363812..fde4c60a2fbd 100644 --- a/lib/rubocop/server/cache.rb +++ b/lib/rubocop/server/cache.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +require 'fileutils' require 'pathname' require_relative '../cache_config' require_relative '../config_finder' From 872d7137fd26977273146a70df8a903dedfe93bd Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Wed, 11 Oct 2023 12:49:00 +0200 Subject: [PATCH 0031/1411] Update Changelog --- CHANGELOG.md | 32 +++++++++++++++++++ ...to_parallel_inspection_when_config_file.md | 1 - ...ance_style_format_string_autocorrection.md | 1 - ...yle_guard_clause_aware_of_define_method.md | 1 - ...nt_filter_chain_aware_of_select_present.md | 1 - ...require_statement_as_unsafe_autocorrect.md | 1 - ...ity_comparison_as_unsafe_autocorrection.md | 1 - ...dant_filter_chain_as_unsafe_autocorrect.md | 1 - .../fix_a_false_negative_for_lint_debugger.md | 1 - ...alse_negative_for_metrics_module_length.md | 1 - ...or_style_identical_conditional_branches.md | 1 - ...g_literal_interpolated_in_words_literal.md | 1 - ...p_flop_with_beginless_or_endless_ranges.md | 1 - .../fix_an_error_for_lint_mixed_case_range.md | 1 - ...error_for_style_nested_ternary_operator.md | 1 - ...gatives_for_style_multiline_block_chain.md | 1 - ...gatives_for_style_redundant_parentheses.md | 1 - ...ayout_multiline_method_call_indentation.md | 1 - ...t_cache_key_caused_by_fileutils_require.md | 1 - ..._add_new_style_single_line_do_end_block.md | 1 - ...safe_navigation_aware_of_const_receiver.md | 1 - ...double_splat_hash_braces_aware_of_merge.md | 1 - 22 files changed, 32 insertions(+), 21 deletions(-) delete mode 100644 changelog/change_enable_auto_parallel_inspection_when_config_file.md delete mode 100644 changelog/change_enhance_style_format_string_autocorrection.md delete mode 100644 changelog/change_make_style_guard_clause_aware_of_define_method.md delete mode 100644 changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md delete mode 100644 changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md delete mode 100644 changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md delete mode 100644 changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md delete mode 100644 changelog/fix_a_false_negative_for_lint_debugger.md delete mode 100644 changelog/fix_a_false_negative_for_metrics_module_length.md delete mode 100644 changelog/fix_a_false_positive_for_style_identical_conditional_branches.md delete mode 100644 changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md delete mode 100644 changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md delete mode 100644 changelog/fix_an_error_for_lint_mixed_case_range.md delete mode 100644 changelog/fix_an_error_for_style_nested_ternary_operator.md delete mode 100644 changelog/fix_false_negatives_for_style_multiline_block_chain.md delete mode 100644 changelog/fix_false_negatives_for_style_redundant_parentheses.md delete mode 100644 changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md delete mode 100644 changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md delete mode 100644 changelog/new_add_new_style_single_line_do_end_block.md delete mode 100644 changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md delete mode 100644 changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 7132cffd3801..3e8189c4870d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,36 @@ ## master (unreleased) +### New features + +* [#12227](https://github.com/rubocop/rubocop/pull/12227): Add new `Style/SingleLineDoEndBlock` cop. ([@koic][]) +* [#12246](https://github.com/rubocop/rubocop/pull/12246): Make `Lint/RedundantSafeNavigation` aware of constant receiver. ([@koic][]) +* [#12257](https://github.com/rubocop/rubocop/issues/12257): Make `Style/RedundantDoubleSplatHashBraces` aware of `merge` methods. ([@koic][]) + +### Bug fixes + +* [#12244](https://github.com/rubocop/rubocop/issues/12244): Fix a false negative for `Lint/Debugger` when using debugger method inside block. ([@koic][]) +* [#12231](https://github.com/rubocop/rubocop/issues/12231): Fix a false negative for `Metrics/ModuleLength` when defining a singleton class in a module. ([@koic][]) +* [#12249](https://github.com/rubocop/rubocop/issues/12249): Fix a false positive `Style/IdenticalConditionalBranches` when `if`..`else` with identical leading lines and assign to condition value. ([@koic][]) +* [#12253](https://github.com/rubocop/rubocop/pull/12253): Fix `Lint/LiteralInInterpolation` to accept an empty string literal interpolated in words literal. ([@knu][]) +* [#12198](https://github.com/rubocop/rubocop/issues/12198): Fix an error for flip-flop with beginless or endless ranges. ([@koic][]) +* [#12259](https://github.com/rubocop/rubocop/issues/12259): Fix an error for `Lint/MixedCaseRange` when using nested character class in regexp. ([@koic][]) +* [#12237](https://github.com/rubocop/rubocop/issues/12237): Fix an error for `Style/NestedTernaryOperator` when a ternary operator has a nested ternary operator within an `if`. ([@koic][]) +* [#12228](https://github.com/rubocop/rubocop/pull/12228): Fix false negatives for `Style/MultilineBlockChain` when using multiline block chain with safe navigation operator. ([@koic][]) +* [#12247](https://github.com/rubocop/rubocop/pull/12247): Fix false negatives for `Style/RedundantParentheses` when using logical or comparison expressions with redundant parentheses. ([@koic][]) +* [#12226](https://github.com/rubocop/rubocop/issues/12226): Fix false positives for `Layout/MultilineMethodCallIndentation` when aligning methods in multiline block chain. ([@koic][]) +* [#12076](https://github.com/rubocop/rubocop/issues/12076): Fixed an issue where the top-level cache folder was named differently during two consecutive rubocop runs. ([@K-S-A][]) + +### Changes + +* [#12235](https://github.com/rubocop/rubocop/pull/12235): Enable auto parallel inspection when config file is specified. ([@aboutNisblee][]) +* [#12234](https://github.com/rubocop/rubocop/pull/12234): Enhance `Style/FormatString`'s autocorrection when using known conversion methods whose return value is not an array. ([@koic][]) +* [#12128](https://github.com/rubocop/rubocop/issues/12128): Make `Style/GuardClause` aware of `define_method`. ([@koic][]) +* [#12126](https://github.com/rubocop/rubocop/pull/12126): Make `Style/RedundantFilterChain` aware of `select.present?` when `ActiveSupportExtensionsEnabled` config is `true`. ([@koic][]) +* [#12250](https://github.com/rubocop/rubocop/pull/12250): Mark `Lint/RedundantRequireStatement` as unsafe autocorrect. ([@koic][]) +* [#12097](https://github.com/rubocop/rubocop/issues/12097): Mark unsafe autocorrect for `Style/ClassEqualityComparison`. ([@koic][]) +* [#12210](https://github.com/rubocop/rubocop/issues/12210): Mark `Style/RedundantFilterChain` as unsafe autocorrect. ([@koic][]) + ## 1.56.4 (2023-09-28) ### Bug fixes @@ -7354,3 +7384,5 @@ [@OwlKing]: https://github.com/OwlKing [@ItsEcholot]: https://github.com/ItsEcholot [@ymap]: https://github.com/ymap +[@aboutNisblee]: https://github.com/aboutNisblee +[@K-S-A]: https://github.com/K-S-A diff --git a/changelog/change_enable_auto_parallel_inspection_when_config_file.md b/changelog/change_enable_auto_parallel_inspection_when_config_file.md deleted file mode 100644 index ca4ecca89c30..000000000000 --- a/changelog/change_enable_auto_parallel_inspection_when_config_file.md +++ /dev/null @@ -1 +0,0 @@ -* [#12235](https://github.com/rubocop/rubocop/pull/12235): Enable auto parallel inspection when config file is specified. ([@aboutNisblee][]) diff --git a/changelog/change_enhance_style_format_string_autocorrection.md b/changelog/change_enhance_style_format_string_autocorrection.md deleted file mode 100644 index 271d1dcecfe6..000000000000 --- a/changelog/change_enhance_style_format_string_autocorrection.md +++ /dev/null @@ -1 +0,0 @@ -* [#12234](https://github.com/rubocop/rubocop/pull/12234): Enhance `Style/FormatString`'s autocorrection when using known conversion methods whose return value is not an array. ([@koic][]) diff --git a/changelog/change_make_style_guard_clause_aware_of_define_method.md b/changelog/change_make_style_guard_clause_aware_of_define_method.md deleted file mode 100644 index dd24fbafdaf8..000000000000 --- a/changelog/change_make_style_guard_clause_aware_of_define_method.md +++ /dev/null @@ -1 +0,0 @@ -* [#12128](https://github.com/rubocop/rubocop/issues/12128): Make `Style/GuardClause` aware of `define_method`. ([@koic][]) diff --git a/changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md b/changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md deleted file mode 100644 index 29bf1baccfa5..000000000000 --- a/changelog/change_make_style_redundant_filter_chain_aware_of_select_present.md +++ /dev/null @@ -1 +0,0 @@ -* [#12126](https://github.com/rubocop/rubocop/pull/12126): Make `Style/RedundantFilterChain` aware of `select.present?` when `ActiveSupportExtensionsEnabled` config is `true`. ([@koic][]) diff --git a/changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md b/changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md deleted file mode 100644 index 405f77d88633..000000000000 --- a/changelog/change_mark_lint_redundant_require_statement_as_unsafe_autocorrect.md +++ /dev/null @@ -1 +0,0 @@ -* [#12250](https://github.com/rubocop/rubocop/pull/12250): Mark `Lint/RedundantRequireStatement` as unsafe autocorrect. ([@koic][]) diff --git a/changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md b/changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md deleted file mode 100644 index 9b07c7fd611d..000000000000 --- a/changelog/change_mark_style_class_equality_comparison_as_unsafe_autocorrection.md +++ /dev/null @@ -1 +0,0 @@ -* [#12097](https://github.com/rubocop/rubocop/issues/12097): Mark unsafe autocorrect for `Style/ClassEqualityComparison`. ([@koic][]) diff --git a/changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md b/changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md deleted file mode 100644 index b68c257fae93..000000000000 --- a/changelog/change_mark_style_redundant_filter_chain_as_unsafe_autocorrect.md +++ /dev/null @@ -1 +0,0 @@ -* [#12210](https://github.com/rubocop/rubocop/issues/12210): Mark `Style/RedundantFilterChain` as unsafe autocorrect. ([@koic][]) diff --git a/changelog/fix_a_false_negative_for_lint_debugger.md b/changelog/fix_a_false_negative_for_lint_debugger.md deleted file mode 100644 index ef3f8be44e35..000000000000 --- a/changelog/fix_a_false_negative_for_lint_debugger.md +++ /dev/null @@ -1 +0,0 @@ -* [#12244](https://github.com/rubocop/rubocop/issues/12244): Fix a false negative for `Lint/Debugger` when using debugger method inside block. ([@koic][]) diff --git a/changelog/fix_a_false_negative_for_metrics_module_length.md b/changelog/fix_a_false_negative_for_metrics_module_length.md deleted file mode 100644 index 4684fda6bd43..000000000000 --- a/changelog/fix_a_false_negative_for_metrics_module_length.md +++ /dev/null @@ -1 +0,0 @@ -* [#12231](https://github.com/rubocop/rubocop/issues/12231): Fix a false negative for `Metrics/ModuleLength` when defining a singleton class in a module. ([@koic][]) diff --git a/changelog/fix_a_false_positive_for_style_identical_conditional_branches.md b/changelog/fix_a_false_positive_for_style_identical_conditional_branches.md deleted file mode 100644 index ef98b448c1af..000000000000 --- a/changelog/fix_a_false_positive_for_style_identical_conditional_branches.md +++ /dev/null @@ -1 +0,0 @@ -* [#12249](https://github.com/rubocop/rubocop/issues/12249): Fix a false positive `Style/IdenticalConditionalBranches` when `if`..`else` with identical leading lines and assign to condition value. ([@koic][]) diff --git a/changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md b/changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md deleted file mode 100644 index e733fb103ce5..000000000000 --- a/changelog/fix_accept_empty_string_literal_interpolated_in_words_literal.md +++ /dev/null @@ -1 +0,0 @@ -* [#12253](https://github.com/rubocop/rubocop/pull/12253): Fix `Lint/LiteralInInterpolation` to accept an empty string literal interpolated in words literal. ([@knu][]) diff --git a/changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md b/changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md deleted file mode 100644 index 2a4c1e803eee..000000000000 --- a/changelog/fix_an_error_for_flip_flop_with_beginless_or_endless_ranges.md +++ /dev/null @@ -1 +0,0 @@ -* [#12198](https://github.com/rubocop/rubocop/issues/12198): Fix an error for flip-flop with beginless or endless ranges. ([@koic][]) diff --git a/changelog/fix_an_error_for_lint_mixed_case_range.md b/changelog/fix_an_error_for_lint_mixed_case_range.md deleted file mode 100644 index 3efbeb724d36..000000000000 --- a/changelog/fix_an_error_for_lint_mixed_case_range.md +++ /dev/null @@ -1 +0,0 @@ -* [#12259](https://github.com/rubocop/rubocop/issues/12259): Fix an error for `Lint/MixedCaseRange` when using nested character class in regexp. ([@koic][]) diff --git a/changelog/fix_an_error_for_style_nested_ternary_operator.md b/changelog/fix_an_error_for_style_nested_ternary_operator.md deleted file mode 100644 index 41b33fb4f5f7..000000000000 --- a/changelog/fix_an_error_for_style_nested_ternary_operator.md +++ /dev/null @@ -1 +0,0 @@ -* [#12237](https://github.com/rubocop/rubocop/issues/12237): Fix an error for `Style/NestedTernaryOperator` when a ternary operator has a nested ternary operator within an `if`. ([@koic][]) diff --git a/changelog/fix_false_negatives_for_style_multiline_block_chain.md b/changelog/fix_false_negatives_for_style_multiline_block_chain.md deleted file mode 100644 index 1bbd5dea4712..000000000000 --- a/changelog/fix_false_negatives_for_style_multiline_block_chain.md +++ /dev/null @@ -1 +0,0 @@ -* [#12228](https://github.com/rubocop/rubocop/pull/12228): Fix false negatives for `Style/MultilineBlockChain` when using multiline block chain with safe navigation operator. ([@koic][]) diff --git a/changelog/fix_false_negatives_for_style_redundant_parentheses.md b/changelog/fix_false_negatives_for_style_redundant_parentheses.md deleted file mode 100644 index 4e253873933e..000000000000 --- a/changelog/fix_false_negatives_for_style_redundant_parentheses.md +++ /dev/null @@ -1 +0,0 @@ -* [#12247](https://github.com/rubocop/rubocop/pull/12247): Fix false negatives for `Style/RedundantParentheses` when using logical or comparison expressions with redundant parentheses. ([@koic][]) diff --git a/changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md b/changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md deleted file mode 100644 index e40246963b90..000000000000 --- a/changelog/fix_false_positives_for_layout_multiline_method_call_indentation.md +++ /dev/null @@ -1 +0,0 @@ -* [#12226](https://github.com/rubocop/rubocop/issues/12226): Fix false positives for `Layout/MultilineMethodCallIndentation` when aligning methods in multiline block chain. ([@koic][]) diff --git a/changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md b/changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md deleted file mode 100644 index e39cff7f1090..000000000000 --- a/changelog/fix_inconsistent_cache_key_caused_by_fileutils_require.md +++ /dev/null @@ -1 +0,0 @@ -* [#12076](https://github.com/rubocop/rubocop/issues/12076): Fixed an issue where the top-level cache folder was named differently during two consecutive rubocop runs. ([@K-S-A][]) diff --git a/changelog/new_add_new_style_single_line_do_end_block.md b/changelog/new_add_new_style_single_line_do_end_block.md deleted file mode 100644 index 13b36be51c5d..000000000000 --- a/changelog/new_add_new_style_single_line_do_end_block.md +++ /dev/null @@ -1 +0,0 @@ -* [#12227](https://github.com/rubocop/rubocop/pull/12227): Add new `Style/SingleLineDoEndBlock` cop. ([@koic][]) diff --git a/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md b/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md deleted file mode 100644 index e10b49c0ef93..000000000000 --- a/changelog/new_make_lint_redundant_safe_navigation_aware_of_const_receiver.md +++ /dev/null @@ -1 +0,0 @@ -* [#12246](https://github.com/rubocop/rubocop/pull/12246): Make `Lint/RedundantSafeNavigation` aware of constant receiver. ([@koic][]) diff --git a/changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md b/changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md deleted file mode 100644 index 43e220599059..000000000000 --- a/changelog/new_make_style_redundant_double_splat_hash_braces_aware_of_merge.md +++ /dev/null @@ -1 +0,0 @@ -* [#12257](https://github.com/rubocop/rubocop/issues/12257): Make `Style/RedundantDoubleSplatHashBraces` aware of `merge` methods. ([@koic][]) From bfdb5ff4fec74c0dd154268a8e4b97dba7a79aed Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Wed, 11 Oct 2023 12:49:25 +0200 Subject: [PATCH 0032/1411] Cut 1.57 --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- CHANGELOG.md | 2 + CONTRIBUTING.md | 2 +- README.md | 2 +- config/default.yml | 8 +- docs/antora.yml | 2 +- docs/modules/ROOT/pages/cops.adoc | 1 + docs/modules/ROOT/pages/cops_lint.adoc | 25 ++++- docs/modules/ROOT/pages/cops_metrics.adoc | 3 +- docs/modules/ROOT/pages/cops_style.adoc | 108 ++++++++++++++++++++-- docs/modules/ROOT/pages/installation.adoc | 2 +- lib/rubocop/version.rb | 2 +- relnotes/v1.57.0.md | 34 +++++++ 13 files changed, 170 insertions(+), 23 deletions(-) create mode 100644 relnotes/v1.57.0.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9d4b4fbabbb4..a28b0084b3f7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -38,7 +38,7 @@ output by `rubocop -V`, include them as well. Here's an example: ``` $ [bundle exec] rubocop -V -1.56.4 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] +1.57.0 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] - rubocop-performance 1.18.0 - rubocop-rspec 2.23.2 ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e8189c4870d..19360bac67f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ ## master (unreleased) +## 1.57.0 (2023-10-11) + ### New features * [#12227](https://github.com/rubocop/rubocop/pull/12227): Add new `Style/SingleLineDoEndBlock` cop. ([@koic][]) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b222f6f33248..efcfe5da9a46 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ do so. ```console $ rubocop -V -1.56.4 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] +1.57.0 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] - rubocop-performance 1.18.0 - rubocop-rspec 2.23.2 ``` diff --git a/README.md b/README.md index 010f26cbe145..40af39097085 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi in your `Gemfile`: ```rb -gem 'rubocop', '~> 1.56', require: false +gem 'rubocop', '~> 1.57', require: false ``` See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details. diff --git a/config/default.yml b/config/default.yml index 6d9d613776c2..93eeffdbfd4a 100644 --- a/config/default.yml +++ b/config/default.yml @@ -2172,7 +2172,7 @@ Lint/RedundantRequireStatement: Enabled: true SafeAutoCorrect: false VersionAdded: '0.76' - VersionChanged: '<>' + VersionChanged: '1.57' Lint/RedundantSafeNavigation: Description: 'Checks for redundant safe navigation calls.' @@ -3358,7 +3358,7 @@ Style/ClassEqualityComparison: Enabled: true SafeAutoCorrect: false VersionAdded: '0.93' - VersionChanged: '<>' + VersionChanged: '1.57' AllowedMethods: - == - equal? @@ -4926,7 +4926,7 @@ Style/RedundantFilterChain: Enabled: pending SafeAutoCorrect: false VersionAdded: '1.52' - VersionChanged: '<>' + VersionChanged: '1.57' Style/RedundantFreeze: Description: "Checks usages of Object#freeze on immutable objects." @@ -5191,7 +5191,7 @@ Style/SingleLineBlockParams: Style/SingleLineDoEndBlock: Description: 'Checks for single-line `do`...`end` blocks.' Enabled: pending - VersionAdded: '<>' + VersionAdded: '1.57' Style/SingleLineMethods: Description: 'Avoid single-line methods.' diff --git a/docs/antora.yml b/docs/antora.yml index 9c897ea03d1d..ec7a70bdfe4f 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop title: RuboCop # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: ~ +version: '1.57' nav: - modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/pages/cops.adoc b/docs/modules/ROOT/pages/cops.adoc index e2b4fb26834f..f81b8d2730a3 100644 --- a/docs/modules/ROOT/pages/cops.adoc +++ b/docs/modules/ROOT/pages/cops.adoc @@ -599,6 +599,7 @@ In the following section you find all available cops: * xref:cops_style.adoc#stylesignalexception[Style/SignalException] * xref:cops_style.adoc#stylesingleargumentdig[Style/SingleArgumentDig] * xref:cops_style.adoc#stylesinglelineblockparams[Style/SingleLineBlockParams] +* xref:cops_style.adoc#stylesinglelinedoendblock[Style/SingleLineDoEndBlock] * xref:cops_style.adoc#stylesinglelinemethods[Style/SingleLineMethods] * xref:cops_style.adoc#styleslicingwithrange[Style/SlicingWithRange] * xref:cops_style.adoc#stylesolenestedconditional[Style/SoleNestedConditional] diff --git a/docs/modules/ROOT/pages/cops_lint.adoc b/docs/modules/ROOT/pages/cops_lint.adoc index 51bdcca28728..60ddfaafcbaa 100644 --- a/docs/modules/ROOT/pages/cops_lint.adoc +++ b/docs/modules/ROOT/pages/cops_lint.adoc @@ -1752,7 +1752,7 @@ end Checks for blocks without a body. Such empty blocks are typically an oversight or we should provide a comment -be clearer what we're aiming for. +to clarify what we're aiming for. Empty lambdas and procs are ignored by default. @@ -4598,9 +4598,9 @@ because it's unknown what kind of string will be expanded as a result: | Enabled | Yes -| Yes +| Yes (Unsafe) | 0.76 -| - +| 1.57 |=== Checks for unnecessary `require` statement. @@ -4624,6 +4624,11 @@ Below are the features that each `TargetRubyVersion` targets. This cop target those features. +=== Safety + +This cop's autocorrection is unsafe because if `require 'pp'` is removed from one file, +`NameError` can be encountered when another file uses `PP.pp`. + === Examples [source,ruby] @@ -4649,8 +4654,12 @@ require 'unloaded_feature' |=== Checks for redundant safe navigation calls. -`instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, and `equal?` methods -are checked by default. These are customizable with `AllowedMethods` option. +Use cases where a constant is `nil` are rare and an offense is detected +when the receiver is a constant. + +For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, +and `equal?` methods are checked by default. +These are customizable with `AllowedMethods` option. The `AllowedMethods` option specifies nil-safe methods, in other words, it is a method that is allowed to skip safe navigation. @@ -4670,6 +4679,9 @@ will be autocorrected to never return `nil`. [source,ruby] ---- +# bad +Const&.do_something + # bad do_something if attrs&.respond_to?(:[]) @@ -4681,6 +4693,9 @@ while node&.is_a?(BeginNode) node = node.parent end +# good +Const.do_something + # good while node.is_a?(BeginNode) node = node.parent diff --git a/docs/modules/ROOT/pages/cops_metrics.adoc b/docs/modules/ROOT/pages/cops_metrics.adoc index e8f97e8f2442..473d0a9a8f33 100644 --- a/docs/modules/ROOT/pages/cops_metrics.adoc +++ b/docs/modules/ROOT/pages/cops_metrics.adoc @@ -98,13 +98,12 @@ You can set constructs you want to fold with `CountAsOne`. Available are: 'array', 'hash', 'heredoc', and 'method_call'. Each construct will be counted as one line regardless of its actual size. +NOTE: This cop does not apply for `Struct` definitions. NOTE: The `ExcludedMethods` configuration is deprecated and only kept for backwards compatibility. Please use `AllowedMethods` and `AllowedPatterns` instead. By default, there are no methods to allowed. -NOTE: This cop does not apply for `Struct` definitions. - === Examples ==== CountAsOne: ['array', 'heredoc', 'method_call'] diff --git a/docs/modules/ROOT/pages/cops_style.adoc b/docs/modules/ROOT/pages/cops_style.adoc index 2c81ad791db2..0be1a6a3fe84 100644 --- a/docs/modules/ROOT/pages/cops_style.adoc +++ b/docs/modules/ROOT/pages/cops_style.adoc @@ -1419,9 +1419,9 @@ var.kind_of?(String) | Enabled | Yes -| Yes +| Yes (Unsafe) | 0.93 -| - +| 1.57 |=== Enforces the use of `Object#instance_of?` instead of class comparison @@ -1429,6 +1429,12 @@ for equality. `==`, `equal?`, and `eql?` custom method definitions are allowed by default. These are customizable with `AllowedMethods` option. +=== Safety + +This cop's autocorrection is unsafe because there is no guarantee that +the constant `Foo` exists when autocorrecting `var.class.name == 'Foo'` to +`var.instance_of?(Foo)`. + === Examples [source,ruby] @@ -4731,13 +4737,25 @@ end |=== Enforces the use of a single string formatting utility. -Valid options include Kernel#format, Kernel#sprintf and String#%. +Valid options include `Kernel#format`, `Kernel#sprintf`, and `String#%`. -The detection of String#% cannot be implemented in a reliable +The detection of `String#%` cannot be implemented in a reliable manner for all cases, so only two scenarios are considered - if the first argument is a string literal and if the second argument is an array literal. +Autocorrection will be applied when using argument is a literal or known built-in conversion +methods such as `to_d`, `to_f`, `to_h`, `to_i`, `to_r`, `to_s`, and `to_sym` on variables, +provided that their return value is not an array. For example, when using `to_s`, +`'%s' % [1, 2, 3].to_s` can be autocorrected without any incompatibility: + +[source,ruby] +---- +'%s' % [1, 2, 3] #=> '1' +format('%s', [1, 2, 3]) #=> '[1, 2, 3]' +'%s' % [1, 2, 3].to_s #=> '[1, 2, 3]' +---- + === Examples ==== EnforcedStyle: format (default) @@ -5213,6 +5231,25 @@ end # good foo || raise('exception') if something ok + +# bad +define_method(:test) do + if something + work + end +end + +# good +define_method(:test) do + return unless something + + work +end + +# also good +define_method(:test) do + work if something +end ---- ==== AllowConsecutiveConditionals: false (default) @@ -11184,6 +11221,12 @@ do_something(**{foo: bar, baz: qux}) # good do_something(foo: bar, baz: qux) + +# bad +do_something(**{foo: bar, baz: qux}.merge(options)) + +# good +do_something(foo: bar, baz: qux, **options) ---- == Style/RedundantEach @@ -11383,14 +11426,21 @@ require_relative '../foo.so' | Pending | Yes -| Yes +| Yes (Unsafe) | 1.52 -| - +| 1.57 |=== Identifies usages of `any?`, `empty?` or `none?` predicate methods chained to `select`/`filter`/`find_all` and change them to use predicate method instead. +=== Safety + +This cop's autocorrection is unsafe because `array.select.any?` evaluates all elements +through the `select` method, while `array.any?` uses short-circuit evaluation. +In other words, `array.select.any?` guarantees the evaluation of every element, +but `array.any?` does not necessarily evaluate all of them. + === Examples [source,ruby] @@ -11419,6 +11469,9 @@ arr.select { |x| x > 1 }.any?(&:odd?) ---- # good arr.select { |x| x > 1 }.many? + +# good +arr.select { |x| x > 1 }.present? ---- ==== AllCops:ActiveSupportExtensionsEnabled: true @@ -11430,6 +11483,12 @@ arr.select { |x| x > 1 }.many? # good arr.many? { |x| x > 1 } + +# bad +arr.select { |x| x > 1 }.present? + +# good +arr.any? { |x| x > 1 } ---- == Style/RedundantFreeze @@ -13457,6 +13516,43 @@ end | Array |=== +== Style/SingleLineDoEndBlock + +|=== +| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed + +| Pending +| Yes +| Yes +| 1.57 +| - +|=== + +Checks for single-line `do`...`end` block. + +In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic` +in `Style/BlockDelimiters`. The autocorrection maintains the `do` ... `end` syntax to +preserve semantics and does not change it to `{`...`}` block. + +=== Examples + +[source,ruby] +---- +# bad +foo do |arg| bar(arg) end + +# good +foo do |arg| + bar(arg) +end + +# bad +->(arg) do bar(arg) end + +# good +->(arg) { bar(arg) } +---- + == Style/SingleLineMethods |=== diff --git a/docs/modules/ROOT/pages/installation.adoc b/docs/modules/ROOT/pages/installation.adoc index c78eca60c71d..6f7065496222 100644 --- a/docs/modules/ROOT/pages/installation.adoc +++ b/docs/modules/ROOT/pages/installation.adoc @@ -22,7 +22,7 @@ in your `Gemfile`: [source,rb] ---- -gem 'rubocop', '~> 1.56', require: false +gem 'rubocop', '~> 1.57', require: false ---- .A Modular RuboCop diff --git a/lib/rubocop/version.rb b/lib/rubocop/version.rb index 25a9aa56fab6..7279fbf05ff1 100644 --- a/lib/rubocop/version.rb +++ b/lib/rubocop/version.rb @@ -3,7 +3,7 @@ module RuboCop # This module holds the RuboCop version information. module Version - STRING = '1.56.4' + STRING = '1.57.0' MSG = '%s (using Parser %s, ' \ 'rubocop-ast %s, ' \ diff --git a/relnotes/v1.57.0.md b/relnotes/v1.57.0.md new file mode 100644 index 000000000000..4c7f3af6b8c9 --- /dev/null +++ b/relnotes/v1.57.0.md @@ -0,0 +1,34 @@ +### New features + +* [#12227](https://github.com/rubocop/rubocop/pull/12227): Add new `Style/SingleLineDoEndBlock` cop. ([@koic][]) +* [#12246](https://github.com/rubocop/rubocop/pull/12246): Make `Lint/RedundantSafeNavigation` aware of constant receiver. ([@koic][]) +* [#12257](https://github.com/rubocop/rubocop/issues/12257): Make `Style/RedundantDoubleSplatHashBraces` aware of `merge` methods. ([@koic][]) + +### Bug fixes + +* [#12244](https://github.com/rubocop/rubocop/issues/12244): Fix a false negative for `Lint/Debugger` when using debugger method inside block. ([@koic][]) +* [#12231](https://github.com/rubocop/rubocop/issues/12231): Fix a false negative for `Metrics/ModuleLength` when defining a singleton class in a module. ([@koic][]) +* [#12249](https://github.com/rubocop/rubocop/issues/12249): Fix a false positive `Style/IdenticalConditionalBranches` when `if`..`else` with identical leading lines and assign to condition value. ([@koic][]) +* [#12253](https://github.com/rubocop/rubocop/pull/12253): Fix `Lint/LiteralInInterpolation` to accept an empty string literal interpolated in words literal. ([@knu][]) +* [#12198](https://github.com/rubocop/rubocop/issues/12198): Fix an error for flip-flop with beginless or endless ranges. ([@koic][]) +* [#12259](https://github.com/rubocop/rubocop/issues/12259): Fix an error for `Lint/MixedCaseRange` when using nested character class in regexp. ([@koic][]) +* [#12237](https://github.com/rubocop/rubocop/issues/12237): Fix an error for `Style/NestedTernaryOperator` when a ternary operator has a nested ternary operator within an `if`. ([@koic][]) +* [#12228](https://github.com/rubocop/rubocop/pull/12228): Fix false negatives for `Style/MultilineBlockChain` when using multiline block chain with safe navigation operator. ([@koic][]) +* [#12247](https://github.com/rubocop/rubocop/pull/12247): Fix false negatives for `Style/RedundantParentheses` when using logical or comparison expressions with redundant parentheses. ([@koic][]) +* [#12226](https://github.com/rubocop/rubocop/issues/12226): Fix false positives for `Layout/MultilineMethodCallIndentation` when aligning methods in multiline block chain. ([@koic][]) +* [#12076](https://github.com/rubocop/rubocop/issues/12076): Fixed an issue where the top-level cache folder was named differently during two consecutive rubocop runs. ([@K-S-A][]) + +### Changes + +* [#12235](https://github.com/rubocop/rubocop/pull/12235): Enable auto parallel inspection when config file is specified. ([@aboutNisblee][]) +* [#12234](https://github.com/rubocop/rubocop/pull/12234): Enhance `Style/FormatString`'s autocorrection when using known conversion methods whose return value is not an array. ([@koic][]) +* [#12128](https://github.com/rubocop/rubocop/issues/12128): Make `Style/GuardClause` aware of `define_method`. ([@koic][]) +* [#12126](https://github.com/rubocop/rubocop/pull/12126): Make `Style/RedundantFilterChain` aware of `select.present?` when `ActiveSupportExtensionsEnabled` config is `true`. ([@koic][]) +* [#12250](https://github.com/rubocop/rubocop/pull/12250): Mark `Lint/RedundantRequireStatement` as unsafe autocorrect. ([@koic][]) +* [#12097](https://github.com/rubocop/rubocop/issues/12097): Mark unsafe autocorrect for `Style/ClassEqualityComparison`. ([@koic][]) +* [#12210](https://github.com/rubocop/rubocop/issues/12210): Mark `Style/RedundantFilterChain` as unsafe autocorrect. ([@koic][]) + +[@koic]: https://github.com/koic +[@knu]: https://github.com/knu +[@K-S-A]: https://github.com/K-S-A +[@aboutNisblee]: https://github.com/aboutNisblee From 215ab03ccdf722ebc3b0c43a62649755f4280451 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Wed, 11 Oct 2023 12:51:41 +0200 Subject: [PATCH 0033/1411] Switch back the docs version --- docs/antora.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/antora.yml b/docs/antora.yml index ec7a70bdfe4f..9c897ea03d1d 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop title: RuboCop # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: '1.57' +version: ~ nav: - modules/ROOT/nav.adoc From e162c99c066dc9b98f61b2d99ec4a3a919cf9852 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 11 Oct 2023 20:51:03 +0900 Subject: [PATCH 0034/1411] Fix an incorrect autocorrect for `Style/RedundantDoubleSplatHashBraces` This PR fixes the following incorrect autocorrect for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` method call twice. ```console $ bundle exec rspec spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb:82 Run options: include {:locations=>{"./spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb"=>[82]}} (snip) Failures: 1) RuboCop::Cop::Style::RedundantDoubleSplatHashBraces registers an offense when using double splat hash braces with `merge` method call twice Failure/Error: expect(new_source).to eq(correction) expected: "do_something(foo: bar, **options)\ndo_something(baz: qux, **options)\n" got: "do_something(foo: bar, **options)\ndo_something(baz: qux.merge(options))\n" (compared using ==) Diff: @@ -1,3 +1,3 @@ do_something(foo: bar, **options) -do_something(baz: qux, **options) +do_something(baz: qux.merge(options)) # ./lib/rubocop/rspec/expect_offense.rb:164:in `expect_correction' # ./spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb:90:in `block (2 levels) in ' Finished in 0.15475 seconds (files took 1.24 seconds to load) 1 example, 1 failure ``` --- ...for_style_redundant_double_splat_hash_braces.md | 1 + .../style/redundant_double_splat_hash_braces.rb | 2 +- .../redundant_double_splat_hash_braces_spec.rb | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md diff --git a/changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md new file mode 100644 index 000000000000..f224ac81d303 --- /dev/null +++ b/changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md @@ -0,0 +1 @@ +* [#12262](https://github.com/rubocop/rubocop/pull/12262): Fix an incorrect autocorrect for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` method call twice. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index 6e3466877747..defcff640ae2 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -84,7 +84,7 @@ def range_of_merge_methods(merge_methods) end def extract_send_methods(kwsplat) - @extract_send_methods ||= kwsplat.each_descendant(:send, :csend) + kwsplat.each_descendant(:send, :csend) end def convert_to_new_arguments(node) diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index c0a3f4e4f8bf..538814e0c83e 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -79,6 +79,20 @@ RUBY end + it 'registers an offense when using double splat hash braces with `merge` method call twice' do + expect_offense(<<~RUBY) + do_something(**{ foo: bar }.merge(options)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + do_something(**{ baz: qux }.merge(options)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + RUBY + + expect_correction(<<~RUBY) + do_something(foo: bar, **options) + do_something(baz: qux, **options) + RUBY + end + it 'registers an offense when using double splat hash braces with `merge` multiple arguments method call' do expect_offense(<<~RUBY) do_something(**{foo: bar, baz: qux}.merge(options1, options2)) From 873cb9f1dfd2d02a574f0ad95de36a3f33547b3a Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Mon, 11 Sep 2023 23:35:28 +0900 Subject: [PATCH 0035/1411] Fix an incorrect autocorrect for `Style/RedundantException` when message is not string --- ...tocorrect_for_style_redundant_exception.md | 1 + lib/rubocop/cop/style/redundant_exception.rb | 44 ++++++--- .../cop/style/redundant_exception_spec.rb | 94 ++++++++++++++++--- 3 files changed, 113 insertions(+), 26 deletions(-) create mode 100644 changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md diff --git a/changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md b/changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md new file mode 100644 index 000000000000..f1611a55d191 --- /dev/null +++ b/changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md @@ -0,0 +1 @@ +* [#12177](https://github.com/rubocop/rubocop/pull/12177): Fix an incorrect autocorrect for `Style/RedundantException`. ([@ydah][]) diff --git a/lib/rubocop/cop/style/redundant_exception.rb b/lib/rubocop/cop/style/redundant_exception.rb index 03e09f6eaa08..ee557e732f13 100644 --- a/lib/rubocop/cop/style/redundant_exception.rb +++ b/lib/rubocop/cop/style/redundant_exception.rb @@ -5,17 +5,21 @@ module Cop module Style # Checks for RuntimeError as the argument of raise/fail. # - # It checks for code like this: - # # @example - # # Bad + # # bad # raise RuntimeError, 'message' - # - # # Bad # raise RuntimeError.new('message') # - # # Good + # # good # raise 'message' + # + # # bad - message is not a string + # raise RuntimeError, Object.new + # raise RuntimeError.new(Object.new) + # + # # good + # raise Object.new.to_s + # class RedundantException < Base extend AutoCorrector @@ -30,26 +34,42 @@ def on_send(node) fix_exploded(node) || fix_compact(node) end + private + def fix_exploded(node) exploded?(node) do |command, message| add_offense(node, message: MSG_1) do |corrector| - if node.parenthesized? - corrector.replace(node, "#{command}(#{message.source})") - else - corrector.replace(node, "#{command} #{message.source}") - end + corrector.replace(node, replaced_exploded(node, command, message)) end end end + def replaced_exploded(node, command, message) + arg = string_message?(message) ? message.source : "#{message.source}.to_s" + arg = node.parenthesized? ? "(#{arg})" : " #{arg}" + "#{command}#{arg}" + end + + def string_message?(message) + message.str_type? || message.dstr_type? || message.xstr_type? + end + def fix_compact(node) compact?(node) do |new_call, message| add_offense(node, message: MSG_2) do |corrector| - corrector.replace(new_call, message.source) + corrector.replace(new_call, replaced_compact(message)) end end end + def replaced_compact(message) + if string_message?(message) + message.source + else + "#{message.source}.to_s" + end + end + # @!method exploded?(node) def_node_matcher :exploded?, <<~PATTERN (send nil? ${:raise :fail} (const {nil? cbase} :RuntimeError) $_) diff --git a/spec/rubocop/cop/style/redundant_exception_spec.rb b/spec/rubocop/cop/style/redundant_exception_spec.rb index a02ad1249ccb..1e36452690ad 100644 --- a/spec/rubocop/cop/style/redundant_exception_spec.rb +++ b/spec/rubocop/cop/style/redundant_exception_spec.rb @@ -4,54 +4,54 @@ shared_examples 'common behavior' do |keyword, runtime_error| it "reports an offense for a #{keyword} with #{runtime_error}" do expect_offense(<<~RUBY, keyword: keyword, runtime_error: runtime_error) - %{keyword} %{runtime_error}, msg - ^{keyword}^^{runtime_error}^^^^^ Redundant `RuntimeError` argument can be removed. + %{keyword} %{runtime_error}, "message" + ^{keyword}^^{runtime_error}^^^^^^^^^^^ Redundant `RuntimeError` argument can be removed. RUBY expect_correction(<<~RUBY) - #{keyword} msg + #{keyword} "message" RUBY end it "reports an offense for a #{keyword} with #{runtime_error} and ()" do expect_offense(<<~RUBY, keyword: keyword, runtime_error: runtime_error) - %{keyword}(%{runtime_error}, msg) - ^{keyword}^^{runtime_error}^^^^^^ Redundant `RuntimeError` argument can be removed. + %{keyword}(%{runtime_error}, "message") + ^{keyword}^^{runtime_error}^^^^^^^^^^^^ Redundant `RuntimeError` argument can be removed. RUBY expect_correction(<<~RUBY) - #{keyword}(msg) + #{keyword}("message") RUBY end it "reports an offense for a #{keyword} with #{runtime_error}.new" do expect_offense(<<~RUBY, keyword: keyword, runtime_error: runtime_error) - %{keyword} %{runtime_error}.new msg - ^{keyword}^^{runtime_error}^^^^^^^^ Redundant `RuntimeError.new` call can be replaced with just the message. + %{keyword} %{runtime_error}.new "message" + ^{keyword}^^{runtime_error}^^^^^^^^^^^^^^ Redundant `RuntimeError.new` call can be replaced with just the message. RUBY expect_correction(<<~RUBY) - #{keyword} msg + #{keyword} "message" RUBY end it "reports an offense for a #{keyword} with #{runtime_error}.new" do expect_offense(<<~RUBY, keyword: keyword, runtime_error: runtime_error) - %{keyword} %{runtime_error}.new(msg) - ^{keyword}^^{runtime_error}^^^^^^^^^ Redundant `RuntimeError.new` call can be replaced with just the message. + %{keyword} %{runtime_error}.new("message") + ^{keyword}^^{runtime_error}^^^^^^^^^^^^^^^ Redundant `RuntimeError.new` call can be replaced with just the message. RUBY expect_correction(<<~RUBY) - #{keyword} msg + #{keyword} "message" RUBY end it "accepts a #{keyword} with #{runtime_error} if it does not have 2 args" do - expect_no_offenses("#{keyword} #{runtime_error}, msg, caller") + expect_no_offenses("#{keyword} #{runtime_error}, 'message', caller") end it 'accepts rescue w/ non redundant error' do - expect_no_offenses "#{keyword} OtherError, msg" + expect_no_offenses "#{keyword} OtherError, 'message'" end end @@ -59,4 +59,70 @@ include_examples 'common behavior', 'raise', '::RuntimeError' include_examples 'common behavior', 'fail', 'RuntimeError' include_examples 'common behavior', 'fail', '::RuntimeError' + + it 'registers an offense for raise with RuntimeError, "#{message}"' do + expect_offense(<<~'RUBY') + raise RuntimeError, "#{message}" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError` argument can be removed. + RUBY + + expect_correction(<<~'RUBY') + raise "#{message}" + RUBY + end + + it 'registers an offense for raise with RuntimeError, `command`' do + expect_offense(<<~RUBY) + raise RuntimeError, `command` + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError` argument can be removed. + RUBY + + expect_correction(<<~RUBY) + raise `command` + RUBY + end + + it 'registers an offense for raise with RuntimeError, Object.new' do + expect_offense(<<~RUBY) + raise RuntimeError, Object.new + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError` argument can be removed. + RUBY + + expect_correction(<<~RUBY) + raise Object.new.to_s + RUBY + end + + it 'registers an offense for raise with RuntimeError.new, Object.new and parans' do + expect_offense(<<~RUBY) + raise RuntimeError.new(Object.new) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError.new` call can be replaced with just the message. + RUBY + + expect_correction(<<~RUBY) + raise Object.new.to_s + RUBY + end + + it 'registers an offense for raise with RuntimeError.new, Object.new no parens' do + expect_offense(<<~RUBY) + raise RuntimeError.new Object.new + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError.new` call can be replaced with just the message. + RUBY + + expect_correction(<<~RUBY) + raise Object.new.to_s + RUBY + end + + it 'registers an offense for raise with RuntimeError, valiable' do + expect_offense(<<~RUBY) + raise RuntimeError, valiable + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError` argument can be removed. + RUBY + + expect_correction(<<~RUBY) + raise valiable.to_s + RUBY + end end From 84840b894ee6316d4367daf4cc96e03456e7374f Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 12 Oct 2023 00:47:27 +0900 Subject: [PATCH 0036/1411] Fix typos This commit fixes the following build error: ``` Check spelling of all files with codespell: spec/rubocop/cop/style/redundant_exception_spec.rb#L120 valiable ==> variable, valuable, available Check spelling of all files with codespell: spec/rubocop/cop/style/redundant_exception_spec.rb#L125 valiable ==> variable, valuable, available ``` https://github.com/rubocop/rubocop/actions/runs/6484903585 --- spec/rubocop/cop/style/redundant_exception_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/rubocop/cop/style/redundant_exception_spec.rb b/spec/rubocop/cop/style/redundant_exception_spec.rb index 1e36452690ad..7632bfe7de6d 100644 --- a/spec/rubocop/cop/style/redundant_exception_spec.rb +++ b/spec/rubocop/cop/style/redundant_exception_spec.rb @@ -115,14 +115,14 @@ RUBY end - it 'registers an offense for raise with RuntimeError, valiable' do + it 'registers an offense for raise with RuntimeError, variable' do expect_offense(<<~RUBY) - raise RuntimeError, valiable + raise RuntimeError, variable ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError` argument can be removed. RUBY expect_correction(<<~RUBY) - raise valiable.to_s + raise variable.to_s RUBY end end From a4a505da327c7a0dcd0e2d6bed2149628ed3e614 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 12 Oct 2023 00:43:54 +0900 Subject: [PATCH 0037/1411] [Fix #12265] Fix an error for `Layout/MultilineMethodCallIndentation` Fixes #12265. This PR fixes an error for `Layout/MultilineMethodCallIndentation` when usingarithmetic operation with block inside a grouped expression. --- ...ror_for_layout_multiline_method_call_indentation.md | 1 + .../cop/layout/multiline_method_call_indentation.rb | 2 +- .../layout/multiline_method_call_indentation_spec.rb | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_an_error_for_layout_multiline_method_call_indentation.md diff --git a/changelog/fix_an_error_for_layout_multiline_method_call_indentation.md b/changelog/fix_an_error_for_layout_multiline_method_call_indentation.md new file mode 100644 index 000000000000..e82585d6dfff --- /dev/null +++ b/changelog/fix_an_error_for_layout_multiline_method_call_indentation.md @@ -0,0 +1 @@ +* [#12265](https://github.com/rubocop/rubocop/issues/12265): Fix an error for `Layout/MultilineMethodCallIndentation` when usingarithmetic operation with block inside a grouped expression. ([@koic][]) diff --git a/lib/rubocop/cop/layout/multiline_method_call_indentation.rb b/lib/rubocop/cop/layout/multiline_method_call_indentation.rb index aaaeea54c946..afb76b900745 100644 --- a/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +++ b/lib/rubocop/cop/layout/multiline_method_call_indentation.rb @@ -182,7 +182,7 @@ def semantic_alignment_base(node, rhs) return unless rhs.source.start_with?('.', '&.') node = semantic_alignment_node(node) - return unless node&.loc&.selector + return unless node&.loc&.selector && node.loc.dot node.loc.dot.join(node.loc.selector) end diff --git a/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb b/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb index f141d037fd67..6fa108d3c150 100644 --- a/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb +++ b/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb @@ -73,6 +73,16 @@ RUBY end + it 'accepts arithmetic operation with block inside a grouped expression' do + expect_no_offenses(<<~RUBY) + ( + a * b do + end + ) + .c + RUBY + end + it 'accepts an expression where the first method spans multiple lines' do expect_no_offenses(<<~RUBY) subject.each do |item| From 7edb5cab7487973809ddade987f80ae7b131c81e Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Thu, 12 Oct 2023 15:22:08 +0900 Subject: [PATCH 0038/1411] [Fix #12261] Fix an infinite loop for `Layout/MultilineMethodCallIndentation` Fix: https://github.com/rubocop/rubocop/issues/12261 --- ...ayout_multiline_method_call_indentation.md | 1 + .../multiline_method_call_indentation.rb | 6 +++++- .../multiline_method_call_indentation_spec.rb | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md diff --git a/changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md b/changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md new file mode 100644 index 000000000000..6dfce8abf187 --- /dev/null +++ b/changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md @@ -0,0 +1 @@ +* [#12261](https://github.com/rubocop/rubocop/issues/12261): Fix an infinite loop for `Layout/MultilineMethodCallIndentation` when multiline method chain with a block argument and method chain. ([@ydah][]) diff --git a/lib/rubocop/cop/layout/multiline_method_call_indentation.rb b/lib/rubocop/cop/layout/multiline_method_call_indentation.rb index afb76b900745..aa6c1c723abd 100644 --- a/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +++ b/lib/rubocop/cop/layout/multiline_method_call_indentation.rb @@ -227,7 +227,11 @@ def find_multiline_block_chain_node(node) return unless (block_node = node.each_descendant(:block, :numblock).first) return unless block_node.multiline? && block_node.parent.call_type? - block_node.parent + if node.receiver.call_type? + node.receiver + else + block_node.parent + end end def first_call_has_a_dot(node) diff --git a/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb b/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb index 6fa108d3c150..2ddd9f87501b 100644 --- a/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb +++ b/spec/rubocop/cop/layout/multiline_method_call_indentation_spec.rb @@ -99,6 +99,16 @@ RUBY end + it 'accepts aligned methods when multiline method chain with a block argument and method chain' do + expect_no_offenses(<<~RUBY) + a(b) + .c( + d do + end.f + ) + RUBY + end + it "doesn't crash on unaligned multiline lambdas" do expect_no_offenses(<<~RUBY) MyClass.(my_args) @@ -335,6 +345,16 @@ &.b RUBY end + + it 'accepts aligned methods when multiline method chain with a block argument and method chain' do + expect_no_offenses(<<~RUBY) + a&.(b) + .c( + d do + end.f + ) + RUBY + end end end From 128618c7a8e3336bbe9ff8f800a73ff04dfc7a81 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 12 Oct 2023 11:30:56 +0900 Subject: [PATCH 0039/1411] Fix false positives for `Style/RedundantDoubleSplatHashBraces` Fixes #12263. This PR fixes false positives for `Style/RedundantDoubleSplatHashBraces` when method call for no hash braced double splat receiver. The code shown in #12263 is incompatible as shown below and is a false positive: ```ruby def x(opts) = puts(opts) h = {foo: :bar} x(**h.merge(k: :h)) #=> {:foo=>:bar, :k=>:h} x(k: :v, **h) #=> {:k=>:v, :foo=>:bar} ``` --- ...tyle_redundant_double_splat_hash_braces.md | 1 + .../redundant_double_splat_hash_braces.rb | 22 +++++++++++++++++-- ...redundant_double_splat_hash_braces_spec.rb | 12 ++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md diff --git a/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md new file mode 100644 index 000000000000..e4f013193dc6 --- /dev/null +++ b/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md @@ -0,0 +1 @@ +* [#12263](https://github.com/rubocop/rubocop/issues/12263): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when method call for no hash braced double splat receiver. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index defcff640ae2..573ee0b0ff82 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -27,10 +27,11 @@ class RedundantDoubleSplatHashBraces < Base # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def on_hash(node) - return if !node.braces? || node.pairs.empty? || node.pairs.any?(&:hash_rocket?) + return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?) return unless (parent = node.parent) - return unless (kwsplat = node.each_ancestor(:kwsplat).first) return if parent.call_type? && !merge_method?(parent) + return unless (kwsplat = node.each_ancestor(:kwsplat).first) + return if allowed_double_splat_receiver?(kwsplat) add_offense(kwsplat) do |corrector| autocorrect(corrector, node, kwsplat) @@ -40,6 +41,14 @@ def on_hash(node) private + def allowed_double_splat_receiver?(kwsplat) + return false unless kwsplat.children.first.call_type? + + root_receiver = root_receiver(kwsplat.children.first) + + !root_receiver&.hash_type? + end + def autocorrect(corrector, node, kwsplat) corrector.remove(kwsplat.loc.operator) corrector.remove(opening_brace(node)) @@ -51,6 +60,15 @@ def autocorrect(corrector, node, kwsplat) autocorrect_merge_methods(corrector, merge_methods, kwsplat) end + def root_receiver(node) + receiver = node.receiver + if receiver&.receiver + root_receiver(receiver) + else + receiver + end + end + def select_merge_method_nodes(kwsplat) extract_send_methods(kwsplat).select do |node| merge_method?(node) diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index 538814e0c83e..f57e2d33f247 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -138,6 +138,18 @@ RUBY end + it 'does not register an offense when method call for no hash braced double splat receiver' do + expect_no_offenses(<<~RUBY) + do_something(**options.merge({foo: bar})) + RUBY + end + + it 'does not register an offense when safe navigation method call for no hash braced double splat receiver' do + expect_no_offenses(<<~RUBY) + do_something(**options&.merge({foo: bar})) + RUBY + end + it 'does not register an offense when using empty double splat hash braces arguments' do expect_no_offenses(<<~RUBY) do_something(**{}) From 12016d8894cff2cb079a26a51e4e5dc6a6cb936f Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 13 Oct 2023 12:24:09 +0900 Subject: [PATCH 0040/1411] [Fix #12271] Fix a false positive for `Lint/RedundantSafeNavigation` Fixes #12271. This PR fixes a false positive for `Lint/RedundantSafeNavigation` when using snake case constant receiver. Camel case is used for naming classes and modules, while snake case is used for all other constants. This naming conforms with `Naming/ConstantName` cop. Since constants that turn into classes or modules are normally not `nil`, they will continue to be detected. However, this PR will update to allow safe navigation for constants in snake case. This change resolves both issue https://github.com/rubocop/rubocop-rails/issues/1104 and #12271. --- ...tive_for_lint_redundant_safe_navigation.md | 1 + .../cop/lint/redundant_safe_navigation.rb | 14 ++++++++----- .../lint/redundant_safe_navigation_spec.rb | 21 +++++++++++++++---- 3 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md diff --git a/changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md b/changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md new file mode 100644 index 000000000000..f07d8876009a --- /dev/null +++ b/changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md @@ -0,0 +1 @@ +* [#12271](https://github.com/rubocop/rubocop/issues/12271): Fix a false positive for `Lint/RedundantSafeNavigation` when using snake case constant receiver. ([@koic][]) diff --git a/lib/rubocop/cop/lint/redundant_safe_navigation.rb b/lib/rubocop/cop/lint/redundant_safe_navigation.rb index 0629fb213bee..2c01c514b686 100644 --- a/lib/rubocop/cop/lint/redundant_safe_navigation.rb +++ b/lib/rubocop/cop/lint/redundant_safe_navigation.rb @@ -4,8 +4,8 @@ module RuboCop module Cop module Lint # Checks for redundant safe navigation calls. - # Use cases where a constant is `nil` are rare and an offense is detected - # when the receiver is a constant. + # Use cases where a constant, named in camel case for classes and modules is `nil` are rare, + # and an offense is not detected when the receiver is a snake case constant. # # For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, # and `equal?` methods are checked by default. @@ -26,7 +26,7 @@ module Lint # # @example # # bad - # Const&.do_something + # CamelCaseConst&.do_something # # # bad # do_something if attrs&.respond_to?(:[]) @@ -40,7 +40,7 @@ module Lint # end # # # good - # Const.do_something + # CamelCaseConst.do_something # # # good # while node.is_a?(BeginNode) @@ -67,13 +67,16 @@ class RedundantSafeNavigation < Base NIL_SPECIFIC_METHODS = (nil.methods - Object.new.methods).to_set.freeze + SNAKE_CASE = /\A[[:digit:][:upper:]_]+\z/.freeze + # @!method respond_to_nil_specific_method?(node) def_node_matcher :respond_to_nil_specific_method?, <<~PATTERN (csend _ :respond_to? (sym %NIL_SPECIFIC_METHODS)) PATTERN + # rubocop:disable Metrics/AbcSize def on_csend(node) - unless node.receiver.const_type? + unless node.receiver.const_type? && !node.receiver.source.match?(SNAKE_CASE) return unless check?(node) && allowed_method?(node.method_name) return if respond_to_nil_specific_method?(node) end @@ -81,6 +84,7 @@ def on_csend(node) range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos) add_offense(range) { |corrector| corrector.replace(node.loc.dot, '.') } end + # rubocop:enable Metrics/AbcSize private diff --git a/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb b/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb index 74430a016ccf..478a8ea86762 100644 --- a/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb +++ b/spec/rubocop/cop/lint/redundant_safe_navigation_spec.rb @@ -3,14 +3,27 @@ RSpec.describe RuboCop::Cop::Lint::RedundantSafeNavigation, :config do let(:cop_config) { { 'AllowedMethods' => %w[respond_to?] } } - it 'registers an offense and corrects when `&.` is used for const receiver' do + it 'registers an offense and corrects when `&.` is used for camel case const receiver' do expect_offense(<<~RUBY) - Foo&.do_something - ^^^^^^^^^^^^^^ Redundant safe navigation detected. + Const&.do_something + ^^^^^^^^^^^^^^ Redundant safe navigation detected. + ConstName&.do_something + ^^^^^^^^^^^^^^ Redundant safe navigation detected. + Const_name&.do_something # It is treated as camel case, similar to the `Naming/ConstantName` cop. + ^^^^^^^^^^^^^^ Redundant safe navigation detected. RUBY expect_correction(<<~RUBY) - Foo.do_something + Const.do_something + ConstName.do_something + Const_name.do_something # It is treated as camel case, similar to the `Naming/ConstantName` cop. + RUBY + end + + it 'does not register an offense and corrects when `&.` is used for snake case const receiver' do + expect_no_offenses(<<~RUBY) + CONST&.do_something + CONST_NAME&.do_something RUBY end From a302d0cf3a34016d2240e0183a04d3012d022a54 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 13 Oct 2023 09:35:36 +0200 Subject: [PATCH 0041/1411] Update Changelog --- CHANGELOG.md | 9 +++++++++ ..._false_positive_for_lint_redundant_safe_navigation.md | 1 - ...error_for_layout_multiline_method_call_indentation.md | 1 - ...ncorrect_autocorrect_for_style_redundant_exception.md | 1 - ..._loop_for_layout_multiline_method_call_indentation.md | 1 - ...itive_for_style_redundant_double_splat_hash_braces.md | 1 - ...rrect_for_style_redundant_double_splat_hash_braces.md | 1 - 7 files changed, 9 insertions(+), 6 deletions(-) delete mode 100644 changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md delete mode 100644 changelog/fix_an_error_for_layout_multiline_method_call_indentation.md delete mode 100644 changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md delete mode 100644 changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md delete mode 100644 changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md delete mode 100644 changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 19360bac67f6..63a82016a524 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ ## master (unreleased) +### Bug fixes + +* [#12271](https://github.com/rubocop/rubocop/issues/12271): Fix a false positive for `Lint/RedundantSafeNavigation` when using snake case constant receiver. ([@koic][]) +* [#12265](https://github.com/rubocop/rubocop/issues/12265): Fix an error for `Layout/MultilineMethodCallIndentation` when usingarithmetic operation with block inside a grouped expression. ([@koic][]) +* [#12177](https://github.com/rubocop/rubocop/pull/12177): Fix an incorrect autocorrect for `Style/RedundantException`. ([@ydah][]) +* [#12261](https://github.com/rubocop/rubocop/issues/12261): Fix an infinite loop for `Layout/MultilineMethodCallIndentation` when multiline method chain with a block argument and method chain. ([@ydah][]) +* [#12263](https://github.com/rubocop/rubocop/issues/12263): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when method call for no hash braced double splat receiver. ([@koic][]) +* [#12262](https://github.com/rubocop/rubocop/pull/12262): Fix an incorrect autocorrect for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` method call twice. ([@koic][]) + ## 1.57.0 (2023-10-11) ### New features diff --git a/changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md b/changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md deleted file mode 100644 index f07d8876009a..000000000000 --- a/changelog/fix_a_false_positive_for_lint_redundant_safe_navigation.md +++ /dev/null @@ -1 +0,0 @@ -* [#12271](https://github.com/rubocop/rubocop/issues/12271): Fix a false positive for `Lint/RedundantSafeNavigation` when using snake case constant receiver. ([@koic][]) diff --git a/changelog/fix_an_error_for_layout_multiline_method_call_indentation.md b/changelog/fix_an_error_for_layout_multiline_method_call_indentation.md deleted file mode 100644 index e82585d6dfff..000000000000 --- a/changelog/fix_an_error_for_layout_multiline_method_call_indentation.md +++ /dev/null @@ -1 +0,0 @@ -* [#12265](https://github.com/rubocop/rubocop/issues/12265): Fix an error for `Layout/MultilineMethodCallIndentation` when usingarithmetic operation with block inside a grouped expression. ([@koic][]) diff --git a/changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md b/changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md deleted file mode 100644 index f1611a55d191..000000000000 --- a/changelog/fix_an_incorrect_autocorrect_for_style_redundant_exception.md +++ /dev/null @@ -1 +0,0 @@ -* [#12177](https://github.com/rubocop/rubocop/pull/12177): Fix an incorrect autocorrect for `Style/RedundantException`. ([@ydah][]) diff --git a/changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md b/changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md deleted file mode 100644 index 6dfce8abf187..000000000000 --- a/changelog/fix_an_infinite_loop_for_layout_multiline_method_call_indentation.md +++ /dev/null @@ -1 +0,0 @@ -* [#12261](https://github.com/rubocop/rubocop/issues/12261): Fix an infinite loop for `Layout/MultilineMethodCallIndentation` when multiline method chain with a block argument and method chain. ([@ydah][]) diff --git a/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md deleted file mode 100644 index e4f013193dc6..000000000000 --- a/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md +++ /dev/null @@ -1 +0,0 @@ -* [#12263](https://github.com/rubocop/rubocop/issues/12263): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when method call for no hash braced double splat receiver. ([@koic][]) diff --git a/changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md deleted file mode 100644 index f224ac81d303..000000000000 --- a/changelog/fix_incorrect_autocorrect_for_style_redundant_double_splat_hash_braces.md +++ /dev/null @@ -1 +0,0 @@ -* [#12262](https://github.com/rubocop/rubocop/pull/12262): Fix an incorrect autocorrect for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` method call twice. ([@koic][]) From 9141fe50b7c3a884852f5e49688a3f5dd3d2f7e0 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 13 Oct 2023 09:35:57 +0200 Subject: [PATCH 0042/1411] Cut 1.57.1 --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- CHANGELOG.md | 2 ++ CONTRIBUTING.md | 2 +- docs/antora.yml | 2 +- docs/modules/ROOT/pages/cops_lint.adoc | 8 ++++---- docs/modules/ROOT/pages/cops_style.adoc | 15 +++++++++------ lib/rubocop/version.rb | 2 +- relnotes/v1.57.1.md | 11 +++++++++++ 8 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 relnotes/v1.57.1.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index a28b0084b3f7..0ef7cc151be4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -38,7 +38,7 @@ output by `rubocop -V`, include them as well. Here's an example: ``` $ [bundle exec] rubocop -V -1.57.0 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] +1.57.1 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] - rubocop-performance 1.18.0 - rubocop-rspec 2.23.2 ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 63a82016a524..ecd39d45116c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ ## master (unreleased) +## 1.57.1 (2023-10-13) + ### Bug fixes * [#12271](https://github.com/rubocop/rubocop/issues/12271): Fix a false positive for `Lint/RedundantSafeNavigation` when using snake case constant receiver. ([@koic][]) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index efcfe5da9a46..09396ae24888 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ do so. ```console $ rubocop -V -1.57.0 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] +1.57.1 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] - rubocop-performance 1.18.0 - rubocop-rspec 2.23.2 ``` diff --git a/docs/antora.yml b/docs/antora.yml index 9c897ea03d1d..ec7a70bdfe4f 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop title: RuboCop # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: ~ +version: '1.57' nav: - modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/pages/cops_lint.adoc b/docs/modules/ROOT/pages/cops_lint.adoc index 60ddfaafcbaa..cb79a7dbbf47 100644 --- a/docs/modules/ROOT/pages/cops_lint.adoc +++ b/docs/modules/ROOT/pages/cops_lint.adoc @@ -4654,8 +4654,8 @@ require 'unloaded_feature' |=== Checks for redundant safe navigation calls. -Use cases where a constant is `nil` are rare and an offense is detected -when the receiver is a constant. +Use cases where a constant, named in camel case for classes and modules is `nil` are rare, +and an offense is not detected when the receiver is a snake case constant. For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, and `equal?` methods are checked by default. @@ -4680,7 +4680,7 @@ will be autocorrected to never return `nil`. [source,ruby] ---- # bad -Const&.do_something +CamelCaseConst&.do_something # bad do_something if attrs&.respond_to?(:[]) @@ -4694,7 +4694,7 @@ while node&.is_a?(BeginNode) end # good -Const.do_something +CamelCaseConst.do_something # good while node.is_a?(BeginNode) diff --git a/docs/modules/ROOT/pages/cops_style.adoc b/docs/modules/ROOT/pages/cops_style.adoc index 0be1a6a3fe84..9e37ef3c8c3b 100644 --- a/docs/modules/ROOT/pages/cops_style.adoc +++ b/docs/modules/ROOT/pages/cops_style.adoc @@ -11287,20 +11287,23 @@ array.each_with_object { |v, o| do_something(v, o) } Checks for RuntimeError as the argument of raise/fail. -It checks for code like this: - === Examples [source,ruby] ---- -# Bad +# bad raise RuntimeError, 'message' - -# Bad raise RuntimeError.new('message') -# Good +# good raise 'message' + +# bad - message is not a string +raise RuntimeError, Object.new +raise RuntimeError.new(Object.new) + +# good +raise Object.new.to_s ---- === References diff --git a/lib/rubocop/version.rb b/lib/rubocop/version.rb index 7279fbf05ff1..341e6e11f03d 100644 --- a/lib/rubocop/version.rb +++ b/lib/rubocop/version.rb @@ -3,7 +3,7 @@ module RuboCop # This module holds the RuboCop version information. module Version - STRING = '1.57.0' + STRING = '1.57.1' MSG = '%s (using Parser %s, ' \ 'rubocop-ast %s, ' \ diff --git a/relnotes/v1.57.1.md b/relnotes/v1.57.1.md new file mode 100644 index 000000000000..dd2bd339eab2 --- /dev/null +++ b/relnotes/v1.57.1.md @@ -0,0 +1,11 @@ +### Bug fixes + +* [#12271](https://github.com/rubocop/rubocop/issues/12271): Fix a false positive for `Lint/RedundantSafeNavigation` when using snake case constant receiver. ([@koic][]) +* [#12265](https://github.com/rubocop/rubocop/issues/12265): Fix an error for `Layout/MultilineMethodCallIndentation` when usingarithmetic operation with block inside a grouped expression. ([@koic][]) +* [#12177](https://github.com/rubocop/rubocop/pull/12177): Fix an incorrect autocorrect for `Style/RedundantException`. ([@ydah][]) +* [#12261](https://github.com/rubocop/rubocop/issues/12261): Fix an infinite loop for `Layout/MultilineMethodCallIndentation` when multiline method chain with a block argument and method chain. ([@ydah][]) +* [#12263](https://github.com/rubocop/rubocop/issues/12263): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when method call for no hash braced double splat receiver. ([@koic][]) +* [#12262](https://github.com/rubocop/rubocop/pull/12262): Fix an incorrect autocorrect for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` method call twice. ([@koic][]) + +[@koic]: https://github.com/koic +[@ydah]: https://github.com/ydah From b7fb0641a8289dc93401f1a95963fa43f7ed4a7d Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Fri, 13 Oct 2023 09:37:22 +0200 Subject: [PATCH 0043/1411] Switch back the docs version --- docs/antora.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/antora.yml b/docs/antora.yml index ec7a70bdfe4f..9c897ea03d1d 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop title: RuboCop # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: '1.57' +version: ~ nav: - modules/ROOT/nav.adoc From a8bea2b9852281c31fd2c05048272a278851c73b Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 14 Oct 2023 02:04:32 +0900 Subject: [PATCH 0044/1411] [Fix #12275] Fix a false positive for `Style/RedundantDoubleSplatHashBraces` Fixes #12275. This PR fixes a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat within block argument containing a hash literal in an array literal. --- ...style_redundant_double_splat_hash_brace.md | 1 + .../redundant_double_splat_hash_braces.rb | 6 ++-- ...redundant_double_splat_hash_braces_spec.rb | 33 +++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md diff --git a/changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md b/changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md new file mode 100644 index 000000000000..71fa909b5bf9 --- /dev/null +++ b/changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md @@ -0,0 +1 @@ +* [#12275](https://github.com/rubocop/rubocop/issues/12275): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat within block argument containing a hash literal in an array literal. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index 573ee0b0ff82..6a66f5107198 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -42,9 +42,11 @@ def on_hash(node) private def allowed_double_splat_receiver?(kwsplat) - return false unless kwsplat.children.first.call_type? + first_child = kwsplat.children.first + return true if first_child.block_type? || first_child.numblock_type? + return false unless first_child.call_type? - root_receiver = root_receiver(kwsplat.children.first) + root_receiver = root_receiver(first_child) !root_receiver&.hash_type? end diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index f57e2d33f247..fbaac2eec16f 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -126,6 +126,21 @@ RUBY end + it 'registers an offense when using double splat hash braces inside block' do + expect_offense(<<~RUBY) + block do + do_something(**{foo: bar, baz: qux}) + ^^^^^^^^^^^^^^^^^^^^^^ Remove the redundant double splat and braces, use keyword arguments directly. + end + RUBY + + expect_correction(<<~RUBY) + block do + do_something(foo: bar, baz: qux) + end + RUBY + end + it 'does not register an offense when using keyword arguments' do expect_no_offenses(<<~RUBY) do_something(foo: bar, baz: qux) @@ -191,4 +206,22 @@ { a: a } RUBY end + + it 'does not register an offense when using double splat within block argument containing a hash literal in an array literal' do + expect_no_offenses(<<~RUBY) + do_something(**x.do_something { [foo: bar] }) + RUBY + end + + it 'does not register an offense when using double splat within block argument containing a nested hash literal' do + expect_no_offenses(<<~RUBY) + do_something(**x.do_something { {foo: {bar: baz}} }) + RUBY + end + + it 'does not register an offense when using double splat within numbered block argument containing a nested hash literal' do + expect_no_offenses(<<~RUBY) + do_something(**x.do_something { {foo: {bar: _1}} }) + RUBY + end end From c3ac85d8445e0d821a34e1539fc46657f1620b5a Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 14 Oct 2023 03:30:10 +0900 Subject: [PATCH 0045/1411] [Fix #12279] Fix false positives for `Lint/EmptyConditionalBody` Fixes #12279. This PR fixes false positives for `Lint/EmptyConditionalBody` when missing 2nd `if` body with a comment. --- ...sitives_for_lint_empty_conditional_body.md | 1 + lib/rubocop/cop/mixin/comments_help.rb | 28 +++++++++++-------- .../cop/lint/empty_conditional_body_spec.rb | 15 ++++++++-- 3 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 changelog/fix_false_positives_for_lint_empty_conditional_body.md diff --git a/changelog/fix_false_positives_for_lint_empty_conditional_body.md b/changelog/fix_false_positives_for_lint_empty_conditional_body.md new file mode 100644 index 000000000000..ac478160f0c2 --- /dev/null +++ b/changelog/fix_false_positives_for_lint_empty_conditional_body.md @@ -0,0 +1 @@ +* [#12279](https://github.com/rubocop/rubocop/issues/12279): Fix false positives for `Lint/EmptyConditionalBody` when missing 2nd `if` body with a comment. ([@koic][]) diff --git a/lib/rubocop/cop/mixin/comments_help.rb b/lib/rubocop/cop/mixin/comments_help.rb index f199103e3428..701c486582fd 100644 --- a/lib/rubocop/cop/mixin/comments_help.rb +++ b/lib/rubocop/cop/mixin/comments_help.rb @@ -62,25 +62,29 @@ def buffer # Returns the end line of a node, which might be a comment and not part of the AST # End line is considered either the line at which another node starts, or # the line at which the parent node ends. - # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Lint/DuplicateBranch + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity def find_end_line(node) - if node.if_type? && node.else? - node.loc.else.line - elsif node.if_type? && node.ternary? - node.else_branch.loc.line - elsif node.if_type? && node.elsif? - node.each_ancestor(:if).find(&:if?).loc.end.line + if node.if_type? + if node.else? + node.loc.else.line + elsif node.ternary? + node.else_branch.loc.line + elsif node.elsif? + node.each_ancestor(:if).find(&:if?).loc.end.line + end elsif node.block_type? || node.numblock_type? node.loc.end.line elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node) next_sibling.loc.line elsif (parent = node.parent) - parent.loc.respond_to?(:end) && parent.loc.end ? parent.loc.end.line : parent.loc.line - else - node.loc.end.line - end + if parent.loc.respond_to?(:end) && parent.loc.end + parent.loc.end.line + else + parent.loc.line + end + end || node.loc.end.line end - # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Lint/DuplicateBranch + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity end end end diff --git a/spec/rubocop/cop/lint/empty_conditional_body_spec.rb b/spec/rubocop/cop/lint/empty_conditional_body_spec.rb index d005968f9a4e..774b182d8a80 100644 --- a/spec/rubocop/cop/lint/empty_conditional_body_spec.rb +++ b/spec/rubocop/cop/lint/empty_conditional_body_spec.rb @@ -75,6 +75,17 @@ class Foo RUBY end + it 'does not register an offense for missing 2nd `if` body with a comment' do + expect_no_offenses(<<~RUBY) + if condition1 + do_something1 + end + if condition2 + # noop + end + RUBY + end + it 'does not register an offense for missing 2nd `elsif` body with a comment' do expect_no_offenses(<<~RUBY) if condition1 @@ -347,10 +358,10 @@ class Foo it 'registers an offense for multi-line value omission in `unless`' do expect_offense(<<~RUBY) var = + # This is the value of `other:`, like so: `other: condition || other_condition` unless object.action value:, other: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid `unless` branches without a body. - condition || other_condition # This is the value of `other:`, like so: - # `other: condition || other_condition` + condition || other_condition end RUBY end From 1e5bd7e9d80fcfc47521b7c1f2d5a09f58203c2a Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 15 Oct 2023 00:05:31 +0900 Subject: [PATCH 0046/1411] Fix an error for `Style/SingleLineDoEndBlock` This PR fixes the following error for `Style/SingleLineDoEndBlock` when using single line `do`...`end` with no body ```console $ echo 'foo do end' | bunlde exec rubocop --stdin test.rb -d --only Style/SingleLineDoEndBlock (snip) An error occurred while Style/SingleLineDoEndBlock cop was inspecting /Users/koic/src/github.com/rubocop/rubocop/test.rb:1:0. Expected a Parser::Source::Range, Comment or RuboCop::AST::Node, got NilClass /Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/corrector.rb:111:in `to_range' /Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/corrector.rb:120:in `check_range_validity' /Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/gems/parser-3.2.2.4/ lib/parser/source/tree_rewriter.rb:398:in `combine' /Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/gems/parser-3.2.2.4/ lib/parser/source/tree_rewriter.rb:207:in `wrap' /Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/gems/parser-3.2.2.4/ lib/parser/source/tree_rewriter.rb:243:in `insert_after' /Users/koic/src/github.com/rubocop/rubocop/lib/rubocop/cop/style/single_line_do_end_block.rb:45:in `block in on_block' ``` --- ...rror_for_style_single_line_do_end_block.md | 1 + .../cop/style/single_line_do_end_block.rb | 4 ++- .../style/single_line_do_end_block_spec.rb | 33 +++++++++++++------ 3 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 changelog/fix_an_error_for_style_single_line_do_end_block.md diff --git a/changelog/fix_an_error_for_style_single_line_do_end_block.md b/changelog/fix_an_error_for_style_single_line_do_end_block.md new file mode 100644 index 000000000000..3b31e02ebbad --- /dev/null +++ b/changelog/fix_an_error_for_style_single_line_do_end_block.md @@ -0,0 +1 @@ +* [#12283](https://github.com/rubocop/rubocop/pull/12283): Fix an error for `Style/SingleLineDoEndBlock` when using single line `do`...`end` with no body. ([@koic][]) diff --git a/lib/rubocop/cop/style/single_line_do_end_block.rb b/lib/rubocop/cop/style/single_line_do_end_block.rb index 4d738a69c406..e91e92b863cd 100644 --- a/lib/rubocop/cop/style/single_line_do_end_block.rb +++ b/lib/rubocop/cop/style/single_line_do_end_block.rb @@ -30,6 +30,7 @@ class SingleLineDoEndBlock < Base MSG = 'Prefer multiline `do`...`end` block.' + # rubocop:disable Metrics/AbcSize def on_block(node) return if !node.single_line? || node.braces? @@ -42,10 +43,11 @@ def on_block(node) corrector.remove(node.loc.end) corrector.insert_after(node_body.loc.heredoc_end, "\nend") else - corrector.insert_after(node_body, "\n") + corrector.insert_before(node.loc.end, "\n") end end end + # rubocop:enable Metrics/AbcSize alias on_numblock on_block private diff --git a/spec/rubocop/cop/style/single_line_do_end_block_spec.rb b/spec/rubocop/cop/style/single_line_do_end_block_spec.rb index cff9d124a0ef..906c4a1095c8 100644 --- a/spec/rubocop/cop/style/single_line_do_end_block_spec.rb +++ b/spec/rubocop/cop/style/single_line_do_end_block_spec.rb @@ -9,8 +9,21 @@ expect_correction(<<~RUBY) foo do - bar - end + bar#{' '} + end + RUBY + end + + it 'registers an offense when using single line `do`...`end` with no body' do + expect_offense(<<~RUBY) + foo do end + ^^^^^^^^^^ Prefer multiline `do`...`end` block. + RUBY + + expect_correction(<<~RUBY) + foo do + #{' '} + end RUBY end @@ -22,8 +35,8 @@ expect_correction(<<~RUBY) foo do |arg| - bar(arg) - end + bar(arg)#{' '} + end RUBY end @@ -35,8 +48,8 @@ expect_correction(<<~RUBY) foo do - bar(_1) - end + bar(_1)#{' '} + end RUBY end @@ -65,8 +78,8 @@ expect_correction(<<~RUBY) ->(arg) do - foo arg - end + foo arg#{' '} + end RUBY end @@ -78,8 +91,8 @@ expect_correction(<<~RUBY) lambda do |arg| - foo(arg) - end + foo(arg)#{' '} + end RUBY end From e5866b655b3c579bb97b9c25328fd5033161e5fe Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 15 Oct 2023 16:41:01 +0900 Subject: [PATCH 0047/1411] [Fix #12284] Fix false positives for `Style/SingleArgumentDig` Fixes #12284. This PR fixes false positives for `Style/SingleArgumentDig` when using some anonymous argument syntax. --- ...positives_for_style_single_argument_dig.md | 1 + lib/rubocop/cop/style/single_argument_dig.rb | 3 +- .../cop/style/single_argument_dig_spec.rb | 34 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_false_positives_for_style_single_argument_dig.md diff --git a/changelog/fix_false_positives_for_style_single_argument_dig.md b/changelog/fix_false_positives_for_style_single_argument_dig.md new file mode 100644 index 000000000000..a330483eb136 --- /dev/null +++ b/changelog/fix_false_positives_for_style_single_argument_dig.md @@ -0,0 +1 @@ +* [#12284](https://github.com/rubocop/rubocop/issues/12284): Fix false positives for `Style/SingleArgumentDig` when using some anonymous argument syntax. ([@koic][]) diff --git a/lib/rubocop/cop/style/single_argument_dig.rb b/lib/rubocop/cop/style/single_argument_dig.rb index 5531b42f5a87..4ef196764212 100644 --- a/lib/rubocop/cop/style/single_argument_dig.rb +++ b/lib/rubocop/cop/style/single_argument_dig.rb @@ -33,6 +33,7 @@ class SingleArgumentDig < Base MSG = 'Use `%s[%s]` instead of `%s`.' RESTRICT_ON_SEND = %i[dig].freeze + IGNORED_ARGUMENT_TYPES = %i[block_pass forwarded_restarg forwarded_args hash].freeze # @!method single_argument_dig?(node) def_node_matcher :single_argument_dig?, <<~PATTERN @@ -44,7 +45,7 @@ def on_send(node) expression = single_argument_dig?(node) return unless expression - return if expression.forwarded_args_type? + return if IGNORED_ARGUMENT_TYPES.include?(expression.type) receiver = node.receiver.source argument = expression.source diff --git a/spec/rubocop/cop/style/single_argument_dig_spec.rb b/spec/rubocop/cop/style/single_argument_dig_spec.rb index 78b500e7c77b..c104bd196c0c 100644 --- a/spec/rubocop/cop/style/single_argument_dig_spec.rb +++ b/spec/rubocop/cop/style/single_argument_dig_spec.rb @@ -44,6 +44,40 @@ def foo(...) end end + context '>= Ruby 3.1', :ruby31 do + context 'when using dig with anonymous block argument forwarding' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + def foo(&) + { key: 'value' }.dig(&) + end + RUBY + end + end + end + + context '>= Ruby 3.2', :ruby32 do + context 'when using dig with anonymous rest argument forwarding' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + def foo(*) + { key: 'value' }.dig(*) + end + RUBY + end + end + + context 'when using dig with anonymous keyword argument forwarding' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + def foo(**) + { key: 'value' }.dig(**) + end + RUBY + end + end + end + describe 'dig over a variable as caller' do context 'with single argument' do it 'registers an offense and corrects unsuitable use of dig' do From 2a1687aaec48bb2d70d21306ad773282069235d2 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 17 Oct 2023 10:57:13 +0900 Subject: [PATCH 0048/1411] [Fix #12286] Fix false positives for `Style/RedundantDoubleSplatHashBraces` Fixes #12286. This PR fix false positives for `Style/RedundantDoubleSplatHashBraces` when using double splat with a hash literal enclosed in parenthesized ternary operator. --- ...positive_for_style_redundant_double_splat_hash_braces.md | 1 + lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb | 5 +++-- .../cop/style/redundant_double_splat_hash_braces_spec.rb | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md diff --git a/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md new file mode 100644 index 000000000000..b45b1f16f118 --- /dev/null +++ b/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md @@ -0,0 +1 @@ +* [#12286](https://github.com/rubocop/rubocop/issues/12286): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when using double splat with a hash literal enclosed in parenthesized ternary operator. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index 6a66f5107198..9dbbb73c446a 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -25,10 +25,11 @@ class RedundantDoubleSplatHashBraces < Base MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.' MERGE_METHODS = %i[merge merge!].freeze - # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def on_hash(node) return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?) return unless (parent = node.parent) + return unless parent.call_type? || parent.kwsplat_type? return if parent.call_type? && !merge_method?(parent) return unless (kwsplat = node.each_ancestor(:kwsplat).first) return if allowed_double_splat_receiver?(kwsplat) @@ -37,7 +38,7 @@ def on_hash(node) autocorrect(corrector, node, kwsplat) end end - # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity private diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index fbaac2eec16f..540950d49ce4 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -224,4 +224,10 @@ do_something(**x.do_something { {foo: {bar: _1}} }) RUBY end + + it 'does not register an offense when using double splat with a hash literal enclosed in parenthesized ternary operator' do + expect_no_offenses(<<~RUBY) + do_something(**(foo ? {bar: bar} : baz)) + RUBY + end end From 9eeb2f411c51567a052ad57229118be259b1ef63 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 18 Oct 2023 11:13:54 +0900 Subject: [PATCH 0049/1411] [Fix #12291] Fix a false positive for `Metrics/ClassLength` Fixes #12291. This PR fixes a false positive for `Metrics/ClassLength` when a class with a singleton class definition. --- ..._a_false_positive_for_metrics_class_length.md | 1 + lib/rubocop/cop/metrics/class_length.rb | 7 ++++++- spec/rubocop/cop/metrics/class_length_spec.rb | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_a_false_positive_for_metrics_class_length.md diff --git a/changelog/fix_a_false_positive_for_metrics_class_length.md b/changelog/fix_a_false_positive_for_metrics_class_length.md new file mode 100644 index 000000000000..6fdb5c524c15 --- /dev/null +++ b/changelog/fix_a_false_positive_for_metrics_class_length.md @@ -0,0 +1 @@ +* [#12291](https://github.com/rubocop/rubocop/issues/12291): Fix a false positive for `Metrics/ClassLength` when a class with a singleton class definition. ([@koic][]) diff --git a/lib/rubocop/cop/metrics/class_length.rb b/lib/rubocop/cop/metrics/class_length.rb index d6b937579819..f58f55616f16 100644 --- a/lib/rubocop/cop/metrics/class_length.rb +++ b/lib/rubocop/cop/metrics/class_length.rb @@ -42,7 +42,12 @@ class ClassLength < Base def on_class(node) check_code_length(node) end - alias on_sclass on_class + + def on_sclass(node) + return if node.each_ancestor(:class).any? + + on_class(node) + end def on_casgn(node) parent = node.parent diff --git a/spec/rubocop/cop/metrics/class_length_spec.rb b/spec/rubocop/cop/metrics/class_length_spec.rb index 0d8ee46a59f6..3c019aac79c4 100644 --- a/spec/rubocop/cop/metrics/class_length_spec.rb +++ b/spec/rubocop/cop/metrics/class_length_spec.rb @@ -17,6 +17,22 @@ class Test RUBY end + it 'registers an offense when a class with a singleton class definition has more than 5 lines' do + expect_offense(<<~RUBY) + class Test + ^^^^^^^^^^ Class has too many lines. [8/5] + class << self + a = 1 + a = 2 + a = 3 + a = 4 + a = 5 + a = 6 + end + end + RUBY + end + it 'reports the correct beginning and end lines' do offenses = expect_offense(<<~RUBY) class Test From 33deae5af943ae955ce10b32d594b7fcb34ec148 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 18 Oct 2023 20:51:21 +0900 Subject: [PATCH 0050/1411] [Fix #12293] Fix a false positive for `Style/RedundantDoubleSplatHashBraces` Fixes #12293. This PR fixes a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` and method chain. --- ...style_redundant_double_splat_hash_braces.md | 1 + .../redundant_double_splat_hash_braces.rb | 18 +++++++++++------- .../redundant_double_splat_hash_braces_spec.rb | 6 ++++++ 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 changelog/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md diff --git a/changelog/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md b/changelog/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md new file mode 100644 index 000000000000..40cdea66ba48 --- /dev/null +++ b/changelog/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md @@ -0,0 +1 @@ +* [#12293](https://github.com/rubocop/rubocop/issues/12293): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` and method chain. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index 9dbbb73c446a..de7a30d44bfe 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -25,12 +25,12 @@ class RedundantDoubleSplatHashBraces < Base MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.' MERGE_METHODS = %i[merge merge!].freeze - # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def on_hash(node) return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?) return unless (parent = node.parent) return unless parent.call_type? || parent.kwsplat_type? - return if parent.call_type? && !merge_method?(parent) + return unless mergeable?(parent) return unless (kwsplat = node.each_ancestor(:kwsplat).first) return if allowed_double_splat_receiver?(kwsplat) @@ -38,7 +38,7 @@ def on_hash(node) autocorrect(corrector, node, kwsplat) end end - # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity private @@ -74,7 +74,7 @@ def root_receiver(node) def select_merge_method_nodes(kwsplat) extract_send_methods(kwsplat).select do |node| - merge_method?(node) + mergeable?(node) end end @@ -109,7 +109,7 @@ def extract_send_methods(kwsplat) end def convert_to_new_arguments(node) - return unless merge_method?(node) + return unless mergeable?(node) node.arguments.map do |arg| if arg.hash_type? @@ -120,8 +120,12 @@ def convert_to_new_arguments(node) end end - def merge_method?(node) - MERGE_METHODS.include?(node.method_name) + def mergeable?(node) + return true unless node.call_type? + return false unless MERGE_METHODS.include?(node.method_name) + return true unless (parent = node.parent) + + mergeable?(parent) end end end diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index 540950d49ce4..d6aab94a3924 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -189,6 +189,12 @@ RUBY end + it 'does not register an offense when using double splat hash braces with `merge` and method chain' do + expect_no_offenses(<<~RUBY) + do_something(**{foo: bar, baz: qux}.merge(options).compact_blank) + RUBY + end + it 'does not register an offense when using hash braces arguments' do expect_no_offenses(<<~RUBY) do_something({foo: bar, baz: qux}) From 9409b720881098a5c6a6f7b5fe8d260aa55f8b74 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 20 Oct 2023 12:31:58 +0900 Subject: [PATCH 0051/1411] [Fix #12298] Fix a false positive for `Style/RedundantParentheses` Fixes #12298. This PR fixes a false positive for `Style/RedundantParentheses` when using a parenthesized hash literal as the first argument in a method call without parentheses. --- ...ositive_for_style_redundant_parentheses.md | 1 + .../cop/style/redundant_parentheses.rb | 26 ++++++++++++------- .../cop/style/redundant_parentheses_spec.rb | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 changelog/fix_a_false_positive_for_style_redundant_parentheses.md diff --git a/changelog/fix_a_false_positive_for_style_redundant_parentheses.md b/changelog/fix_a_false_positive_for_style_redundant_parentheses.md new file mode 100644 index 000000000000..46f44672041a --- /dev/null +++ b/changelog/fix_a_false_positive_for_style_redundant_parentheses.md @@ -0,0 +1 @@ +* [#12298](https://github.com/rubocop/rubocop/issues/12298): Fix a false positive for `Style/RedundantParentheses` when using a parenthesized hash literal as the first argument in a method call without parentheses. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_parentheses.rb b/lib/rubocop/cop/style/redundant_parentheses.rb index abee3585f8e5..114c0e0ab1ff 100644 --- a/lib/rubocop/cop/style/redundant_parentheses.rb +++ b/lib/rubocop/cop/style/redundant_parentheses.rb @@ -111,17 +111,19 @@ def empty_parentheses?(node) def first_arg_begins_with_hash_literal?(node) # Don't flag `method ({key: value})` or `method ({key: value}.method)` - method_chain_begins_with_hash_literal?(node.children.first) && - first_argument?(node) && - !parentheses?(node.parent) + hash_literal = method_chain_begins_with_hash_literal(node.children.first) + if (root_method = node.each_ancestor(:send).to_a.last) + parenthesized = root_method.parenthesized_call? + end + hash_literal && first_argument?(node) && !parentheses?(hash_literal) && !parenthesized end - def method_chain_begins_with_hash_literal?(node) - return false if node.nil? - return true if node.hash_type? - return false unless node.send_type? + def method_chain_begins_with_hash_literal(node) + return if node.nil? + return node if node.hash_type? + return unless node.send_type? - method_chain_begins_with_hash_literal?(node.children.first) + method_chain_begins_with_hash_literal(node.children.first) end def check(begin_node) @@ -231,7 +233,13 @@ def only_begin_arg?(args) end def first_argument?(node) - first_send_argument?(node) || first_super_argument?(node) || first_yield_argument?(node) + if first_send_argument?(node) || + first_super_argument?(node) || + first_yield_argument?(node) + return true + end + + node.each_ancestor.any? { |ancestor| first_argument?(ancestor) } end # @!method first_send_argument?(node) diff --git a/spec/rubocop/cop/style/redundant_parentheses_spec.rb b/spec/rubocop/cop/style/redundant_parentheses_spec.rb index 613d8089f879..cdcdba8333f6 100644 --- a/spec/rubocop/cop/style/redundant_parentheses_spec.rb +++ b/spec/rubocop/cop/style/redundant_parentheses_spec.rb @@ -548,6 +548,7 @@ def x context 'when the first argument in a method call begins with a hash literal' do it 'accepts parentheses if the argument list is not parenthesized' do expect_no_offenses('x ({ y: 1 }), z') + expect_no_offenses('x ({ y: 1 }).merge({ y: 2 }), z') expect_no_offenses('x ({ y: 1 }.merge({ y: 2 })), z') expect_no_offenses('x ({ y: 1 }.merge({ y: 2 }).merge({ y: 3 })), z') end From a17909d43a04fca98f7a153814e4bbe9413632d9 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 21 Oct 2023 22:06:45 +0900 Subject: [PATCH 0052/1411] [Fix #12301] Make `Style/RedundantFilterChain` aware of safe navigation Fixes #12301. This PR makes `Style/RedundantFilterChain` aware of safe navigation. --- ...t_filter_chain_aware_of_safe_navigation.md | 1 + .../cop/style/redundant_filter_chain.rb | 7 +-- .../cop/style/redundant_filter_chain_spec.rb | 46 +++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md diff --git a/changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md b/changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md new file mode 100644 index 000000000000..a8594b0d452f --- /dev/null +++ b/changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md @@ -0,0 +1 @@ +* [#12301](https://github.com/rubocop/rubocop/issues/12301): Make `Style/RedundantFilterChain` aware of safe navigation operator. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_filter_chain.rb b/lib/rubocop/cop/style/redundant_filter_chain.rb index 41c3943e513b..b21f47ec3b3c 100644 --- a/lib/rubocop/cop/style/redundant_filter_chain.rb +++ b/lib/rubocop/cop/style/redundant_filter_chain.rb @@ -60,10 +60,10 @@ class RedundantFilterChain < Base # @!method select_predicate?(node) def_node_matcher :select_predicate?, <<~PATTERN - (send + (call { - (block $(send _ {:select :filter :find_all}) ...) - $(send _ {:select :filter :find_all} block_pass_type?) + (block $(call _ {:select :filter :find_all}) ...) + $(call _ {:select :filter :find_all} block_pass_type?) } ${:#{RESTRICT_ON_SEND.join(' :')}}) PATTERN @@ -87,6 +87,7 @@ def on_send(node) register_offense(select_node, node) end end + alias on_csend on_send private diff --git a/spec/rubocop/cop/style/redundant_filter_chain_spec.rb b/spec/rubocop/cop/style/redundant_filter_chain_spec.rb index 546530f00c8f..f556659ed38b 100644 --- a/spec/rubocop/cop/style/redundant_filter_chain_spec.rb +++ b/spec/rubocop/cop/style/redundant_filter_chain_spec.rb @@ -75,6 +75,52 @@ arr.#{method}(&:odd?).any? { |x| x > 10 } RUBY end + + context 'when using safe navigation operator' do + it "registers an offense when using `##{method}` followed by `#any?`" do + expect_offense(<<~RUBY, method: method) + arr&.%{method} { |x| x > 1 }&.any? + ^{method}^^^^^^^^^^^^^^^^^^^^ Use `any?` instead of `#{method}.any?`. + RUBY + + expect_correction(<<~RUBY) + arr&.any? { |x| x > 1 } + RUBY + end + + it "registers an offense when using `##{method}` followed by `#empty?`" do + expect_offense(<<~RUBY, method: method) + arr&.%{method} { |x| x > 1 }&.empty? + ^{method}^^^^^^^^^^^^^^^^^^^^^^ Use `none?` instead of `#{method}.empty?`. + RUBY + + expect_correction(<<~RUBY) + arr&.none? { |x| x > 1 } + RUBY + end + + it "registers an offense when using `##{method}` followed by `#none?`" do + expect_offense(<<~RUBY, method: method) + arr&.%{method} { |x| x > 1 }&.none? + ^{method}^^^^^^^^^^^^^^^^^^^^^ Use `none?` instead of `#{method}.none?`. + RUBY + + expect_correction(<<~RUBY) + arr&.none? { |x| x > 1 } + RUBY + end + + it "registers an offense when using `##{method}` with block-pass followed by `#none?`" do + expect_offense(<<~RUBY, method: method) + arr&.%{method}(&:odd?)&.none? + ^{method}^^^^^^^^^^^^^^^ Use `none?` instead of `#{method}.none?`. + RUBY + + expect_correction(<<~RUBY) + arr&.none?(&:odd?) + RUBY + end + end end it 'does not register an offense when using `#any?`' do From 1725bdc49d166da1fc2b6838b7c22782cc48c3ab Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Mon, 23 Oct 2023 19:21:32 +0900 Subject: [PATCH 0053/1411] [Fix 12300] Fix an error for `Style/IdenticalConditionalBranches` Fixes #12300. This PR fixes an error for `Style/IdenticalConditionalBranches` when `if`...`else` with identical leading lines and using index assign. In RuboCop, the `send` node is used instead of the `indexasgn` node, so `name` cannot be used. https://github.com/rubocop/rubocop-ast/blob/v1.29.0/lib/rubocop/ast/node/indexasgn_node.rb --- ...or_style_identical_conditional_branches.md | 1 + .../style/identical_conditional_branches.rb | 10 ++++- .../identical_conditional_branches_spec.rb | 39 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_error_for_style_identical_conditional_branches.md diff --git a/changelog/fix_error_for_style_identical_conditional_branches.md b/changelog/fix_error_for_style_identical_conditional_branches.md new file mode 100644 index 000000000000..a8a9975f1d22 --- /dev/null +++ b/changelog/fix_error_for_style_identical_conditional_branches.md @@ -0,0 +1 @@ +* [#12300](https://github.com/rubocop/rubocop/issues/12300): Fix an error for `Style/IdenticalConditionalBranches` when `if`...`else` with identical leading lines and using index assign. ([@koic][]) diff --git a/lib/rubocop/cop/style/identical_conditional_branches.rb b/lib/rubocop/cop/style/identical_conditional_branches.rb index d852af4b37b9..a92b286fcdbf 100644 --- a/lib/rubocop/cop/style/identical_conditional_branches.rb +++ b/lib/rubocop/cop/style/identical_conditional_branches.rb @@ -153,7 +153,15 @@ def check_branches(node, branches) return unless duplicated_expressions?(node, heads) condition_variable = assignable_condition_value(node) - return if heads.first.assignment? && condition_variable == heads.first.name.to_s + + head = heads.first + if head.assignment? + # The `send` node is used instead of the `indexasgn` node, so `name` cannot be used. + # https://github.com/rubocop/rubocop-ast/blob/v1.29.0/lib/rubocop/ast/node/indexasgn_node.rb + assigned_value = head.send_type? ? head.receiver.source : head.name.to_s + + return if condition_variable == assigned_value + end check_expressions(node, heads, :before_condition) end diff --git a/spec/rubocop/cop/style/identical_conditional_branches_spec.rb b/spec/rubocop/cop/style/identical_conditional_branches_spec.rb index 915807c25546..ef2e0fb670e9 100644 --- a/spec/rubocop/cop/style/identical_conditional_branches_spec.rb +++ b/spec/rubocop/cop/style/identical_conditional_branches_spec.rb @@ -72,6 +72,45 @@ end end + context 'on if...else with identical leading lines and using index assign' do + it 'registers and corrects an offense' do + expect_offense(<<~RUBY) + if condition + h[:key] = foo + ^^^^^^^^^^^^^ Move `h[:key] = foo` out of the conditional. + bar + else + h[:key] = foo + ^^^^^^^^^^^^^ Move `h[:key] = foo` out of the conditional. + baz + end + RUBY + + expect_correction(<<~RUBY) + h[:key] = foo + if condition + bar + else + baz + end + RUBY + end + end + + context 'on if...else with identical leading lines and index assign to condition value' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + if h[:key] + h[:key] = foo + bar + else + h[:key] = foo + baz + end + RUBY + end + end + context 'on if..else with identical leading lines and assign to condition value of method call receiver' do it "doesn't register an offense" do expect_no_offenses(<<~RUBY) From 21cad5190a5d74751aae03590ba7458e0c1c11d2 Mon Sep 17 00:00:00 2001 From: Jonas Arvidsson Date: Sat, 21 Oct 2023 17:07:03 +0200 Subject: [PATCH 0054/1411] [Fix #11652] Generate inherit_from correctly also with ERB The problem with the existing algorithm, for generating the inherit_from line in --auto-gen-config runs, was that we started by removing the inherit_from (if present) and then inserted it later. The things we must deal with in the algorithm are * there could be a pre-existing inherit_from in .rubocop.yml, or not * there could be a YAML doc start ---, or not * there could be inheritance from one or multiple files A more robust approach to the removing, generating, and re-inserting is to assume that any pre-existing inherit_from directive is already in the right place. By replacing it with a placeholder and later replacing the placeholder with the new inheritance directive, we will get it right without much effort. --- changelog/fix_auto_gen_config_with_erb.md | 1 + .../cli/command/auto_generate_config.rb | 15 ++- spec/rubocop/cli/auto_gen_config_spec.rb | 111 +++++++++++------- 3 files changed, 80 insertions(+), 47 deletions(-) create mode 100644 changelog/fix_auto_gen_config_with_erb.md diff --git a/changelog/fix_auto_gen_config_with_erb.md b/changelog/fix_auto_gen_config_with_erb.md new file mode 100644 index 000000000000..38de0e04a8c4 --- /dev/null +++ b/changelog/fix_auto_gen_config_with_erb.md @@ -0,0 +1 @@ +* [#11652](https://github.com/rubocop/rubocop/issues/11652): Make `--auto-gen-config` generate `inherit_from` correctly inside ERB `if`. ([@jonas054][]) diff --git a/lib/rubocop/cli/command/auto_generate_config.rb b/lib/rubocop/cli/command/auto_generate_config.rb index 8b5954bea64a..91066ed1d1d3 100644 --- a/lib/rubocop/cli/command/auto_generate_config.rb +++ b/lib/rubocop/cli/command/auto_generate_config.rb @@ -10,6 +10,7 @@ class AutoGenerateConfig < Base AUTO_GENERATED_FILE = '.rubocop_todo.yml' YAML_OPTIONAL_DOC_START = /\A---(\s+#|\s*\z)/.freeze + PLACEHOLDER = '###rubocop:inherit_here' PHASE_1 = 'Phase 1 of 2: run Layout/LineLength cop' PHASE_2 = 'Phase 2 of 2: run all cops' @@ -125,15 +126,19 @@ def add_inheritance_from_auto_generated_file(config_file) def existing_configuration(config_file) File.read(config_file, encoding: Encoding::UTF_8) - .sub(/^inherit_from: *[^\n]+/, '') - .sub(/^inherit_from: *(\n *- *[^\n]+)+/, '') + .sub(/^inherit_from: *[^\n]+/, PLACEHOLDER) + .sub(/^inherit_from: *(\n *- *[^\n]+)+/, PLACEHOLDER) end def write_config_file(file_name, file_string, rubocop_yml_contents) lines = /\S/.match?(rubocop_yml_contents) ? rubocop_yml_contents.split("\n", -1) : [] - doc_start_index = lines.index { |line| YAML_OPTIONAL_DOC_START.match?(line) } || -1 - lines.insert(doc_start_index + 1, "inherit_from:#{file_string}\n") - File.write(file_name, lines.join("\n")) + unless rubocop_yml_contents&.include?(PLACEHOLDER) + doc_start_index = lines.index { |line| YAML_OPTIONAL_DOC_START.match?(line) } || -1 + lines.insert(doc_start_index + 1, PLACEHOLDER) + end + File.write(file_name, lines.join("\n") + .sub(/#{PLACEHOLDER}\n*/o, "inherit_from:#{file_string}\n\n") + .sub(/\n\n+\Z/, "\n")) end def relative_path_to_todo_from_options_config diff --git a/spec/rubocop/cli/auto_gen_config_spec.rb b/spec/rubocop/cli/auto_gen_config_spec.rb index e09c31b7eb6a..7d9c69dc4755 100644 --- a/spec/rubocop/cli/auto_gen_config_spec.rb +++ b/spec/rubocop/cli/auto_gen_config_spec.rb @@ -300,50 +300,77 @@ def f end end - it 'overwrites an existing todo file' do - create_file('example1.rb', ['# frozen_string_literal: true', - '', - 'x= 0 ', - '#' * 125, - 'y ', - 'puts x']) - create_file('.rubocop_todo.yml', <<~YAML) - Layout/LineLength: - Enabled: false - YAML - create_file('.rubocop.yml', ['inherit_from: .rubocop_todo.yml']) - expect(cli.run(['--auto-gen-config'])).to eq(0) - expect(File.readlines('.rubocop_todo.yml')[8..].map(&:chomp)) - .to eq(['# Offense count: 1', - '# This cop supports safe autocorrection (--autocorrect).', - '# Configuration parameters: AllowForAlignment, ' \ - 'EnforcedStyleForExponentOperator.', - '# SupportedStylesForExponentOperator: space, no_space', - 'Layout/SpaceAroundOperators:', - ' Exclude:', - " - 'example1.rb'", - '', - '# Offense count: 2', - '# This cop supports safe autocorrection (--autocorrect).', - '# Configuration parameters: AllowInHeredoc.', - 'Layout/TrailingWhitespace:', - ' Exclude:', - " - 'example1.rb'", - '', - '# Offense count: 1', - '# This cop supports safe autocorrection (--autocorrect).', - '# Configuration parameters: AllowHeredoc, ' \ - 'AllowURI, URISchemes, IgnoreCopDirectives, ' \ - 'AllowedPatterns.', - '# URISchemes: http, https', - 'Layout/LineLength:', - ' Max: 125']) + shared_examples 'overwrites todo file' do |description, code| + context "when .rubocop.yml contains #{description}" do + it 'overwrites an existing todo file' do + create_file('example1.rb', ['# frozen_string_literal: true', + '', + 'x= 0 ', + '#' * 125, + 'y ', + 'puts x']) + create_file('.rubocop_todo.yml', <<~YAML) + Layout/LineLength: + Enabled: false + YAML + create_empty_file('other.yml') + create_file('.rubocop.yml', code) + expect(cli.run(['--auto-gen-config'])).to eq(0) + expect(File.readlines('.rubocop_todo.yml')[8..].map(&:chomp)) + .to eq(['# Offense count: 1', + '# This cop supports safe autocorrection (--autocorrect).', + '# Configuration parameters: AllowForAlignment, ' \ + 'EnforcedStyleForExponentOperator.', + '# SupportedStylesForExponentOperator: space, no_space', + 'Layout/SpaceAroundOperators:', + ' Exclude:', + " - 'example1.rb'", + '', + '# Offense count: 2', + '# This cop supports safe autocorrection (--autocorrect).', + '# Configuration parameters: AllowInHeredoc.', + 'Layout/TrailingWhitespace:', + ' Exclude:', + " - 'example1.rb'", + '', + '# Offense count: 1', + '# This cop supports safe autocorrection (--autocorrect).', + '# Configuration parameters: AllowHeredoc, ' \ + 'AllowURI, URISchemes, IgnoreCopDirectives, ' \ + 'AllowedPatterns.', + '# URISchemes: http, https', + 'Layout/LineLength:', + ' Max: 125']) + expect(File.readlines('.rubocop.yml').map(&:chomp)).to eq(code) + + # Create new CLI instance to avoid using cached configuration. + new_cli = RuboCop::CLI.new + + expect(new_cli.run(['example1.rb'])).to eq(0) + end + end + end - # Create new CLI instance to avoid using cached configuration. - new_cli = RuboCop::CLI.new + include_examples 'overwrites todo file', + 'only the inherit_from line', + ['inherit_from: .rubocop_todo.yml'] - expect(new_cli.run(['example1.rb'])).to eq(0) - end + # Makes the shared example work the same with the conditional as without. + ENV['HZPKCEAXTFQLOWB'] = 'true' + + include_examples 'overwrites todo file', + 'a single line inherit_from in an ERB conditional', + ['<% if ENV["HZPKCEAXTFQLOWB"] %>', + 'inherit_from: .rubocop_todo.yml', + '<% end %>'] + + include_examples 'overwrites todo file', + 'a multiline inherit_from in an ERB conditional', + ['<% if ENV["HZPKCEAXTFQLOWB"] %>', + 'inherit_from:', + ' - .rubocop_todo.yml', + ' - other.yml', + '<% end %>'] it 'honors rubocop:disable comments' do create_file('example1.rb', ['#' * 121, From 7bedbf497b390fe6527e8a75f248b62cf2485341 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 24 Oct 2023 13:49:00 +0900 Subject: [PATCH 0055/1411] [Fix #12274] Fix a false positive for `Lint/Void` Fixes #12274. This PR fixes a false positive for `Lint/Void` when `each`'s receiver is an object of `Enumerator` to which `filter` has been applied. `each` blocks are allowed to prevent false positives. The expression inside the following block is not void: ```ruby enumerator = [1, 2, 3].filter enumerator.each { |item| item >= 2 } #=> [2, 3] ``` This might introduce false negatives, but higher severity Lint cop should aim for as safe detections as possible, I think. --- .../fix_a_false_positive_for_lint_void.md | 1 + lib/rubocop/cop/lint/void.rb | 20 ++++++++++++++++--- spec/rubocop/cop/lint/void_spec.rb | 10 ++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_a_false_positive_for_lint_void.md diff --git a/changelog/fix_a_false_positive_for_lint_void.md b/changelog/fix_a_false_positive_for_lint_void.md new file mode 100644 index 000000000000..fa8877189365 --- /dev/null +++ b/changelog/fix_a_false_positive_for_lint_void.md @@ -0,0 +1 @@ +* [#12274](https://github.com/rubocop/rubocop/issues/12274): Fix a false positive for `Lint/Void` when `each`'s receiver is an object of `Enumerator` to which `filter` has been applied. ([@koic][]) diff --git a/lib/rubocop/cop/lint/void.rb b/lib/rubocop/cop/lint/void.rb index 60b2838b7808..2048559ca927 100644 --- a/lib/rubocop/cop/lint/void.rb +++ b/lib/rubocop/cop/lint/void.rb @@ -6,6 +6,16 @@ module Lint # Checks for operators, variables, literals, lambda, proc and nonmutating # methods used in void context. # + # `each` blocks are allowed to prevent false positives. + # For example, the expression inside the `each` block below. + # It's not void, especially when the receiver is an `Enumerator`: + # + # [source,ruby] + # ---- + # enumerator = [1, 2, 3].filter + # enumerator.each { |item| item >= 2 } #=> [2, 3] + # ---- + # # @example CheckForMethodsWithNoSideEffects: false (default) # # bad # def some_method @@ -72,6 +82,7 @@ def on_block(node) return unless node.body && !node.body.begin_type? return unless in_void_context?(node.body) + check_void_op(node.body) { node.method?(:each) } check_expression(node.body) end @@ -87,11 +98,13 @@ def on_begin(node) def check_begin(node) expressions = *node expressions.pop unless in_void_context?(node) - expressions.each { |expr| check_expression(expr) } + expressions.each do |expr| + check_void_op(expr) + check_expression(expr) + end end def check_expression(expr) - check_void_op(expr) check_literal(expr) check_var(expr) check_self(expr) @@ -101,8 +114,9 @@ def check_expression(expr) check_nonmutating(expr) end - def check_void_op(node) + def check_void_op(node, &block) return unless node.send_type? && OPERATORS.include?(node.method_name) + return if block && yield(node) add_offense(node.loc.selector, message: format(OP_MSG, op: node.method_name)) do |corrector| diff --git a/spec/rubocop/cop/lint/void_spec.rb b/spec/rubocop/cop/lint/void_spec.rb index 2ed71e7c01d5..b85678dd5a67 100644 --- a/spec/rubocop/cop/lint/void_spec.rb +++ b/spec/rubocop/cop/lint/void_spec.rb @@ -451,6 +451,16 @@ def foo=(rhs) RUBY end + it 'does not register `#each` block with conditional expression' do + expect_no_offenses(<<~RUBY) + enumerator_as_filter.each do |item| + # The `filter` method is used to filter for matches with `42`. + # In this case, it's not void. + item == 42 + end + RUBY + end + context 'Ruby 2.7', :ruby27 do it 'registers two offenses for void literals in `#tap` method' do expect_offense(<<~RUBY) From 34e77c6f25be91cca0d20f1bebfe32ba163ff24d Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 25 Oct 2023 01:22:50 +0900 Subject: [PATCH 0056/1411] Tweak offense message for `Lint/Void` This commit tweaks offense message for `Lint/Void` when registering offenses of void constants. --- lib/rubocop/cop/lint/void.rb | 20 ++++++++++++-------- spec/rubocop/cop/lint/void_spec.rb | 30 +++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/lib/rubocop/cop/lint/void.rb b/lib/rubocop/cop/lint/void.rb index 2048559ca927..d584b98e6cc4 100644 --- a/lib/rubocop/cop/lint/void.rb +++ b/lib/rubocop/cop/lint/void.rb @@ -57,6 +57,7 @@ class Void < Base OP_MSG = 'Operator `%s` used in void context.' VAR_MSG = 'Variable `%s` used in void context.' + CONST_MSG = 'Constant `%s` used in void context.' LIT_MSG = 'Literal `%s` used in void context.' SELF_MSG = '`self` used in void context.' EXPRESSION_MSG = '`%s` used in void context.' @@ -127,15 +128,18 @@ def check_void_op(node, &block) def check_var(node) return unless node.variable? || node.const_type? - if node.const_type? && node.special_keyword? - add_offense(node, message: format(VAR_MSG, var: node.source)) do |corrector| - autocorrect_void_expression(corrector, node) - end + if node.const_type? + template = node.special_keyword? ? VAR_MSG : CONST_MSG + + offense_range = node + message = format(template, var: node.source) else - add_offense(node.loc.name, - message: format(VAR_MSG, var: node.loc.name.source)) do |corrector| - autocorrect_void_expression(corrector, node) - end + offense_range = node.loc.name + message = format(VAR_MSG, var: node.loc.name.source) + end + + add_offense(offense_range, message: message) do |corrector| + autocorrect_void_expression(corrector, node) end end diff --git a/spec/rubocop/cop/lint/void_spec.rb b/spec/rubocop/cop/lint/void_spec.rb index b85678dd5a67..8917d6695fc6 100644 --- a/spec/rubocop/cop/lint/void_spec.rb +++ b/spec/rubocop/cop/lint/void_spec.rb @@ -85,7 +85,7 @@ end end - %w[var @var @@var VAR $var].each do |var| + %w[var @var @@var $var].each do |var| it "registers an offense for void var #{var} if not on last line" do expect_offense(<<~RUBY, var: var) %{var} = 5 @@ -101,6 +101,20 @@ end end + it 'registers an offense for void constant `CONST` if not on last line' do + expect_offense(<<~RUBY) + CONST = 5 + CONST + ^^^^^ Constant `CONST` used in void context. + top + RUBY + + expect_correction(<<~RUBY) + CONST = 5 + top + RUBY + end + %w(1 2.0 :test /test/ [1] {}).each do |lit| it "registers an offense for void lit #{lit} if not on last line" do expect_offense(<<~RUBY, lit: lit) @@ -437,6 +451,20 @@ def foo=(rhs) RUBY end + it 'registers an offenses for void constant in a `#each` method' do + expect_offense(<<~RUBY) + array.each do |_item| + CONST + ^^^^^ Constant `CONST` used in void context. + end + RUBY + + expect_correction(<<~RUBY) + array.each do |_item| + end + RUBY + end + it 'handles `#each` block with single expression' do expect_offense(<<~RUBY) array.each do |_item| From 36f62b6b4e98c64c27ab244b394ab8194036aea6 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 25 Oct 2023 12:37:40 +0900 Subject: [PATCH 0057/1411] [Fix #12307] Fix an infinite loop error for `Layout/EndAlignment` Fixes #12307. This PR fixes an infinite loop error for `Layout/EndAlignment` when `EnforcedStyleAlignWith: variable` and using a conditional statement in a method argument on the same line and `end` with method call is not aligned. --- ...nfinite_loop_error_for_layout_end_alignment.md | 1 + lib/rubocop/cop/layout/end_alignment.rb | 8 +++++++- spec/rubocop/cop/layout/end_alignment_spec.rb | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md diff --git a/changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md b/changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md new file mode 100644 index 000000000000..5d9d3f5fa1ab --- /dev/null +++ b/changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md @@ -0,0 +1 @@ +* [#12307](https://github.com/rubocop/rubocop/issues/12307): Fix an infinite loop error for `Layout/EndAlignment` when `EnforcedStyleAlignWith: variable` and using a conditional statement in a method argument on the same line and `end` with method call is not aligned. ([@koic][]) diff --git a/lib/rubocop/cop/layout/end_alignment.rb b/lib/rubocop/cop/layout/end_alignment.rb index 6e75b78593a1..7535605dbfd5 100644 --- a/lib/rubocop/cop/layout/end_alignment.rb +++ b/lib/rubocop/cop/layout/end_alignment.rb @@ -163,7 +163,13 @@ def alignment_node(node) when :keyword node when :variable - alignment_node_for_variable_style(node) + align_to = alignment_node_for_variable_style(node) + + while (parent = align_to.parent) && parent.send_type? && same_line?(align_to, parent) + align_to = parent + end + + align_to else start_line_range(node) end diff --git a/spec/rubocop/cop/layout/end_alignment_spec.rb b/spec/rubocop/cop/layout/end_alignment_spec.rb index fd03097ede83..f6ed585cfc7c 100644 --- a/spec/rubocop/cop/layout/end_alignment_spec.rb +++ b/spec/rubocop/cop/layout/end_alignment_spec.rb @@ -438,6 +438,21 @@ class << self RUBY end + it 'registers an offense when using a conditional statement in a method argument on the same line and `end` with method call is not aligned' do + expect_offense(<<~RUBY) + do_something case condition + when expr + end.method_call + ^^^ `end` at 3, 13 is not aligned with `do_something case` at 1, 0. + RUBY + + expect_correction(<<~RUBY) + do_something case condition + when expr + end.method_call + RUBY + end + it 'register an offense when using a pattern matching in a method argument and `end` is not aligned', :ruby27 do expect_offense(<<~RUBY) format( From b2b29da6406ed55fe42fe045435c29bed6635299 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 26 Oct 2023 01:59:44 +0900 Subject: [PATCH 0058/1411] [Fix #12310] Drop `base64` gem from runtime dependency Fixes #12310. This PR drops `base64` gem from runtime dependency. RuboCop only uses `Base64.encode64` from the `base64` gem. Therefore, there's no need to depend on the entire `base64` gem. The implementation of `Base64.encode64` is quite simple: https://github.com/ruby/base64/blob/v0.1.1/lib/base64.rb#L27-L40 This change is a better approach that has also been adopted by https://github.com/rack/rack/pull/2110. --- changelog/fix_drop_base64_gem_from_runtime_dependency.md | 1 + lib/rubocop/formatter/html_formatter.rb | 6 ++++-- rubocop.gemspec | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_drop_base64_gem_from_runtime_dependency.md diff --git a/changelog/fix_drop_base64_gem_from_runtime_dependency.md b/changelog/fix_drop_base64_gem_from_runtime_dependency.md new file mode 100644 index 000000000000..905b06ee680c --- /dev/null +++ b/changelog/fix_drop_base64_gem_from_runtime_dependency.md @@ -0,0 +1 @@ +* [#12310](https://github.com/rubocop/rubocop/issues/12310): Drop `base64` gem from runtime dependency. ([@koic][]) diff --git a/lib/rubocop/formatter/html_formatter.rb b/lib/rubocop/formatter/html_formatter.rb index 7c4880c9be59..77b41d6f3388 100644 --- a/lib/rubocop/formatter/html_formatter.rb +++ b/lib/rubocop/formatter/html_formatter.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require 'base64' require 'cgi' require 'erb' require 'ostruct' @@ -124,7 +123,10 @@ def escape(string) def base64_encoded_logo_image image = File.read(LOGO_IMAGE_PATH, binmode: true) - Base64.encode64(image) + + # `Base64.encode64` compatible: + # https://github.com/ruby/base64/blob/v0.1.1/lib/base64.rb#L27-L40 + [image].pack('m') end end end diff --git a/rubocop.gemspec b/rubocop.gemspec index d0c1add6994e..4590fff4d317 100644 --- a/rubocop.gemspec +++ b/rubocop.gemspec @@ -31,7 +31,6 @@ Gem::Specification.new do |s| 'rubygems_mfa_required' => 'true' } - s.add_runtime_dependency('base64', '~> 0.1.1') s.add_runtime_dependency('json', '~> 2.3') s.add_runtime_dependency('language_server-protocol', '>= 3.17.0') s.add_runtime_dependency('parallel', '~> 1.10') From d79ee4b3eefeabcef2de0894abe03bab69ab7ec5 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 26 Oct 2023 12:10:56 +0900 Subject: [PATCH 0059/1411] [Fix #12312] Fix an incorrect autocorrect for `Style/HashSyntax` Fixes #12312. This PR fixes an incorrect autocorrect for `Style/HashSyntax` when braced hash key and value are the same and it is used in `if`...`else`. --- ...incorrect_autocorrect_style_hash_syntax.md | 1 + .../cop/mixin/hash_shorthand_syntax.rb | 25 +++++++++++-------- spec/rubocop/cop/style/hash_syntax_spec.rb | 19 ++++++++++++++ 3 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md diff --git a/changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md b/changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md new file mode 100644 index 000000000000..7e101f865833 --- /dev/null +++ b/changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md @@ -0,0 +1 @@ +* [#12312](https://github.com/rubocop/rubocop/issues/12312): Fix an incorrect autocorrect for `Style/HashSyntax` when braced hash key and value are the same and it is used in `if`...`else`. ([@koic][]) diff --git a/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb b/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb index 651af331fddb..b2c888d85bc4 100644 --- a/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +++ b/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb @@ -48,18 +48,21 @@ def on_pair(node) def register_offense(node, message, replacement) # rubocop:disable Metrics/AbcSize add_offense(node.value, message: message) do |corrector| - if (def_node = def_node_that_require_parentheses(node)) - last_argument = def_node.last_argument - if last_argument.nil? || !last_argument.hash_type? - next corrector.replace(node, replacement) - end - - white_spaces = range_between(def_node.selector.end_pos, - def_node.first_argument.source_range.begin_pos) - corrector.replace(white_spaces, '(') - corrector.insert_after(last_argument, ')') if node == last_argument.pairs.last - end corrector.replace(node, replacement) + + next unless (def_node = def_node_that_require_parentheses(node)) + + last_argument = def_node.last_argument + if last_argument.nil? || !last_argument.hash_type? + next corrector.replace(node, replacement) + end + + white_spaces = range_between(def_node.selector.end_pos, + def_node.first_argument.source_range.begin_pos) + next if node.parent.braces? + + corrector.replace(white_spaces, '(') + corrector.insert_after(last_argument, ')') if node == last_argument.pairs.last end end diff --git a/spec/rubocop/cop/style/hash_syntax_spec.rb b/spec/rubocop/cop/style/hash_syntax_spec.rb index 48c32cb2caab..6c2ab359b064 100644 --- a/spec/rubocop/cop/style/hash_syntax_spec.rb +++ b/spec/rubocop/cop/style/hash_syntax_spec.rb @@ -938,6 +938,25 @@ RUBY end + it 'registers and corrects an offense when braced hash key and value are the same and it is used in `if`...`else`' do + expect_offense(<<~RUBY) + if condition + template % {value: value} + ^^^^^ Omit the hash value. + else + do_something + end + RUBY + + expect_correction(<<~RUBY) + if condition + template % {value:} + else + do_something + end + RUBY + end + it 'registers and corrects an offense when hash key and hash value are the same and it in the method body' do expect_offense(<<~RUBY) def do_something From d995cb457b1ca24ba3b2f5bb11ec72f1a63d4343 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 26 Oct 2023 12:40:50 +0300 Subject: [PATCH 0060/1411] Fix a changelog entry --- ...false_positive_for_style_redundant_double_splat_hash_braces.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog/{changelog => }/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md (100%) diff --git a/changelog/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md similarity index 100% rename from changelog/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md rename to changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md From 4ab36220f2cb0b13b45a2642024a1a33ac47efe5 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 26 Oct 2023 12:41:26 +0300 Subject: [PATCH 0061/1411] Update Changelog --- CHANGELOG.md | 18 ++++++++++++++++++ .../fix_a_false_positive_for_lint_void.md | 1 - ..._false_positive_for_metrics_class_length.md | 1 - ...style_redundant_double_splat_hash_braces.md | 1 - ...positive_for_style_redundant_parentheses.md | 1 - ...error_for_style_single_line_do_end_block.md | 1 - ..._incorrect_autocorrect_style_hash_syntax.md | 1 - ...nite_loop_error_for_layout_end_alignment.md | 1 - changelog/fix_auto_gen_config_with_erb.md | 1 - ..._drop_base64_gem_from_runtime_dependency.md | 1 - ...for_style_identical_conditional_branches.md | 1 - ...style_redundant_double_splat_hash_braces.md | 1 - ...ositives_for_lint_empty_conditional_body.md | 1 - ..._style_redundant_double_splat_hash_brace.md | 1 - ..._positives_for_style_single_argument_dig.md | 1 - ...nt_filter_chain_aware_of_safe_navigation.md | 1 - 16 files changed, 18 insertions(+), 15 deletions(-) delete mode 100644 changelog/fix_a_false_positive_for_lint_void.md delete mode 100644 changelog/fix_a_false_positive_for_metrics_class_length.md delete mode 100644 changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md delete mode 100644 changelog/fix_a_false_positive_for_style_redundant_parentheses.md delete mode 100644 changelog/fix_an_error_for_style_single_line_do_end_block.md delete mode 100644 changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md delete mode 100644 changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md delete mode 100644 changelog/fix_auto_gen_config_with_erb.md delete mode 100644 changelog/fix_drop_base64_gem_from_runtime_dependency.md delete mode 100644 changelog/fix_error_for_style_identical_conditional_branches.md delete mode 100644 changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md delete mode 100644 changelog/fix_false_positives_for_lint_empty_conditional_body.md delete mode 100644 changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md delete mode 100644 changelog/fix_false_positives_for_style_single_argument_dig.md delete mode 100644 changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd39d45116c..c9ecb2dc7549 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,24 @@ ## master (unreleased) +### Bug fixes + +* [#12274](https://github.com/rubocop/rubocop/issues/12274): Fix a false positive for `Lint/Void` when `each`'s receiver is an object of `Enumerator` to which `filter` has been applied. ([@koic][]) +* [#12291](https://github.com/rubocop/rubocop/issues/12291): Fix a false positive for `Metrics/ClassLength` when a class with a singleton class definition. ([@koic][]) +* [#12293](https://github.com/rubocop/rubocop/issues/12293): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` and method chain. ([@koic][]) +* [#12298](https://github.com/rubocop/rubocop/issues/12298): Fix a false positive for `Style/RedundantParentheses` when using a parenthesized hash literal as the first argument in a method call without parentheses. ([@koic][]) +* [#12283](https://github.com/rubocop/rubocop/pull/12283): Fix an error for `Style/SingleLineDoEndBlock` when using single line `do`...`end` with no body. ([@koic][]) +* [#12312](https://github.com/rubocop/rubocop/issues/12312): Fix an incorrect autocorrect for `Style/HashSyntax` when braced hash key and value are the same and it is used in `if`...`else`. ([@koic][]) +* [#12307](https://github.com/rubocop/rubocop/issues/12307): Fix an infinite loop error for `Layout/EndAlignment` when `EnforcedStyleAlignWith: variable` and using a conditional statement in a method argument on the same line and `end` with method call is not aligned. ([@koic][]) +* [#11652](https://github.com/rubocop/rubocop/issues/11652): Make `--auto-gen-config` generate `inherit_from` correctly inside ERB `if`. ([@jonas054][]) +* [#12310](https://github.com/rubocop/rubocop/issues/12310): Drop `base64` gem from runtime dependency. ([@koic][]) +* [#12300](https://github.com/rubocop/rubocop/issues/12300): Fix an error for `Style/IdenticalConditionalBranches` when `if`...`else` with identical leading lines and using index assign. ([@koic][]) +* [#12286](https://github.com/rubocop/rubocop/issues/12286): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when using double splat with a hash literal enclosed in parenthesized ternary operator. ([@koic][]) +* [#12279](https://github.com/rubocop/rubocop/issues/12279): Fix false positives for `Lint/EmptyConditionalBody` when missing 2nd `if` body with a comment. ([@koic][]) +* [#12275](https://github.com/rubocop/rubocop/issues/12275): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat within block argument containing a hash literal in an array literal. ([@koic][]) +* [#12284](https://github.com/rubocop/rubocop/issues/12284): Fix false positives for `Style/SingleArgumentDig` when using some anonymous argument syntax. ([@koic][]) +* [#12301](https://github.com/rubocop/rubocop/issues/12301): Make `Style/RedundantFilterChain` aware of safe navigation operator. ([@koic][]) + ## 1.57.1 (2023-10-13) ### Bug fixes diff --git a/changelog/fix_a_false_positive_for_lint_void.md b/changelog/fix_a_false_positive_for_lint_void.md deleted file mode 100644 index fa8877189365..000000000000 --- a/changelog/fix_a_false_positive_for_lint_void.md +++ /dev/null @@ -1 +0,0 @@ -* [#12274](https://github.com/rubocop/rubocop/issues/12274): Fix a false positive for `Lint/Void` when `each`'s receiver is an object of `Enumerator` to which `filter` has been applied. ([@koic][]) diff --git a/changelog/fix_a_false_positive_for_metrics_class_length.md b/changelog/fix_a_false_positive_for_metrics_class_length.md deleted file mode 100644 index 6fdb5c524c15..000000000000 --- a/changelog/fix_a_false_positive_for_metrics_class_length.md +++ /dev/null @@ -1 +0,0 @@ -* [#12291](https://github.com/rubocop/rubocop/issues/12291): Fix a false positive for `Metrics/ClassLength` when a class with a singleton class definition. ([@koic][]) diff --git a/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md deleted file mode 100644 index 40cdea66ba48..000000000000 --- a/changelog/fix_a_false_positive_for_style_redundant_double_splat_hash_braces.md +++ /dev/null @@ -1 +0,0 @@ -* [#12293](https://github.com/rubocop/rubocop/issues/12293): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` and method chain. ([@koic][]) diff --git a/changelog/fix_a_false_positive_for_style_redundant_parentheses.md b/changelog/fix_a_false_positive_for_style_redundant_parentheses.md deleted file mode 100644 index 46f44672041a..000000000000 --- a/changelog/fix_a_false_positive_for_style_redundant_parentheses.md +++ /dev/null @@ -1 +0,0 @@ -* [#12298](https://github.com/rubocop/rubocop/issues/12298): Fix a false positive for `Style/RedundantParentheses` when using a parenthesized hash literal as the first argument in a method call without parentheses. ([@koic][]) diff --git a/changelog/fix_an_error_for_style_single_line_do_end_block.md b/changelog/fix_an_error_for_style_single_line_do_end_block.md deleted file mode 100644 index 3b31e02ebbad..000000000000 --- a/changelog/fix_an_error_for_style_single_line_do_end_block.md +++ /dev/null @@ -1 +0,0 @@ -* [#12283](https://github.com/rubocop/rubocop/pull/12283): Fix an error for `Style/SingleLineDoEndBlock` when using single line `do`...`end` with no body. ([@koic][]) diff --git a/changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md b/changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md deleted file mode 100644 index 7e101f865833..000000000000 --- a/changelog/fix_an_incorrect_autocorrect_style_hash_syntax.md +++ /dev/null @@ -1 +0,0 @@ -* [#12312](https://github.com/rubocop/rubocop/issues/12312): Fix an incorrect autocorrect for `Style/HashSyntax` when braced hash key and value are the same and it is used in `if`...`else`. ([@koic][]) diff --git a/changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md b/changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md deleted file mode 100644 index 5d9d3f5fa1ab..000000000000 --- a/changelog/fix_an_infinite_loop_error_for_layout_end_alignment.md +++ /dev/null @@ -1 +0,0 @@ -* [#12307](https://github.com/rubocop/rubocop/issues/12307): Fix an infinite loop error for `Layout/EndAlignment` when `EnforcedStyleAlignWith: variable` and using a conditional statement in a method argument on the same line and `end` with method call is not aligned. ([@koic][]) diff --git a/changelog/fix_auto_gen_config_with_erb.md b/changelog/fix_auto_gen_config_with_erb.md deleted file mode 100644 index 38de0e04a8c4..000000000000 --- a/changelog/fix_auto_gen_config_with_erb.md +++ /dev/null @@ -1 +0,0 @@ -* [#11652](https://github.com/rubocop/rubocop/issues/11652): Make `--auto-gen-config` generate `inherit_from` correctly inside ERB `if`. ([@jonas054][]) diff --git a/changelog/fix_drop_base64_gem_from_runtime_dependency.md b/changelog/fix_drop_base64_gem_from_runtime_dependency.md deleted file mode 100644 index 905b06ee680c..000000000000 --- a/changelog/fix_drop_base64_gem_from_runtime_dependency.md +++ /dev/null @@ -1 +0,0 @@ -* [#12310](https://github.com/rubocop/rubocop/issues/12310): Drop `base64` gem from runtime dependency. ([@koic][]) diff --git a/changelog/fix_error_for_style_identical_conditional_branches.md b/changelog/fix_error_for_style_identical_conditional_branches.md deleted file mode 100644 index a8a9975f1d22..000000000000 --- a/changelog/fix_error_for_style_identical_conditional_branches.md +++ /dev/null @@ -1 +0,0 @@ -* [#12300](https://github.com/rubocop/rubocop/issues/12300): Fix an error for `Style/IdenticalConditionalBranches` when `if`...`else` with identical leading lines and using index assign. ([@koic][]) diff --git a/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md deleted file mode 100644 index b45b1f16f118..000000000000 --- a/changelog/fix_false_positive_for_style_redundant_double_splat_hash_braces.md +++ /dev/null @@ -1 +0,0 @@ -* [#12286](https://github.com/rubocop/rubocop/issues/12286): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when using double splat with a hash literal enclosed in parenthesized ternary operator. ([@koic][]) diff --git a/changelog/fix_false_positives_for_lint_empty_conditional_body.md b/changelog/fix_false_positives_for_lint_empty_conditional_body.md deleted file mode 100644 index ac478160f0c2..000000000000 --- a/changelog/fix_false_positives_for_lint_empty_conditional_body.md +++ /dev/null @@ -1 +0,0 @@ -* [#12279](https://github.com/rubocop/rubocop/issues/12279): Fix false positives for `Lint/EmptyConditionalBody` when missing 2nd `if` body with a comment. ([@koic][]) diff --git a/changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md b/changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md deleted file mode 100644 index 71fa909b5bf9..000000000000 --- a/changelog/fix_false_positives_for_style_redundant_double_splat_hash_brace.md +++ /dev/null @@ -1 +0,0 @@ -* [#12275](https://github.com/rubocop/rubocop/issues/12275): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat within block argument containing a hash literal in an array literal. ([@koic][]) diff --git a/changelog/fix_false_positives_for_style_single_argument_dig.md b/changelog/fix_false_positives_for_style_single_argument_dig.md deleted file mode 100644 index a330483eb136..000000000000 --- a/changelog/fix_false_positives_for_style_single_argument_dig.md +++ /dev/null @@ -1 +0,0 @@ -* [#12284](https://github.com/rubocop/rubocop/issues/12284): Fix false positives for `Style/SingleArgumentDig` when using some anonymous argument syntax. ([@koic][]) diff --git a/changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md b/changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md deleted file mode 100644 index a8594b0d452f..000000000000 --- a/changelog/fix_make_style_redundant_filter_chain_aware_of_safe_navigation.md +++ /dev/null @@ -1 +0,0 @@ -* [#12301](https://github.com/rubocop/rubocop/issues/12301): Make `Style/RedundantFilterChain` aware of safe navigation operator. ([@koic][]) From 47735efc2b410578a196fd2758da87d01802c655 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 26 Oct 2023 12:44:23 +0300 Subject: [PATCH 0062/1411] Cut 1.57.2 --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- CHANGELOG.md | 2 ++ CONTRIBUTING.md | 2 +- docs/antora.yml | 2 +- docs/modules/ROOT/pages/cops_lint.adoc | 10 ++++++++++ lib/rubocop/version.rb | 2 +- relnotes/v1.57.2.md | 20 ++++++++++++++++++++ 7 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 relnotes/v1.57.2.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 0ef7cc151be4..ab52fee56867 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -38,7 +38,7 @@ output by `rubocop -V`, include them as well. Here's an example: ``` $ [bundle exec] rubocop -V -1.57.1 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] +1.57.2 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] - rubocop-performance 1.18.0 - rubocop-rspec 2.23.2 ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index c9ecb2dc7549..cf746ca4e98a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ ## master (unreleased) +## 1.57.2 (2023-10-26) + ### Bug fixes * [#12274](https://github.com/rubocop/rubocop/issues/12274): Fix a false positive for `Lint/Void` when `each`'s receiver is an object of `Enumerator` to which `filter` has been applied. ([@koic][]) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09396ae24888..3db1afa76d8b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,7 @@ do so. ```console $ rubocop -V -1.57.1 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] +1.57.2 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux] - rubocop-performance 1.18.0 - rubocop-rspec 2.23.2 ``` diff --git a/docs/antora.yml b/docs/antora.yml index 9c897ea03d1d..ec7a70bdfe4f 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop title: RuboCop # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: ~ +version: '1.57' nav: - modules/ROOT/nav.adoc diff --git a/docs/modules/ROOT/pages/cops_lint.adoc b/docs/modules/ROOT/pages/cops_lint.adoc index cb79a7dbbf47..0299cd556b5d 100644 --- a/docs/modules/ROOT/pages/cops_lint.adoc +++ b/docs/modules/ROOT/pages/cops_lint.adoc @@ -7454,6 +7454,16 @@ do_something(1) Checks for operators, variables, literals, lambda, proc and nonmutating methods used in void context. +`each` blocks are allowed to prevent false positives. +For example, the expression inside the `each` block below. +It's not void, especially when the receiver is an `Enumerator`: + +[source,ruby] +---- +enumerator = [1, 2, 3].filter +enumerator.each { |item| item >= 2 } #=> [2, 3] +---- + === Examples ==== CheckForMethodsWithNoSideEffects: false (default) diff --git a/lib/rubocop/version.rb b/lib/rubocop/version.rb index 341e6e11f03d..003a46dd5b9f 100644 --- a/lib/rubocop/version.rb +++ b/lib/rubocop/version.rb @@ -3,7 +3,7 @@ module RuboCop # This module holds the RuboCop version information. module Version - STRING = '1.57.1' + STRING = '1.57.2' MSG = '%s (using Parser %s, ' \ 'rubocop-ast %s, ' \ diff --git a/relnotes/v1.57.2.md b/relnotes/v1.57.2.md new file mode 100644 index 000000000000..ad529cb49527 --- /dev/null +++ b/relnotes/v1.57.2.md @@ -0,0 +1,20 @@ +### Bug fixes + +* [#12274](https://github.com/rubocop/rubocop/issues/12274): Fix a false positive for `Lint/Void` when `each`'s receiver is an object of `Enumerator` to which `filter` has been applied. ([@koic][]) +* [#12291](https://github.com/rubocop/rubocop/issues/12291): Fix a false positive for `Metrics/ClassLength` when a class with a singleton class definition. ([@koic][]) +* [#12293](https://github.com/rubocop/rubocop/issues/12293): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat hash braces with `merge` and method chain. ([@koic][]) +* [#12298](https://github.com/rubocop/rubocop/issues/12298): Fix a false positive for `Style/RedundantParentheses` when using a parenthesized hash literal as the first argument in a method call without parentheses. ([@koic][]) +* [#12283](https://github.com/rubocop/rubocop/pull/12283): Fix an error for `Style/SingleLineDoEndBlock` when using single line `do`...`end` with no body. ([@koic][]) +* [#12312](https://github.com/rubocop/rubocop/issues/12312): Fix an incorrect autocorrect for `Style/HashSyntax` when braced hash key and value are the same and it is used in `if`...`else`. ([@koic][]) +* [#12307](https://github.com/rubocop/rubocop/issues/12307): Fix an infinite loop error for `Layout/EndAlignment` when `EnforcedStyleAlignWith: variable` and using a conditional statement in a method argument on the same line and `end` with method call is not aligned. ([@koic][]) +* [#11652](https://github.com/rubocop/rubocop/issues/11652): Make `--auto-gen-config` generate `inherit_from` correctly inside ERB `if`. ([@jonas054][]) +* [#12310](https://github.com/rubocop/rubocop/issues/12310): Drop `base64` gem from runtime dependency. ([@koic][]) +* [#12300](https://github.com/rubocop/rubocop/issues/12300): Fix an error for `Style/IdenticalConditionalBranches` when `if`...`else` with identical leading lines and using index assign. ([@koic][]) +* [#12286](https://github.com/rubocop/rubocop/issues/12286): Fix false positives for `Style/RedundantDoubleSplatHashBraces` when using double splat with a hash literal enclosed in parenthesized ternary operator. ([@koic][]) +* [#12279](https://github.com/rubocop/rubocop/issues/12279): Fix false positives for `Lint/EmptyConditionalBody` when missing 2nd `if` body with a comment. ([@koic][]) +* [#12275](https://github.com/rubocop/rubocop/issues/12275): Fix a false positive for `Style/RedundantDoubleSplatHashBraces` when using double splat within block argument containing a hash literal in an array literal. ([@koic][]) +* [#12284](https://github.com/rubocop/rubocop/issues/12284): Fix false positives for `Style/SingleArgumentDig` when using some anonymous argument syntax. ([@koic][]) +* [#12301](https://github.com/rubocop/rubocop/issues/12301): Make `Style/RedundantFilterChain` aware of safe navigation operator. ([@koic][]) + +[@koic]: https://github.com/koic +[@jonas054]: https://github.com/jonas054 From 0a43c2f4dde06adf1e7b02c36bdd15cc86214e09 Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 26 Oct 2023 12:46:08 +0300 Subject: [PATCH 0063/1411] Switch back the docs version --- docs/antora.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/antora.yml b/docs/antora.yml index ec7a70bdfe4f..9c897ea03d1d 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -2,6 +2,6 @@ name: rubocop title: RuboCop # We always provide version without patch here (e.g. 1.1), # as patch versions should not appear in the docs. -version: '1.57' +version: ~ nav: - modules/ROOT/nav.adoc From fa2727e1e44322d12a0edbb9e2c419c549ffcecd Mon Sep 17 00:00:00 2001 From: Bozhidar Batsov Date: Thu, 26 Oct 2023 12:53:49 +0300 Subject: [PATCH 0064/1411] Tweak wording --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 40af39097085..f618119488f0 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ $ cd my/cool/ruby/project $ rubocop ``` -You can also use this magic in your favorite editor with RuboCop's [built-in LSP](https://docs.rubocop.org/rubocop/usage/lsp.html). +You can also use this magic in your favorite editor with RuboCop's [built-in LSP server](https://docs.rubocop.org/rubocop/usage/lsp.html). ## Documentation From a4754075c0ddc6babf0a1a05dfee540650316a80 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 27 Oct 2023 02:03:57 +0900 Subject: [PATCH 0065/1411] Suppress a Ruby warning when using Ruby 3.3.0dev Follow up #12313. `base64` is not needed at runtime, but it was required as a test dependency. So, this PR suppresses the following warning when using Ruby 3.3.0dev: ```consle $ ruby -v ruby 3.3.0dev (2023-10-23T08:04:27Z master e6fcf07a6f) [x86_64-darwin22] $ cd path/to/rubocop $ bundle exec rspec /Users/koic/.rbenv/versions/3.3.0-dev/lib/ruby/gems/3.3.0+0/gems/webmock-3.19.1/lib/webmock/util/headers.rb:3: warning: base64 which will no longer be part of the default gems since Ruby 3.4.0. Add base64 to your Gemfile or gemspec. ``` https://app.circleci.com/pipelines/github/rubocop/rubocop/10108/workflows/20097132-bbe3-4fa4-ad7e-de7c30c86e69/jobs/291956?invite=true#step-104-0_163 The `base64` dependency can be removed from Gemfile when https://github.com/bblimke/webmock/pull/1041 is merged and released. It's a workaround until then. --- Gemfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index 69f5c5b1a69e..3dd40569e092 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,9 @@ gem 'test-queue' gem 'yard', '~> 0.9' group :test do + # FIXME: This `base64` dependency can be removed when https://github.com/bblimke/webmock/pull/1041 + # is merged and released. It's a workaround until then. + gem 'base64' # FIXME: This `bigdecimal` dependency can be removed when https://github.com/jnunemaker/crack/pull/75 # is merged and released. It's a workaround until then. gem 'bigdecimal', platform: :mri From afa41965a9463dab806f124a2b48981cde39f32d Mon Sep 17 00:00:00 2001 From: Dave Powers Date: Fri, 27 Oct 2023 10:47:43 -0400 Subject: [PATCH 0066/1411] Update Helix LSP config based on v23.10 changes - retain configuration example for older versions --- docs/modules/ROOT/pages/usage/lsp.adoc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/modules/ROOT/pages/usage/lsp.adoc b/docs/modules/ROOT/pages/usage/lsp.adoc index f95ca50fab1d..9d4a74af94df 100644 --- a/docs/modules/ROOT/pages/usage/lsp.adoc +++ b/docs/modules/ROOT/pages/usage/lsp.adoc @@ -124,6 +124,23 @@ https://github.com/helix-editor/helix[Helix] is a post-modern modal text editor Add the following to your Helix language configuration file (e.g. `~/.config/helix/languages.toml`): +Helix 23.10 or later: + +```toml +[language-server.rubocop] +command = "bundle" +args = ["exec", "rubocop", "--lsp"] + +[[language]] +name = "ruby" +auto-format = true +language-servers = [ + { name = "rubocop" } +] +``` + +Before Helix 23.10 or earlier: + ```toml [[language]] name = "ruby" From 9109cc10315c35ed25189c616627a39cb1da04f5 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 28 Oct 2023 14:24:30 +0900 Subject: [PATCH 0067/1411] Use RuboCop RSpec 2.25 https://github.com/rubocop/rubocop-rspec/releases/tag/v2.25.0 --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3dd40569e092..5d66639b957b 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ gem 'rake', '~> 13.0' gem 'rspec', '~> 3.7' gem 'rubocop-performance', '~> 1.19.0' gem 'rubocop-rake', '~> 0.6.0' -gem 'rubocop-rspec', '~> 2.24.0' +gem 'rubocop-rspec', '~> 2.25.0' # Workaround for cc-test-reporter with SimpleCov 0.18. # Stop upgrading SimpleCov until the following issue will be resolved. # https://github.com/codeclimate/test-reporter/issues/418 From fe802d9a3b4dca31d1952d77205d2f3546882e93 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 29 Oct 2023 15:23:14 +0900 Subject: [PATCH 0068/1411] Fix typos --- spec/rubocop/cop/layout/end_alignment_spec.rb | 8 ++-- .../layout/first_argument_indentation_spec.rb | 2 +- ...pace_inside_array_literal_brackets_spec.rb | 2 +- .../cop/lint/duplicate_match_pattern_spec.rb | 4 +- .../cop/lint/percent_string_array_spec.rb | 2 +- .../lint/redundant_require_statement_spec.rb | 4 +- ...nal_assignment_assign_to_condition_spec.rb | 2 +- .../cop/style/documentation_method_spec.rb | 2 +- .../method_call_with_args_parentheses_spec.rb | 42 +++++++++---------- .../style/multiline_ternary_operator_spec.rb | 10 ++--- 10 files changed, 39 insertions(+), 39 deletions(-) diff --git a/spec/rubocop/cop/layout/end_alignment_spec.rb b/spec/rubocop/cop/layout/end_alignment_spec.rb index f6ed585cfc7c..fc75f5f7e57f 100644 --- a/spec/rubocop/cop/layout/end_alignment_spec.rb +++ b/spec/rubocop/cop/layout/end_alignment_spec.rb @@ -375,7 +375,7 @@ class << self include_examples 'aligned', 'puts 1; until', 'Test', ' end' include_examples 'aligned', 'puts 1; case', 'a when b', ' end' - it 'register an offense when using `+` operator method and `end` is not aligned' do + it 'registers an offense when using `+` operator method and `end` is not aligned' do expect_offense(<<~RUBY) variable + if condition foo @@ -394,7 +394,7 @@ class << self RUBY end - it 'register an offense when using `-` operator method and `end` is not aligned' do + it 'registers an offense when using `-` operator method and `end` is not aligned' do expect_offense(<<~RUBY) variable - if condition foo @@ -413,7 +413,7 @@ class << self RUBY end - it 'register an offense when using a conditional statement in a method argument and `end` is not aligned' do + it 'registers an offense when using a conditional statement in a method argument and `end` is not aligned' do expect_offense(<<~RUBY) format( case condition @@ -453,7 +453,7 @@ class << self RUBY end - it 'register an offense when using a pattern matching in a method argument and `end` is not aligned', :ruby27 do + it 'registers an offense when using a pattern matching in a method argument and `end` is not aligned', :ruby27 do expect_offense(<<~RUBY) format( case pattern diff --git a/spec/rubocop/cop/layout/first_argument_indentation_spec.rb b/spec/rubocop/cop/layout/first_argument_indentation_spec.rb index ae20b9d18067..6500889af07a 100644 --- a/spec/rubocop/cop/layout/first_argument_indentation_spec.rb +++ b/spec/rubocop/cop/layout/first_argument_indentation_spec.rb @@ -545,7 +545,7 @@ end context 'for assignment' do - it 'register an offense and corrects a correctly indented first ' \ + it 'registers an offense and corrects a correctly indented first ' \ 'argument and does not care about the second argument' do expect_offense(<<~RUBY) x = run( diff --git a/spec/rubocop/cop/layout/space_inside_array_literal_brackets_spec.rb b/spec/rubocop/cop/layout/space_inside_array_literal_brackets_spec.rb index 8b8d0b4f35f4..1a37b663d60d 100644 --- a/spec/rubocop/cop/layout/space_inside_array_literal_brackets_spec.rb +++ b/spec/rubocop/cop/layout/space_inside_array_literal_brackets_spec.rb @@ -436,7 +436,7 @@ def Vector.[](*array) RUBY end - it 'register an offense and corrects when 2 arrays are on one line' do + it 'registers an offense and corrects when 2 arrays are on one line' do expect_offense(<<~RUBY) [ 2, 3, 4 ] - [3, 4 ] ^ #{use_space_message} diff --git a/spec/rubocop/cop/lint/duplicate_match_pattern_spec.rb b/spec/rubocop/cop/lint/duplicate_match_pattern_spec.rb index 0272262fa509..e5f27769734c 100644 --- a/spec/rubocop/cop/lint/duplicate_match_pattern_spec.rb +++ b/spec/rubocop/cop/lint/duplicate_match_pattern_spec.rb @@ -169,7 +169,7 @@ RUBY end - it 'register an offense for repeated `in` patterns and the same `if` guard is used' do + it 'registers an offense for repeated `in` patterns and the same `if` guard is used' do expect_offense(<<~RUBY) case x in foo if condition @@ -181,7 +181,7 @@ RUBY end - it 'register an offense for repeated `in` patterns and the same `unless` guard is used' do + it 'registers an offense for repeated `in` patterns and the same `unless` guard is used' do expect_offense(<<~RUBY) case x in foo unless condition diff --git a/spec/rubocop/cop/lint/percent_string_array_spec.rb b/spec/rubocop/cop/lint/percent_string_array_spec.rb index 0a6fd8a4dea7..754320c34424 100644 --- a/spec/rubocop/cop/lint/percent_string_array_spec.rb +++ b/spec/rubocop/cop/lint/percent_string_array_spec.rb @@ -65,7 +65,7 @@ end context 'with invalid byte sequence in UTF-8' do - it 'add an offense and corrects when tokens contain quotes' do + it 'adds an offense and corrects when tokens contain quotes' do expect_offense(<<~RUBY) %W("a\\255\\255") ^^^^^^^^^^^^^^^ Within `%w`/`%W`, quotes and ',' are unnecessary and may be unwanted in the resulting strings. diff --git a/spec/rubocop/cop/lint/redundant_require_statement_spec.rb b/spec/rubocop/cop/lint/redundant_require_statement_spec.rb index bfa463a11350..98884dc67ca2 100644 --- a/spec/rubocop/cop/lint/redundant_require_statement_spec.rb +++ b/spec/rubocop/cop/lint/redundant_require_statement_spec.rb @@ -52,7 +52,7 @@ end context 'target ruby version >= 2.1', :ruby21 do - it 'register an offense and corrects when using requiring `thread` or already redundant features' do + it 'registers an offense and corrects when using requiring `thread` or already redundant features' do expect_offense(<<~RUBY) require 'enumerator' ^^^^^^^^^^^^^^^^^^^^ Remove unnecessary `require` statement. @@ -107,7 +107,7 @@ end context 'target ruby version >= 2.5', :ruby25 do - it 'register an offense and corrects when using requiring `pp` or already redundant features' do + it 'registers an offense and corrects when using requiring `pp` or already redundant features' do expect_offense(<<~RUBY) require 'enumerator' ^^^^^^^^^^^^^^^^^^^^ Remove unnecessary `require` statement. diff --git a/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb b/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb index db1899aba9fe..5e2e24d28bbe 100644 --- a/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb +++ b/spec/rubocop/cop/style/conditional_assignment_assign_to_condition_spec.rb @@ -1572,7 +1572,7 @@ RUBY end - it 'register an offense for multiple assignment in if else' do + it 'registers an offense for multiple assignment in if else' do expect_offense(<<~RUBY) if baz ^^^^^^ Use the return of the conditional for variable assignment and comparison. diff --git a/spec/rubocop/cop/style/documentation_method_spec.rb b/spec/rubocop/cop/style/documentation_method_spec.rb index 5bbc0dad51ad..aae1e1a7112c 100644 --- a/spec/rubocop/cop/style/documentation_method_spec.rb +++ b/spec/rubocop/cop/style/documentation_method_spec.rb @@ -139,7 +139,7 @@ def foo; end RUBY end - it 'register an offense with inline `private_class_method`' do + it 'registers an offense with inline `private_class_method`' do expect_offense(<<~RUBY) private_class_method def self.foo ^^^^^^^^^^^^ Missing method documentation comment. diff --git a/spec/rubocop/cop/style/method_call_with_args_parentheses_spec.rb b/spec/rubocop/cop/style/method_call_with_args_parentheses_spec.rb index c3df1f69e013..40893346ed68 100644 --- a/spec/rubocop/cop/style/method_call_with_args_parentheses_spec.rb +++ b/spec/rubocop/cop/style/method_call_with_args_parentheses_spec.rb @@ -88,7 +88,7 @@ def self.x() = foo(y) RUBY end - it 'register an offense for method call without parens' do + it 'registers an offense for method call without parens' do expect_offense(<<~RUBY) top.test a, b ^^^^^^^^^^^^^ Use parentheses for method calls with arguments. @@ -100,7 +100,7 @@ def self.x() = foo(y) end context 'when using safe navigation operator' do - it 'register an offense for method call without parens' do + it 'registers an offense for method call without parens' do expect_offense(<<~RUBY) top&.test a, b ^^^^^^^^^^^^^^ Use parentheses for method calls with arguments. @@ -112,7 +112,7 @@ def self.x() = foo(y) end end - it 'register an offense for non-receiver method call without parens' do + it 'registers an offense for non-receiver method call without parens' do expect_offense(<<~RUBY) def foo test a, b @@ -127,7 +127,7 @@ def foo RUBY end - it 'register an offense for methods starting with capital without parens' do + it 'registers an offense for methods starting with capital without parens' do expect_offense(<<~RUBY) def foo Test a, b @@ -142,7 +142,7 @@ def foo RUBY end - it 'register an offense for superclass call without parens' do + it 'registers an offense for superclass call without parens' do expect_offense(<<~RUBY) def foo super a @@ -169,7 +169,7 @@ def foo expect_no_offenses('super(a)') end - it 'register an offense for yield without parens' do + it 'registers an offense for yield without parens' do expect_offense(<<~RUBY) def foo yield a @@ -498,7 +498,7 @@ def foo(**) end end - it 'register an offense for parens in method call without args' do + it 'registers an offense for parens in method call without args' do trailing_whitespace = ' ' expect_offense(<<~RUBY) @@ -511,7 +511,7 @@ def foo(**) RUBY end - it 'register an offense for multi-line method calls' do + it 'registers an offense for multi-line method calls' do expect_offense(<<~RUBY) test( ^ Omit parentheses for method calls with arguments. @@ -526,7 +526,7 @@ def foo(**) RUBY end - it 'register an offense for superclass call with parens' do + it 'registers an offense for superclass call with parens' do expect_offense(<<~RUBY) def foo super(a) @@ -541,7 +541,7 @@ def foo RUBY end - it 'register an offense for yield call with parens' do + it 'registers an offense for yield call with parens' do expect_offense(<<~RUBY) def foo yield(a) @@ -556,7 +556,7 @@ def foo RUBY end - it 'register an offense for parens in the last chain' do + it 'registers an offense for parens in the last chain' do expect_offense(<<~RUBY) foo().bar(3).wait(4) ^^^ Omit parentheses for method calls with arguments. @@ -567,7 +567,7 @@ def foo RUBY end - it 'register an offense for parens in do-end blocks' do + it 'registers an offense for parens in do-end blocks' do expect_offense(<<~RUBY) foo(:arg) do ^^^^^^ Omit parentheses for method calls with arguments. @@ -582,7 +582,7 @@ def foo RUBY end - it 'register an offense for hashes in keyword values' do + it 'registers an offense for hashes in keyword values' do expect_offense(<<~RUBY) method_call(hash: {foo: :bar}) ^^^^^^^^^^^^^^^^^^^ Omit parentheses for method calls with arguments. @@ -593,7 +593,7 @@ def foo RUBY end - it 'register an offense for %r regex literal as arguments' do + it 'registers an offense for %r regex literal as arguments' do expect_offense(<<~RUBY) method_call(%r{foo}) ^^^^^^^^^ Omit parentheses for method calls with arguments. @@ -604,7 +604,7 @@ def foo RUBY end - it 'register an offense for parens in string interpolation' do + it 'registers an offense for parens in string interpolation' do expect_offense(<<~'RUBY') "#{t('no.parens')}" ^^^^^^^^^^^^^ Omit parentheses for method calls with arguments. @@ -615,7 +615,7 @@ def foo RUBY end - it 'register an offense in complex conditionals' do + it 'registers an offense in complex conditionals' do expect_offense(<<~RUBY) def foo if cond.present? && verify?(:something) @@ -644,7 +644,7 @@ def foo RUBY end - it 'register an offense in assignments' do + it 'registers an offense in assignments' do expect_offense(<<~RUBY) foo = A::B.new(c) ^^^ Omit parentheses for method calls with arguments. @@ -671,7 +671,7 @@ def foo RUBY end - it 'register an offense for camel-case methods with arguments' do + it 'registers an offense for camel-case methods with arguments' do expect_offense(<<~RUBY) Array(:arg) ^^^^^^ Omit parentheses for method calls with arguments. @@ -682,7 +682,7 @@ def foo RUBY end - it 'register an offense in multi-line inheritance' do + it 'registers an offense in multi-line inheritance' do expect_offense(<<~RUBY) class Point < Struct.new(:x, :y) ^^^^^^^^ Omit parentheses for method calls with arguments. @@ -695,7 +695,7 @@ class Point < Struct.new :x, :y RUBY end - it 'register an offense in calls inside braced blocks' do + it 'registers an offense in calls inside braced blocks' do expect_offense(<<~RUBY) client.images(page: page) { |resource| Image.new(resource) } ^^^^^^^^^^ Omit parentheses for method calls with arguments. @@ -706,7 +706,7 @@ class Point < Struct.new :x, :y RUBY end - it 'register an offense in calls inside braced numblocks', :ruby27 do + it 'registers an offense in calls inside braced numblocks', :ruby27 do expect_offense(<<~RUBY) client.images(page: page) { Image.new(_1) } ^^^^ Omit parentheses for method calls with arguments. diff --git a/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb b/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb index 638979557e33..1fc189ee1b05 100644 --- a/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +++ b/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb @@ -124,7 +124,7 @@ RUBY end - it 'register an offense and corrects when returning a multiline ternary operator expression with `return`' do + it 'registers an offense and corrects when returning a multiline ternary operator expression with `return`' do expect_offense(<<~RUBY) return cond ? ^^^^^^ Avoid multi-line ternary operators, use single-line instead. @@ -137,7 +137,7 @@ RUBY end - it 'register an offense and corrects when returning a multiline ternary operator expression with `break`' do + it 'registers an offense and corrects when returning a multiline ternary operator expression with `break`' do expect_offense(<<~RUBY) break cond ? ^^^^^^ Avoid multi-line ternary operators, use single-line instead. @@ -150,7 +150,7 @@ RUBY end - it 'register an offense and corrects when returning a multiline ternary operator expression with `next`' do + it 'registers an offense and corrects when returning a multiline ternary operator expression with `next`' do expect_offense(<<~RUBY) next cond ? ^^^^^^ Avoid multi-line ternary operators, use single-line instead. @@ -163,7 +163,7 @@ RUBY end - it 'register an offense and corrects when returning a multiline ternary operator expression with method call' do + it 'registers an offense and corrects when returning a multiline ternary operator expression with method call' do expect_offense(<<~RUBY) do_something cond ? ^^^^^^ Avoid multi-line ternary operators, use single-line instead. @@ -176,7 +176,7 @@ RUBY end - it 'register an offense and corrects when returning a multiline ternary operator expression with safe navigation method call' do + it 'registers an offense and corrects when returning a multiline ternary operator expression with safe navigation method call' do expect_offense(<<~RUBY) obj&.do_something cond ? ^^^^^^ Avoid multi-line ternary operators, use single-line instead. From afab18cdf7903af585d412ce7de43281b734ef31 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 28 Oct 2023 13:19:06 +0900 Subject: [PATCH 0069/1411] Add a project spec Follow up https://github.com/rubocop/rubocop/commit/d995cb4 This PR adds a project spec to prevent an unexpected changelog entry file path. For instance, if an unexpected file named `changelog/changelog/fix_foo.md` exists, it will fail as follows: ```console $ bundle exec rspec spec/project_spec.rb:309 (snip) 1) RuboCop Project Changelog future entries will not have a directory Failure/Error: expect(Dir[dir].all? { |path| File.file?(path) }).to be(true) expected true got false # ./spec/project_spec.rb:309:in `block (4 levels) in ' Finished in 0.02034 seconds (files took 1.71 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/project_spec.rb:308 # RuboCop Project Changelog future entries will not have a directory ``` --- spec/project_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/project_spec.rb b/spec/project_spec.rb index 9869a9bc3160..928da7248f8e 100644 --- a/spec/project_spec.rb +++ b/spec/project_spec.rb @@ -305,6 +305,10 @@ def expected dir = File.expand_path('../changelog', __dir__) + it 'will not have a directory' do + expect(Dir["#{dir}/*"].none? { |path| File.directory?(path) }).to be(true) + end + Dir["#{dir}/*.md"].each do |path| context "For #{path}" do let(:path) { path } From 930755cd46ebf3861ee0472a0cfb874413f4328d Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 31 Oct 2023 16:12:51 +0900 Subject: [PATCH 0070/1411] Fix an error for `Style/RedundantDoubleSplatHashBraces` Fixes https://github.com/rubocop/rubocop/issues/12275#issuecomment-1786554892. This PR fixes an error for `Style/RedundantDoubleSplatHashBraces` when method call for parenthesized no hash double double splat. --- ...an_error_for_style_redundant_double_splat_hash_braces.md | 1 + lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb | 6 +++--- .../cop/style/redundant_double_splat_hash_braces_spec.rb | 6 ++++++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_an_error_for_style_redundant_double_splat_hash_braces.md diff --git a/changelog/fix_an_error_for_style_redundant_double_splat_hash_braces.md b/changelog/fix_an_error_for_style_redundant_double_splat_hash_braces.md new file mode 100644 index 000000000000..12cfb0020bf5 --- /dev/null +++ b/changelog/fix_an_error_for_style_redundant_double_splat_hash_braces.md @@ -0,0 +1 @@ +* [#12326](https://github.com/rubocop/rubocop/pull/12326): Fix an error for `Style/RedundantDoubleSplatHashBraces` when method call for parenthesized no hash double double splat. ([@koic][]) diff --git a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb index de7a30d44bfe..005aa6e8c425 100644 --- a/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +++ b/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb @@ -25,20 +25,20 @@ class RedundantDoubleSplatHashBraces < Base MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.' MERGE_METHODS = %i[merge merge!].freeze - # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity def on_hash(node) return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?) return unless (parent = node.parent) return unless parent.call_type? || parent.kwsplat_type? return unless mergeable?(parent) return unless (kwsplat = node.each_ancestor(:kwsplat).first) - return if allowed_double_splat_receiver?(kwsplat) + return if !node.braces? || allowed_double_splat_receiver?(kwsplat) add_offense(kwsplat) do |corrector| autocorrect(corrector, node, kwsplat) end end - # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity private diff --git a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb index d6aab94a3924..44391a29ee43 100644 --- a/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb +++ b/spec/rubocop/cop/style/redundant_double_splat_hash_braces_spec.rb @@ -165,6 +165,12 @@ RUBY end + it 'does not register an offense when method call for parenthesized no hash double double splat' do + expect_no_offenses(<<~RUBY) + do_something(**(options.merge(foo: bar))) + RUBY + end + it 'does not register an offense when using empty double splat hash braces arguments' do expect_no_offenses(<<~RUBY) do_something(**{}) From 4b468726bfd789d86935e8fe80115f81c25cec5c Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 31 Oct 2023 00:03:01 +0900 Subject: [PATCH 0071/1411] [Fix #12324] Fix an error for `Layout/RescueEnsureAlignment` Fixes #12324. This PR fixes an error for `Layout/RescueEnsureAlignment` when using `rescue` in `do`...`end` block assigned to object attribute. --- ..._error_for_layout_rescue_ensure_alignment.md | 1 + .../cop/layout/rescue_ensure_alignment.rb | 4 ++-- .../cop/layout/rescue_ensure_alignment_spec.rb | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 changelog/fix_error_for_layout_rescue_ensure_alignment.md diff --git a/changelog/fix_error_for_layout_rescue_ensure_alignment.md b/changelog/fix_error_for_layout_rescue_ensure_alignment.md new file mode 100644 index 000000000000..9ab58a9f5898 --- /dev/null +++ b/changelog/fix_error_for_layout_rescue_ensure_alignment.md @@ -0,0 +1 @@ +* [#12324](https://github.com/rubocop/rubocop/issues/12324): Fix an error for `Layout/RescueEnsureAlignment` when using `rescue` in `do`...`end` block assigned to object attribute. ([@koic][]) diff --git a/lib/rubocop/cop/layout/rescue_ensure_alignment.rb b/lib/rubocop/cop/layout/rescue_ensure_alignment.rb index 3b8a741c7e54..36f6558be7d1 100644 --- a/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +++ b/lib/rubocop/cop/layout/rescue_ensure_alignment.rb @@ -104,8 +104,8 @@ def alignment_source(node, starting_loc) mlhs_node, = *node mlhs_node.source_range else - # It is a wrapper with access modifier. - node.child_nodes.first.loc.name + # It is a wrapper with receiver of object attribute or access modifier. + node.receiver&.source_range || node.child_nodes.first.loc.name end range_between(starting_loc.begin_pos, ending_loc.end_pos).source diff --git a/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb b/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb index 223c66299cd1..e6f55e53c8c8 100644 --- a/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb +++ b/spec/rubocop/cop/layout/rescue_ensure_alignment_spec.rb @@ -688,6 +688,23 @@ def foo end end + context 'rescue in do-end block assigned to object attribute' do + it 'registers an offense' do + expect_offense(<<~RUBY) + obj.attr = do_something do + rescue StandardError + ^^^^^^ `rescue` at 2, 2 is not aligned with `obj` at 1, 0. + end + RUBY + + expect_correction(<<~RUBY) + obj.attr = do_something do + rescue StandardError + end + RUBY + end + end + context 'rescue in do-end block on multi-assignment' do it 'registers an offense' do expect_offense(<<~RUBY) From 558a7399e5d1bf5b05d4a04c45337b75ac4bb045 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Wed, 1 Nov 2023 13:29:31 +0900 Subject: [PATCH 0072/1411] [Fix #12322] Fix an error for `Style/CombinableLoops` Fixes #12322. This PR fixes an error for `Style/CombinableLoops` when looping over the same data for the third consecutive time or more. --- .../fix_error_for_style_combinable_loops.md | 1 + lib/rubocop/cop/style/combinable_loops.rb | 9 ++------- spec/rubocop/cop/style/combinable_loops_spec.rb | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 changelog/fix_error_for_style_combinable_loops.md diff --git a/changelog/fix_error_for_style_combinable_loops.md b/changelog/fix_error_for_style_combinable_loops.md new file mode 100644 index 000000000000..4dbf5bf304aa --- /dev/null +++ b/changelog/fix_error_for_style_combinable_loops.md @@ -0,0 +1 @@ +* [#12322](https://github.com/rubocop/rubocop/issues/12322): Fix an error for `Style/CombinableLoops` when looping over the same data for the third consecutive time or more. ([@koic][]) diff --git a/lib/rubocop/cop/style/combinable_loops.rb b/lib/rubocop/cop/style/combinable_loops.rb index 73a5923bb6d7..d8e34bb06f78 100644 --- a/lib/rubocop/cop/style/combinable_loops.rb +++ b/lib/rubocop/cop/style/combinable_loops.rb @@ -59,8 +59,6 @@ module Style class CombinableLoops < Base extend AutoCorrector - include RangeHelp - MSG = 'Combine this loop with the previous loop.' def on_block(node) @@ -105,11 +103,8 @@ def same_collection_looping_for?(node, sibling) end def combine_with_left_sibling(corrector, node) - corrector.replace( - node.left_sibling.body, - "#{node.left_sibling.body.source}\n#{node.body.source}" - ) - corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left)) + corrector.remove(node.left_sibling.body.source_range.end.join(node.left_sibling.loc.end)) + corrector.remove(node.source_range.begin.join(node.body.source_range.begin)) end end end diff --git a/spec/rubocop/cop/style/combinable_loops_spec.rb b/spec/rubocop/cop/style/combinable_loops_spec.rb index 0a7f9cfe3164..4a7127aa4fb9 100644 --- a/spec/rubocop/cop/style/combinable_loops_spec.rb +++ b/spec/rubocop/cop/style/combinable_loops_spec.rb @@ -29,6 +29,22 @@ RUBY end + it 'registers an offense when looping over the same data for the third consecutive time' do + expect_offense(<<~RUBY) + items.each { |item| foo(item) } + items.each { |item| bar(item) } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Combine this loop with the previous loop. + items.each { |item| baz(item) } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Combine this loop with the previous loop. + RUBY + + expect_correction(<<~RUBY) + items.each { |item| foo(item) + bar(item) + baz(item) } + RUBY + end + context 'Ruby 2.7' do it 'registers an offense when looping over the same data as previous loop in numblocks' do expect_offense(<<~RUBY) From b1fe8001101aeb117b147374e78422a22b319c90 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 4 Nov 2023 00:20:16 +0900 Subject: [PATCH 0073/1411] Make `InternalAffairs/MethodNameEqual` aware of `!=` This PR makes `InternalAffairs/MethodNameEqual` aware of `node.method_name != method_name` and suppresses the following new offenses: ```console $ bundle exec rubocop -a (snip) Offenses: lib/rubocop/cop/lint/duplicate_methods.rb:256:13: C: [Corrected] InternalAffairs/MethodNameEqual: Use !ancestor.method?(:class_eval) instead. ancestor.method_name != :class_eval && !ancestor.class_constructor? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lib/rubocop/cop/style/auto_resource_cleanup.rb:28:13: C: [Corrected] Style/NegatedIf: Favor unless over if for negative conditions. next if !node.method?(target_method) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lib/rubocop/cop/style/auto_resource_cleanup.rb:28:21: C: [Corrected] InternalAffairs/MethodNameEqual: Use !node.method?(target_method) instead. next if node.method_name != target_method ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lib/rubocop/cop/style/conditional_assignment.rb:537:32: C: [Corrected] InternalAffairs/MethodNameEqual: Use !node.method?(:[]=) instead. node.send_type? && node.method_name != :[]= ^^^^^^^^^^^^^^^^^^^^^^^^ 1517 files inspected, 4 offenses detected, 4 offenses corrected ``` --- .../cop/internal_affairs/method_name_equal.rb | 39 +++++++++---------- lib/rubocop/cop/lint/duplicate_methods.rb | 2 +- .../cop/style/auto_resource_cleanup.rb | 2 +- .../cop/style/conditional_assignment.rb | 2 +- .../method_name_equal_spec.rb | 15 ++++++- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/lib/rubocop/cop/internal_affairs/method_name_equal.rb b/lib/rubocop/cop/internal_affairs/method_name_equal.rb index da6388d8d6c2..ea3f56ec74c6 100644 --- a/lib/rubocop/cop/internal_affairs/method_name_equal.rb +++ b/lib/rubocop/cop/internal_affairs/method_name_equal.rb @@ -12,38 +12,37 @@ module InternalAffairs # # good # node.method?(:do_something) # + # # bad + # node.method_name != :do_something + # + # # good + # !node.method?(:do_something) + # class MethodNameEqual < Base - include RangeHelp extend AutoCorrector - MSG = 'Use `method?(%s)` instead of `method_name == %s`.' - RESTRICT_ON_SEND = %i[==].freeze + MSG = 'Use `%s` instead.' + RESTRICT_ON_SEND = %i[== !=].freeze - # @!method method_name?(node) - def_node_matcher :method_name?, <<~PATTERN + # @!method method_name(node) + def_node_matcher :method_name, <<~PATTERN (send - $(send - (...) :method_name) :== - $...) + (send + (...) :method_name) {:== :!=} + $_) PATTERN def on_send(node) - method_name?(node) do |method_name_node, method_name_arg| - message = format(MSG, method_name: method_name_arg.first.source) + method_name(node) do |method_name_arg| + bang = node.method?(:!=) ? '!' : '' + prefer = "#{bang}#{node.receiver.receiver.source}.method?(#{method_name_arg.source})" + message = format(MSG, prefer: prefer) - range = range(method_name_node, node) - - add_offense(range, message: message) do |corrector| - corrector.replace(range, "method?(#{method_name_arg.first.source})") + add_offense(node, message: message) do |corrector| + corrector.replace(node, prefer) end end end - - private - - def range(method_name_node, node) - range_between(method_name_node.loc.selector.begin_pos, node.source_range.end_pos) - end end end end diff --git a/lib/rubocop/cop/lint/duplicate_methods.rb b/lib/rubocop/cop/lint/duplicate_methods.rb index 12c4dd6003a5..ffd584188ce9 100644 --- a/lib/rubocop/cop/lint/duplicate_methods.rb +++ b/lib/rubocop/cop/lint/duplicate_methods.rb @@ -253,7 +253,7 @@ def possible_dsl?(node) # Assume that if a method definition is inside any block call which # we can't identify, it could be a DSL node.each_ancestor(:block).any? do |ancestor| - ancestor.method_name != :class_eval && !ancestor.class_constructor? + !ancestor.method?(:class_eval) && !ancestor.class_constructor? end end diff --git a/lib/rubocop/cop/style/auto_resource_cleanup.rb b/lib/rubocop/cop/style/auto_resource_cleanup.rb index 71a8a55ee989..f6e364c70cf5 100644 --- a/lib/rubocop/cop/style/auto_resource_cleanup.rb +++ b/lib/rubocop/cop/style/auto_resource_cleanup.rb @@ -25,7 +25,7 @@ class AutoResourceCleanup < Base def on_send(node) TARGET_METHODS.each do |target_class, target_method| - next if node.method_name != target_method + next unless node.method?(target_method) target_receiver = s(:const, nil, target_class) next if node.receiver != target_receiver diff --git a/lib/rubocop/cop/style/conditional_assignment.rb b/lib/rubocop/cop/style/conditional_assignment.rb index 1f33cbe1055a..dda47d00b8b8 100644 --- a/lib/rubocop/cop/style/conditional_assignment.rb +++ b/lib/rubocop/cop/style/conditional_assignment.rb @@ -534,7 +534,7 @@ def ternary(node) end def element_assignment?(node) - node.send_type? && node.method_name != :[]= + node.send_type? && !node.method?(:[]=) end def extract_branches(node) diff --git a/spec/rubocop/cop/internal_affairs/method_name_equal_spec.rb b/spec/rubocop/cop/internal_affairs/method_name_equal_spec.rb index 2084a7d4ac60..38d16a75b269 100644 --- a/spec/rubocop/cop/internal_affairs/method_name_equal_spec.rb +++ b/spec/rubocop/cop/internal_affairs/method_name_equal_spec.rb @@ -4,7 +4,7 @@ it 'registers an offense when using `#method == :do_something`' do expect_offense(<<~RUBY) node.method_name == :do_something - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `method?(:do_something)` instead of `method_name == :do_something`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `node.method?(:do_something)` instead. RUBY expect_correction(<<~RUBY) @@ -12,10 +12,21 @@ RUBY end + it 'registers an offense when using `#method != :do_something`' do + expect_offense(<<~RUBY) + node.method_name != :do_something + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `!node.method?(:do_something)` instead. + RUBY + + expect_correction(<<~RUBY) + !node.method?(:do_something) + RUBY + end + it 'registers an offense when using `#method == other_node.do_something`' do expect_offense(<<~RUBY) node.method_name == other_node.do_something - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `method?(other_node.do_something)` instead of `method_name == other_node.do_something`. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `node.method?(other_node.do_something)` instead. RUBY expect_correction(<<~RUBY) From 605a5e2174b540791aa33393253de4e9954004c7 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 5 Nov 2023 02:07:20 +0900 Subject: [PATCH 0074/1411] [Docs] Add missing spaces Follow up https://github.com/rubocop/ruby-style-guide/pull/928. --- .../cop/layout/first_array_element_indentation.rb | 12 ++++++------ lib/rubocop/cop/style/missing_respond_to_missing.rb | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/rubocop/cop/layout/first_array_element_indentation.rb b/lib/rubocop/cop/layout/first_array_element_indentation.rb index 9c309d2e2dc3..b9a843ab3258 100644 --- a/lib/rubocop/cop/layout/first_array_element_indentation.rb +++ b/lib/rubocop/cop/layout/first_array_element_indentation.rb @@ -25,7 +25,7 @@ module Layout # # element are on separate lines is indented one step (two spaces) more # # than the position inside the opening parenthesis. # - # #bad + # # bad # array = [ # :value # ] @@ -33,7 +33,7 @@ module Layout # :no_difference # ]) # - # #good + # # good # array = [ # :value # ] @@ -47,7 +47,7 @@ module Layout # # separate lines is indented the same as an array literal which is not # # defined inside a method call. # - # #bad + # # bad # # consistent # array = [ # :value @@ -56,7 +56,7 @@ module Layout # :its_like_this # ]) # - # #good + # # good # array = [ # :value # ] @@ -68,13 +68,13 @@ module Layout # # The `align_brackets` style enforces that the opening and closing # # brackets are indented to the same position. # - # #bad + # # bad # # align_brackets # and_now_for_something = [ # :completely_different # ] # - # #good + # # good # # align_brackets # and_now_for_something = [ # :completely_different diff --git a/lib/rubocop/cop/style/missing_respond_to_missing.rb b/lib/rubocop/cop/style/missing_respond_to_missing.rb index d803d91d5301..56aeb3d9b59f 100644 --- a/lib/rubocop/cop/style/missing_respond_to_missing.rb +++ b/lib/rubocop/cop/style/missing_respond_to_missing.rb @@ -7,12 +7,12 @@ module Style # defining `respond_to_missing?`. # # @example - # #bad + # # bad # def method_missing(name, *args) # # ... # end # - # #good + # # good # def respond_to_missing?(name, include_private) # # ... # end From 6230707636517b887589ab0995cf271e27f0a520 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 5 Nov 2023 16:31:38 +0900 Subject: [PATCH 0075/1411] Add `StyleGuide` for `Style/SingleLineDoEndBlock` Follow up https://github.com/rubocop/ruby-style-guide/pull/922. --- config/default.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/default.yml b/config/default.yml index 93eeffdbfd4a..8db543077ad1 100644 --- a/config/default.yml +++ b/config/default.yml @@ -5190,6 +5190,7 @@ Style/SingleLineBlockParams: Style/SingleLineDoEndBlock: Description: 'Checks for single-line `do`...`end` blocks.' + StyleGuide: '#single-line-do-end-block' Enabled: pending VersionAdded: '1.57' From 4d9efdc8a502eee35550f00ed220a4c07af63db8 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Fri, 3 Nov 2023 17:41:21 +0900 Subject: [PATCH 0076/1411] [Fix #12328] Make `Style/AutoResourceCleanup` aware of `Tempfile.open` Fixes #12328. This PR makes `Style/AutoResourceCleanup` aware of `Tempfile.open`. --- ...resource_cleanup_aware_of_tempfile_open.md | 1 + .../cop/style/auto_resource_cleanup.rb | 35 +++++++++++-------- .../cop/style/auto_resource_cleanup_spec.rb | 21 +++++++++++ 3 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 changelog/change_change_make_style_auto_resource_cleanup_aware_of_tempfile_open.md diff --git a/changelog/change_change_make_style_auto_resource_cleanup_aware_of_tempfile_open.md b/changelog/change_change_make_style_auto_resource_cleanup_aware_of_tempfile_open.md new file mode 100644 index 000000000000..316344796c4d --- /dev/null +++ b/changelog/change_change_make_style_auto_resource_cleanup_aware_of_tempfile_open.md @@ -0,0 +1 @@ +* [#12328](https://github.com/rubocop/rubocop/issues/12328): Make `Style/AutoResourceCleanup` aware of `Tempfile.open`. ([@koic][]) diff --git a/lib/rubocop/cop/style/auto_resource_cleanup.rb b/lib/rubocop/cop/style/auto_resource_cleanup.rb index f6e364c70cf5..a2e843a82a6f 100644 --- a/lib/rubocop/cop/style/auto_resource_cleanup.rb +++ b/lib/rubocop/cop/style/auto_resource_cleanup.rb @@ -16,31 +16,38 @@ module Style # File.open('file') do |f| # # ... # end + # + # # bad + # f = Tempfile.open('temp') + # + # # good + # Tempfile.open('temp') do |f| + # # ... + # end class AutoResourceCleanup < Base - MSG = 'Use the block version of `%s.%s`.' - - TARGET_METHODS = { File: :open }.freeze + MSG = 'Use the block version of `%s`.' + RESTRICT_ON_SEND = %i[open].freeze - RESTRICT_ON_SEND = TARGET_METHODS.values.freeze + # @!method file_open_method?(node) + def_node_matcher :file_open_method?, <<~PATTERN + (send (const {nil? cbase} {:File :Tempfile}) :open ...) + PATTERN def on_send(node) - TARGET_METHODS.each do |target_class, target_method| - next unless node.method?(target_method) + return if !file_open_method?(node) || cleanup?(node) - target_receiver = s(:const, nil, target_class) - next if node.receiver != target_receiver + current = node.receiver.source_range.begin.join(node.selector.end).source - next if cleanup?(node) - - add_offense(node, message: format(MSG, class: target_class, method: target_method)) - end + add_offense(node, message: format(MSG, current: current)) end private def cleanup?(node) - parent = node.parent - node.block_argument? || (parent && (parent.block_type? || !parent.lvasgn_type?)) + return true if node.block_argument? + return false unless (parent = node.parent) + + parent.block_type? || !parent.lvasgn_type? end end end diff --git a/spec/rubocop/cop/style/auto_resource_cleanup_spec.rb b/spec/rubocop/cop/style/auto_resource_cleanup_spec.rb index 6791498659f1..2f96f4e81b34 100644 --- a/spec/rubocop/cop/style/auto_resource_cleanup_spec.rb +++ b/spec/rubocop/cop/style/auto_resource_cleanup_spec.rb @@ -8,6 +8,27 @@ RUBY end + it 'registers an offense for Tempfile.open without block' do + expect_offense(<<~RUBY) + Tempfile.open("filename") + ^^^^^^^^^^^^^^^^^^^^^^^^^ Use the block version of `Tempfile.open`. + RUBY + end + + it 'registers an offense for ::File.open without block' do + expect_offense(<<~RUBY) + ::File.open("filename") + ^^^^^^^^^^^^^^^^^^^^^^^ Use the block version of `::File.open`. + RUBY + end + + it 'registers an offense for ::Tempfile.open without block' do + expect_offense(<<~RUBY) + ::Tempfile.open("filename") + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use the block version of `::Tempfile.open`. + RUBY + end + it 'does not register an offense for File.open with block' do expect_no_offenses('File.open("file") { |f| something }') end From 857918124a1320cbc09f6cb6db9a3126dd6ff8ca Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sun, 5 Nov 2023 23:06:10 +0900 Subject: [PATCH 0077/1411] [Fix #12361] Fix an incorrect autocorrect for `Naming/BlockForwarding` Fixes #12361. Fix an incorrect autocorrect for `Naming/BlockForwarding` and `Style/ArgumentsForwarding` when autocorrection conflicts for anonymous arguments. --- ..._autocorrect_for_naming_block_fowarding.md | 1 + lib/rubocop/cop/naming/block_forwarding.rb | 2 +- lib/rubocop/cop/style/arguments_forwarding.rb | 4 ++++ spec/rubocop/cli/autocorrect_spec.rb | 22 +++++++++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 changelog/fix_an_incorrect_autocorrect_for_naming_block_fowarding.md diff --git a/changelog/fix_an_incorrect_autocorrect_for_naming_block_fowarding.md b/changelog/fix_an_incorrect_autocorrect_for_naming_block_fowarding.md new file mode 100644 index 000000000000..24e1e5ca4535 --- /dev/null +++ b/changelog/fix_an_incorrect_autocorrect_for_naming_block_fowarding.md @@ -0,0 +1 @@ +* [#12361](https://github.com/rubocop/rubocop/issues/12361): Fix an incorrect autocorrect for `Naming/BlockForwarding` and `Style/ArgumentsForwarding` when autocorrection conflicts for anonymous arguments. ([@koic][]) diff --git a/lib/rubocop/cop/naming/block_forwarding.rb b/lib/rubocop/cop/naming/block_forwarding.rb index 809880d65f19..90052b3f018d 100644 --- a/lib/rubocop/cop/naming/block_forwarding.rb +++ b/lib/rubocop/cop/naming/block_forwarding.rb @@ -48,7 +48,7 @@ class BlockForwarding < Base MSG = 'Use %