Skip to content

Commit

Permalink
[Fix rubocop#11535] Fix a false positive for `Style/NumberedParameter…
Browse files Browse the repository at this point in the history
…sLimit`

Fixes rubocop#11535.

This PR fixes a false positive for `Style/NumberedParametersLimit`
when only `_2` or higher numbered parameter is used.
  • Loading branch information
koic committed Feb 3, 2023
1 parent 3c9c494 commit afaa604
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
@@ -0,0 +1 @@
* [#11535](https://github.com/rubocop/rubocop/issues/11535): Fix a false positive for `Style/NumberedParametersLimit` when only `_2` or higher numbered parameter is used. ([@koic][])
14 changes: 11 additions & 3 deletions lib/rubocop/cop/style/numbered_parameters_limit.rb
Expand Up @@ -12,10 +12,11 @@ module Style
#
# @example Max: 1 (default)
# # bad
# foo { _1.call(_2, _3, _4) }
# use_multiple_numbered_parameters { _1.call(_2, _3, _4) }
#
# # good
# foo { do_something(_1) }
# array.each { use_array_element_as_numbered_parameter(_1) }
# hash.each { use_only_hash_value_as_numbered_parameter(_2) }
class NumberedParametersLimit < Base
extend TargetRubyVersion
extend ExcludeLimit
Expand All @@ -26,9 +27,10 @@ class NumberedParametersLimit < Base
exclude_limit 'Max'

MSG = 'Avoid using more than %<max>i numbered %<parameter>s; %<count>i detected.'
NUMBERED_PARAMETER_PATTERN = /\A_[1-9]\z/.freeze

def on_numblock(node)
_send_node, param_count, * = *node
param_count = numbered_parameter_nodes(node).uniq.count
return if param_count <= max_count

parameter = max_count > 1 ? 'parameters' : 'parameter'
Expand All @@ -38,6 +40,12 @@ def on_numblock(node)

private

def numbered_parameter_nodes(node)
node.each_descendant(:lvar).select do |lvar_node|
lvar_node.source.match?(NUMBERED_PARAMETER_PATTERN)
end
end

def max_count
max = cop_config.fetch('Max', DEFAULT_MAX_VALUE)

Expand Down
25 changes: 25 additions & 0 deletions spec/rubocop/cop/style/numbered_parameters_limit_spec.rb
Expand Up @@ -54,6 +54,31 @@
context 'when Max is 1' do
let(:max) { 1 }

it 'does not register an offense when only numbered parameter `_1` is used once' do
expect_no_offenses(<<~RUBY)
foo { do_something(_1) }
RUBY
end

it 'does not register an offense when only numbered parameter `_1` is used twice' do
expect_no_offenses(<<~RUBY)
foo { do_something(_1, _1) }
RUBY
end

it 'does not register an offense when only numbered parameter `_9` is used once' do
expect_no_offenses(<<~RUBY)
foo { do_something(_9) }
RUBY
end

it 'does not register an offense when using numbered parameter with underscored local variable' do
expect_no_offenses(<<~RUBY)
_lvar = 42
foo { do_something(_2, _lvar) }
RUBY
end

it 'uses the right offense message' do
expect_offense(<<~RUBY)
foo { do_something(_1, _2, _3, _4, _5) }
Expand Down

0 comments on commit afaa604

Please sign in to comment.