Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added new
Lint/TopLevelReturnWithArgument
cop (#8377)
Added new cop for detecting top-level return with argument
- Loading branch information
1 parent
ca9483a
commit b8eaa55
Showing
7 changed files
with
194 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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Lint | ||
# This cop checks for top level return with arguments. If there is a | ||
# top-level return statement with an argument, then the argument is | ||
# always ignored. This is detected automatically since Ruby 2.7. | ||
# | ||
# @example | ||
# | ||
# # Detected since Ruby 2.7 | ||
# return 1 # 1 is always ignored. | ||
class TopLevelReturnWithArgument < Cop | ||
# This cop works by validating the ancestors of the return node. A | ||
# top-level return node's ancestors should not be of block, def, or | ||
# defs type. | ||
|
||
MSG = 'Top level return with argument detected.' | ||
|
||
def on_return(return_node) | ||
add_offense(return_node) if return_node.arguments? && ancestors_valid?(return_node) | ||
end | ||
|
||
private | ||
|
||
def ancestors_valid?(return_node) | ||
prohibited_ancestors = return_node.each_ancestor(:block, :def, :defs) | ||
prohibited_ancestors.none? | ||
end | ||
end | ||
end | ||
end | ||
end |
127 changes: 127 additions & 0 deletions
127
spec/rubocop/cop/lint/top_level_return_with_argument_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,127 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Lint::TopLevelReturnWithArgument, :config do | ||
context 'Code segment with only top-level return statement' do | ||
it 'Expects no offense from the return without arguments' do | ||
expect_no_offenses(<<~RUBY) | ||
return | ||
RUBY | ||
end | ||
|
||
it 'Expects offense from the return with arguments' do | ||
expect_offense(<<~RUBY) | ||
return 1, 2, 3 | ||
^^^^^^^^^^^^^^ Top level return with argument detected. | ||
RUBY | ||
end | ||
|
||
it 'Expects multiple offenses from the return with arguments statements' do | ||
expect_offense(<<~RUBY) | ||
return 1, 2, 3 | ||
^^^^^^^^^^^^^^ Top level return with argument detected. | ||
return 1, 2, 3 | ||
^^^^^^^^^^^^^^ Top level return with argument detected. | ||
return 1, 2, 3 | ||
^^^^^^^^^^^^^^ Top level return with argument detected. | ||
RUBY | ||
end | ||
end | ||
|
||
context 'Code segment with block level returns other than the top-level return' do | ||
it 'Expects no offense from the return without arguments' do | ||
expect_no_offenses(<<~RUBY) | ||
foo | ||
[1, 2, 3, 4, 5].each { |n| return n } | ||
return | ||
bar | ||
RUBY | ||
end | ||
|
||
it 'Expects offense from the return with arguments' do | ||
expect_offense(<<~RUBY) | ||
foo | ||
[1, 2, 3, 4, 5].each { |n| return n } | ||
return 1, 2, 3 | ||
^^^^^^^^^^^^^^ Top level return with argument detected. | ||
bar | ||
RUBY | ||
end | ||
end | ||
|
||
context 'Code segment with method-level return statements' do | ||
it 'Expects offense when method-level & top-level return co-exist' do | ||
expect_offense(<<~RUBY) | ||
def method | ||
return 'Hello World' | ||
end | ||
return 1, 2, 3 | ||
^^^^^^^^^^^^^^ Top level return with argument detected. | ||
RUBY | ||
end | ||
end | ||
|
||
context 'Code segment with inline if along with top-level return' do | ||
it 'Expects no offense from the return without arguments' do | ||
expect_no_offenses(<<~RUBY) | ||
foo | ||
return if 1 == 1 | ||
bar | ||
def method | ||
return "Hello World" if 1 == 1 | ||
end | ||
RUBY | ||
end | ||
|
||
it 'Expects multiple offense from the return with arguments' do | ||
expect_offense(<<~RUBY) | ||
foo | ||
return 1, 2, 3 if 1 == 1 | ||
^^^^^^^^^^^^^^ Top level return with argument detected. | ||
bar | ||
return 2 | ||
^^^^^^^^ Top level return with argument detected. | ||
return 3 | ||
^^^^^^^^ Top level return with argument detected. | ||
def method | ||
return "Hello World" if 1 == 1 | ||
end | ||
RUBY | ||
end | ||
end | ||
|
||
context 'Code segment containing semi-colon separated statements' do | ||
it 'Expects an offense from the return with arguments and multi-line code' do | ||
expect_offense(<<~RUBY) | ||
foo | ||
if a == b; warn 'hey'; return 42; end | ||
^^^^^^^^^ Top level return with argument detected. | ||
bar | ||
RUBY | ||
end | ||
|
||
it 'Expects no offense from the return with arguments and multi-line code' do | ||
expect_no_offenses(<<~RUBY) | ||
foo | ||
if a == b; warn 'hey'; return; end | ||
bar | ||
RUBY | ||
end | ||
end | ||
end |