Commit f008b6a9 authored by Jacopo's avatar Jacopo

Updates after 2nd review

parent 81a22b76
......@@ -111,7 +111,7 @@ namespace :gitlab do
puts " - #{project.full_path} (id: #{project.id})".color(:red)
return if counter >= limit # rubocop:disable Lint/NonLocalExitFromIterator
return if counter >= limit # rubocop:disable Lint/NonLocalExitFromIterator, Cop/AvoidReturnFromBlocks
end
end
end
......@@ -132,7 +132,7 @@ namespace :gitlab do
puts " - #{upload.path} (id: #{upload.id})".color(:red)
return if counter >= limit # rubocop:disable Lint/NonLocalExitFromIterator
return if counter >= limit # rubocop:disable Lint/NonLocalExitFromIterator, Cop/AvoidReturnFromBlocks
end
end
end
......
......@@ -3,6 +3,7 @@
module RuboCop
module Cop
# Checks for break inside strong_memoize blocks.
# For more information see: https://gitlab.com/gitlab-org/gitlab-ce/issues/42889
#
# @example
# # bad
......@@ -26,11 +27,10 @@ module RuboCop
block_body = node.body
return unless block_body
return unless node.method_name == :strong_memoize
block_body.each_node(:break) do |break_node|
container_block = container_block_for(break_node)
next if container_block.method_name != :strong_memoize
next if container_block != node
next if container_block_for(break_node) != node
add_offense(break_node)
end
......@@ -39,7 +39,7 @@ module RuboCop
private
def container_block_for(current_node)
current_node = current_node.parent until current_node.type == :block
current_node = current_node.parent until current_node.type == :block && current_node.method_name == :strong_memoize
current_node
end
......
......@@ -3,7 +3,7 @@
module RuboCop
module Cop
# Checks for return inside blocks.
# Whitelisted methods are ignored: each, each_filename, times, loop, define_method.
# For more information see: https://gitlab.com/gitlab-org/gitlab-ce/issues/42889
#
# @example
# # bad
......@@ -22,40 +22,46 @@ module RuboCop
#
class AvoidReturnFromBlocks < RuboCop::Cop::Cop
MSG = 'Do not return from a block, use next or break instead.'
WHITELISTED_METHODS = %i[each each_filename times loop define_method lambda].freeze
WHITELISTED_METHODS = %i[each each_filename times loop define_method lambda helpers class_methods describe included namespace validations].freeze
def on_block(node)
block_body = node.body
return unless block_body
return if WHITELISTED_METHODS.include?(node.method_name)
return unless top_block?(node)
block_body.each_node(:return) do |return_node|
next if container_block_for(return_node) != node
next if container_block_whitelisted?(return_node)
next if return_inside_method_definition?(return_node)
next if contained_blocks(node, return_node).all?(&method(:whitelisted?))
add_offense(return_node)
end
end
private
def top_block?(node)
current_node = node
top_block = nil
def container_block_for(current_node)
current_node = current_node.parent until current_node.type == :block
while current_node && current_node.type != :def
top_block = current_node if current_node.type == :block
current_node = current_node.parent
end
current_node
top_block == node
end
def container_block_whitelisted?(current_node)
WHITELISTED_METHODS.include?(container_block_for(current_node).method_name)
end
def contained_blocks(node, current_node)
blocks = []
def return_inside_method_definition?(current_node)
current_node = current_node.parent until %i[def block].include?(current_node.type)
until node == current_node
blocks << current_node if current_node.type == :block
current_node = current_node.parent
end
blocks << node
end
# if we found :def before :block in the nodes hierarchy
current_node.type == :def
def whitelisted?(block_node)
WHITELISTED_METHODS.include?(block_node.method_name)
end
end
end
......
......@@ -26,6 +26,19 @@ describe RuboCop::Cop::AvoidBreakFromStrongMemoize do
expect(offense.message).to eq('Do not use break inside strong_memoize, use next instead.')
end
it 'flags violation for break inside strong_memoize nested blocks' do
source = <<~RUBY
strong_memoize do
items.each do |item|
break item
end
end
RUBY
inspect_source(source)
expect(cop.offenses.size).to eq(1)
end
it "doesn't flag violation for next inside strong_memoize" do
source = <<~RUBY
strong_memoize(:result) do
......
......@@ -53,8 +53,8 @@ describe RuboCop::Cop::AvoidReturnFromBlocks do
end
end
%w[each each_filename times loop define_method].each do |example|
it_behaves_like 'examples with whitelisted method', example
%i[each each_filename times loop define_method lambda helpers class_methods describe included namespace validations].each do |whitelisted_method|
it_behaves_like 'examples with whitelisted method', whitelisted_method
end
it "doesn't flag violation for return inside a lambda" do
......@@ -83,22 +83,6 @@ describe RuboCop::Cop::AvoidReturnFromBlocks do
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for whitelisted method inside nested blocks" do
source = <<~RUBY
call do
call_2 do
items.each do |item|
do_something
return if something_else
end
end
end
RUBY
inspect_source(source)
expect(cop.offenses).to be_empty
end
it "doesn't flag violation for next inside a block" do
source = <<~RUBY
call do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment