forked from rubocop/rubocop
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fix rubocop#4153] Add a new cop Lint/ReturnInVoidContext
- Loading branch information
Showing
7 changed files
with
201 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Lint | ||
# This cop checks for the use of a return with a value in a context | ||
# where it the value will be ignored. (initialize and setter methods) | ||
# | ||
# @example | ||
# | ||
# # bad | ||
# def initialize | ||
# foo | ||
# return :qux if bar? | ||
# baz | ||
# end | ||
# | ||
# def foo=(bar) | ||
# return 42 | ||
# end | ||
# | ||
# # good | ||
# def initialize | ||
# foo | ||
# return if bar? | ||
# baz | ||
# end | ||
# | ||
# def foo=(bar) | ||
# return | ||
# end | ||
# | ||
class ReturnInVoidContext < Cop | ||
MSG = 'Do not return a value in `%s`.'.freeze | ||
def on_return(return_node) | ||
method_name = method_name(return_node) | ||
return unless method_name && return_node.descendants.any? && | ||
useless_return_method?(method_name) | ||
|
||
add_offense(return_node, :keyword, format(message, method_name)) | ||
end | ||
|
||
private | ||
|
||
def method_name(return_node) | ||
method_node = return_node.each_ancestor(:block, :def, :defs).first | ||
return nil unless method_node.type == :def | ||
method_node.children.first | ||
end | ||
|
||
def method_setter?(method_name) | ||
method_name.to_s.end_with?('=') && | ||
!%i[!= == === >= <=].include?(method_name) | ||
end | ||
|
||
def useless_return_method?(method_name) | ||
method_name == :initialize || method_setter?(method_name) | ||
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
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,96 @@ | ||
# frozen_string_literal: true | ||
|
||
describe RuboCop::Cop::Lint::ReturnInVoidContext do | ||
subject(:cop) { described_class.new } | ||
|
||
shared_examples 'registers an offense' do |message| | ||
it 'registers an offense' do | ||
inspect_source(cop, source) | ||
|
||
expect(cop.offenses.size).to eq(1) | ||
expect(cop.messages).to eq([message]) | ||
end | ||
end | ||
|
||
shared_examples 'does not registers an offense' do | ||
it 'does not registers an offense' do | ||
inspect_source(cop, source) | ||
expect(cop.offenses.size).to eq(0) | ||
end | ||
end | ||
|
||
context 'with an initialize method containing a return with a value' do | ||
let(:source) do | ||
['class A', | ||
' def initialize', | ||
' return :qux if bar?', | ||
' end', | ||
'end'] | ||
end | ||
it_behaves_like 'registers an offense', | ||
'Do not return a value in `initialize`.' | ||
end | ||
|
||
context 'with an initialize method containing a return without a value' do | ||
let(:source) do | ||
['class A', | ||
' def initialize', | ||
' return if bar?', | ||
' end', | ||
'end'] | ||
end | ||
|
||
it_behaves_like 'does not registers an offense' | ||
end | ||
|
||
context 'with a setter method containing a return with a value' do | ||
let(:source) do | ||
['class A', | ||
' def foo=(bar)', | ||
' return 42', | ||
' end', | ||
'end'] | ||
end | ||
|
||
it_behaves_like 'registers an offense', | ||
'Do not return a value in `foo=`.' | ||
end | ||
|
||
context 'with a setter method containing a return without a value' do | ||
let(:source) do | ||
['class A', | ||
' def foo=(bar)', | ||
' return', | ||
' end', | ||
'end'] | ||
end | ||
|
||
it_behaves_like 'does not registers an offense' | ||
end | ||
|
||
context 'with a non initialize method containing a return' do | ||
let(:source) do | ||
['class A', | ||
' def bar', | ||
' foo', | ||
' return :qux if bar?', | ||
' foo', | ||
' end', | ||
'end'] | ||
end | ||
it_behaves_like 'does not registers an offense' | ||
end | ||
|
||
context 'with a class method called initialize containing a return' do | ||
let(:source) do | ||
['class A', | ||
' def self.initialize', | ||
' foo', | ||
' return :qux if bar?', | ||
' foo', | ||
' end', | ||
'end'] | ||
end | ||
it_behaves_like 'does not registers an offense' | ||
end | ||
end |