From 9469ba0aebec3b375215ffaaa9992d795daec804 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Tue, 23 Jun 2020 20:34:48 +0900 Subject: [PATCH] [Fix #8195] Fix an error for `Style/RedundantFetchBlock` Fixes #8195 This PR fixes an error for `Style/RedundantFetchBlock` when using `#fetch` with empty block. --- CHANGELOG.md | 4 ++++ .../cop/style/redundant_fetch_block.rb | 24 +++++++++++++------ .../cop/style/redundant_fetch_block_spec.rb | 11 +++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3c5770ec36..b8f6a128ea3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/lib/rubocop/cop/style/redundant_fetch_block.rb b/lib/rubocop/cop/style/redundant_fetch_block.rb index 7140c740c59..519157592d8 100644 --- a/lib/rubocop/cop/style/redundant_fetch_block.rb +++ b/lib/rubocop/cop/style/redundant_fetch_block.rb @@ -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) @@ -65,7 +65,9 @@ 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 @@ -73,7 +75,11 @@ def autocorrect(node) 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) @@ -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? diff --git a/spec/rubocop/cop/style/redundant_fetch_block_spec.rb b/spec/rubocop/cop/style/redundant_fetch_block_spec.rb index 744e24ed7ef..3e5426f84cb 100644 --- a/spec/rubocop/cop/style/redundant_fetch_block_spec.rb +++ b/spec/rubocop/cop/style/redundant_fetch_block_spec.rb @@ -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 }