-
-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #173 from fatkodima/block_given_with_explicit_block
Add new `Performance/BlockGivenWithExplicitBlock` cop
- Loading branch information
Showing
7 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
lib/rubocop/cop/performance/block_given_with_explicit_block.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Performance | ||
# This cop identifies unnecessary use of a `block_given?` where explicit check | ||
# of block argument would suffice. | ||
# | ||
# @example | ||
# # bad | ||
# def method(&block) | ||
# do_something if block_given? | ||
# end | ||
# | ||
# # good | ||
# def method(&block) | ||
# do_something if block | ||
# end | ||
# | ||
# # good - block is reassigned | ||
# def method(&block) | ||
# block ||= -> { do_something } | ||
# warn "Using default ..." unless block_given? | ||
# # ... | ||
# end | ||
# | ||
class BlockGivenWithExplicitBlock < Base | ||
extend AutoCorrector | ||
|
||
RESTRICT_ON_SEND = %i[block_given?].freeze | ||
MSG = 'Check block argument explicitly instead of using `block_given?`.' | ||
|
||
def_node_matcher :reassigns_block_arg?, '`(lvasgn %1 ...)' | ||
|
||
def on_send(node) | ||
def_node = node.each_ancestor(:def, :defs).first | ||
return unless def_node | ||
|
||
block_arg = def_node.arguments.find(&:blockarg_type?) | ||
return unless block_arg | ||
|
||
block_arg_name = block_arg.loc.name.source.to_sym | ||
return if reassigns_block_arg?(def_node, block_arg_name) | ||
|
||
add_offense(node) do |corrector| | ||
corrector.replace(node, block_arg_name) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
spec/rubocop/cop/performance/block_given_with_explicit_block_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Performance::BlockGivenWithExplicitBlock do | ||
subject(:cop) { described_class.new } | ||
|
||
it 'registers an offense and corrects when using `block_given?` in an instance method with block arg' do | ||
expect_offense(<<~RUBY) | ||
def method(x, &block) | ||
do_something if block_given? | ||
^^^^^^^^^^^^ Check block argument explicitly instead of using `block_given?`. | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
def method(x, &block) | ||
do_something if block | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense and corrects when using `block_given?` in a class method with block arg' do | ||
expect_offense(<<~RUBY) | ||
def self.method(x, &block) | ||
do_something if block_given? | ||
^^^^^^^^^^^^ Check block argument explicitly instead of using `block_given?`. | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
def self.method(x, &block) | ||
do_something if block | ||
end | ||
RUBY | ||
end | ||
|
||
it 'registers an offense and corrects when using `block_given?` in a method with non standard block arg name' do | ||
expect_offense(<<~RUBY) | ||
def method(x, &myblock) | ||
do_something if block_given? | ||
^^^^^^^^^^^^ Check block argument explicitly instead of using `block_given?`. | ||
end | ||
RUBY | ||
|
||
expect_correction(<<~RUBY) | ||
def method(x, &myblock) | ||
do_something if myblock | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when using `block_given?` in a method without block arg' do | ||
expect_no_offenses(<<~RUBY) | ||
def method(x) | ||
do_something if block_given? | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when block arg is reassigned' do | ||
expect_no_offenses(<<~RUBY) | ||
def method(a, &block) | ||
block ||= -> {} | ||
do_something if block_given? | ||
end | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense when `block_given?` is used outside of a method' do | ||
expect_no_offenses(<<~RUBY) | ||
do_something if block_given? | ||
RUBY | ||
end | ||
end |