Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #8195] Fix an error for Style/RedundantFetchBlock #8197

Merged
merged 1 commit into from Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,10 @@

* [#7868](https://github.com/rubocop-hq/rubocop/pull/7868): `Cop::Base` is the new recommended base class for cops. Extensive refactoring of `Team`, `Commissioner`. ([@marcandre][])

### Bug fixes

* [#8195](https://github.com/rubocop-hq/rubocop/issues/8195): Fix an error for `Style/RedundantFetchBlock` when using `#fetch` with empty block. ([@koic][])

## 0.86.0 (2020-06-22)

### New features
Expand Down
24 changes: 17 additions & 7 deletions lib/rubocop/cop/style/redundant_fetch_block.rb
Expand Up @@ -41,13 +41,13 @@ class RedundantFetchBlock < Cop
(block
$(send _ :fetch _)
(args)
${#basic_literal? const_type?})
${nil? #basic_literal? #const_type?})
PATTERN

def on_block(node)
redundant_fetch_block_candidate?(node) do |send, body|
return if body.const_type? && !check_for_constant?
return if body.str_type? && !check_for_string?
return if body&.const_type? && !check_for_constant?
return if body&.str_type? && !check_for_string?

range = fetch_range(send, node)
good = build_good_method(send, body)
Expand All @@ -65,15 +65,21 @@ def autocorrect(node)
redundant_fetch_block_candidate?(node) do |send, body|
lambda do |corrector|
receiver, _, key = send.children
corrector.replace(node, "#{receiver.source}.fetch(#{key.source}, #{body.source})")
default_value = body ? body.source : 'nil'

corrector.replace(node, "#{receiver.source}.fetch(#{key.source}, #{default_value})")
end
end
end

private

def basic_literal?(node)
node.basic_literal?
node&.basic_literal?
end

def const_type?(node)
node&.const_type?
end

def fetch_range(send, node)
Expand All @@ -82,12 +88,16 @@ def fetch_range(send, node)

def build_good_method(send, body)
key = send.children[2].source
"fetch(#{key}, #{body.source})"
default_value = body ? body.source : 'nil'

"fetch(#{key}, #{default_value})"
end

def build_bad_method(send, body)
key = send.children[2].source
"fetch(#{key}) { #{body.source} }"
block = body ? "{ #{body.source} }" : '{}'

"fetch(#{key}) #{block}"
end

def check_for_constant?
Expand Down
11 changes: 11 additions & 0 deletions spec/rubocop/cop/style/redundant_fetch_block_spec.rb
Expand Up @@ -67,6 +67,17 @@
RUBY
end

it 'registers an offense and corrects when using `#fetch` with empty block' do
expect_offense(<<~RUBY)
hash.fetch(:key) {}
^^^^^^^^^^^^^^ Use `fetch(:key, nil)` instead of `fetch(:key) {}`.
RUBY

expect_correction(<<~RUBY)
hash.fetch(:key, nil)
RUBY
end

it 'registers an offense and corrects when using `#fetch` with constant in the block' do
expect_offense(<<~RUBY)
hash.fetch(:key) { CONSTANT }
Expand Down