diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dcc3edd4c5..8ecd206b9f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * [#7740](https://github.com/rubocop-hq/rubocop/issues/7740): Add `AllowModifiersOnSymbols` configuration to `Style/AccessModifierDeclarations`. ([@tejasbubane][]) * [#7812](https://github.com/rubocop-hq/rubocop/pull/7812): Add auto-correction for `Lint/BooleanSymbol` cop. ([@tejasbubane][]) * [#7823](https://github.com/rubocop-hq/rubocop/pull/7823): Add `IgnoredMethods` configuration in `Metrics/AbcSize`, `Metrics/CyclomaticComplexity`, and `Metrics/PerceivedComplexity` cops. ([@drenmi][]) +* [#7816](https://github.com/rubocop-hq/rubocop/pull/7816): Support Ruby 2.7's numbered parameter for `Style/Lambda`. ([@koic][]) ### Bug fixes diff --git a/lib/rubocop/ast/builder.rb b/lib/rubocop/ast/builder.rb index ce3a9153afa..84ef5abcbde 100644 --- a/lib/rubocop/ast/builder.rb +++ b/lib/rubocop/ast/builder.rb @@ -20,6 +20,7 @@ class Builder < Parser::Builders::Default args: ArgsNode, array: ArrayNode, block: BlockNode, + numblock: BlockNode, break: BreakNode, case_match: CaseMatchNode, case: CaseNode, diff --git a/lib/rubocop/ast/node.rb b/lib/rubocop/ast/node.rb index 7e6b6ddb3e7..64b6ddb5049 100644 --- a/lib/rubocop/ast/node.rb +++ b/lib/rubocop/ast/node.rb @@ -484,7 +484,7 @@ def guard_clause? (send (const nil? :Proc) :new)} PATTERN - def_node_matcher :lambda?, '(block (send nil? :lambda) ...)' + def_node_matcher :lambda?, '({block numblock} (send nil? :lambda) ...)' def_node_matcher :lambda_or_proc?, '{lambda? proc?}' def_node_matcher :class_constructor?, <<~PATTERN diff --git a/lib/rubocop/ast/node/block_node.rb b/lib/rubocop/ast/node/block_node.rb index e27d0b6854f..1af323acdf9 100644 --- a/lib/rubocop/ast/node/block_node.rb +++ b/lib/rubocop/ast/node/block_node.rb @@ -24,7 +24,11 @@ def send_node # # @return [Array] def arguments - node_parts[1] + if numblock_type? + [] # Numbered parameters have no block arguments. + else + node_parts[1] + end end # The body of this block. diff --git a/lib/rubocop/cop/style/lambda.rb b/lib/rubocop/cop/style/lambda.rb index 1122cab4660..c0598ddecb6 100644 --- a/lib/rubocop/cop/style/lambda.rb +++ b/lib/rubocop/cop/style/lambda.rb @@ -73,6 +73,7 @@ def on_block(node) location: node.send_node.source_range, message: message(node, selector)) end + alias on_numblock on_block def autocorrect(node) if node.send_node.source == 'lambda' diff --git a/spec/rubocop/ast/block_node_spec.rb b/spec/rubocop/ast/block_node_spec.rb index 8c0ec4449ee..3acc38e59a7 100644 --- a/spec/rubocop/ast/block_node_spec.rb +++ b/spec/rubocop/ast/block_node_spec.rb @@ -33,6 +33,14 @@ it { expect(block_node.arguments.size).to eq(2) } end + + context '>= Ruby 2.7', :ruby27 do + context 'using numbered parameters' do + let(:source) { 'foo { _1 }' } + + it { expect(block_node.arguments.empty?).to be(true) } + end + end end describe '#arguments?' do @@ -59,6 +67,14 @@ it { expect(block_node.arguments?).to be_truthy } end + + context '>= Ruby 2.7', :ruby27 do + context 'using numbered parameters' do + let(:source) { 'foo { _1 }' } + + it { expect(block_node.arguments?).to be false } + end + end end describe '#braces?' do diff --git a/spec/rubocop/cop/style/lambda_spec.rb b/spec/rubocop/cop/style/lambda_spec.rb index f7d487eb510..a734511d76e 100644 --- a/spec/rubocop/cop/style/lambda_spec.rb +++ b/spec/rubocop/cop/style/lambda_spec.rb @@ -194,6 +194,38 @@ end end + context '>= Ruby 2.7', :ruby27 do + context 'when using numbered parameter' do + context 'with a single line lambda method call' do + let(:source) { 'f = lambda { _1 }' } + + it_behaves_like 'registers an offense', + 'Use the `-> { ... }` lambda literal syntax for ' \ + 'single line lambdas.' + it_behaves_like 'auto-correct', 'f = -> { _1 }' + end + + context 'with a multiline lambda method call' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + l = lambda do + _1 + end + RUBY + end + end + + context 'with a single line lambda literal' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + lambda = -> { _1 } + lambda.(1) + RUBY + end + end + end + end + context 'with a multiline lambda literal' do context 'with arguments' do let(:source) do