Skip to content

Commit

Permalink
Merge pull request #12384 from koic/fix_false_positives_for_lint_void
Browse files Browse the repository at this point in the history
[Fix #12377] Fix false positives for `Lint/Void`
  • Loading branch information
koic committed Nov 18, 2023
2 parents 2b27768 + 053d68c commit 4c40a2d
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 1 deletion.
1 change: 1 addition & 0 deletions changelog/fix_false_positives_for_lint_void.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#12377](https://github.com/rubocop/rubocop/issues/12377): Fix false positives for `Lint/Void` when a collection literal that includes non-literal elements in a method definition. ([@koic][])
15 changes: 14 additions & 1 deletion lib/rubocop/cop/lint/void.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def check_var(node)
end

def check_literal(node)
return if !node.literal? || node.xstr_type? || node.range_type?
return if !entirely_literal?(node) || node.xstr_type? || node.range_type?

add_offense(node, message: format(LIT_MSG, lit: node.source)) do |corrector|
autocorrect_void_expression(corrector, node)
Expand Down Expand Up @@ -217,6 +217,19 @@ def autocorrect_nonmutating_send(corrector, node, suggestion)
end
corrector.replace(send_node.loc.selector, suggestion)
end

def entirely_literal?(node)
case node.type
when :array
node.each_value.all? { |value| entirely_literal?(value) }
when :hash
return false unless node.each_key.all? { |key| entirely_literal?(key) }

node.each_value.all? { |value| entirely_literal?(value) }
else
node.literal?
end
end
end
end
end
Expand Down
125 changes: 125 additions & 0 deletions spec/rubocop/cop/lint/void_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,131 @@ def merge
end
end

it 'does not register an offense for an array literal that includes non-literal elements in a method definition' do
expect_no_offenses(<<~RUBY)
def something
[foo, bar]
baz
end
RUBY
end

it 'does not register an offense for a nested array literal that includes non-literal elements in a method definition' do
expect_no_offenses(<<~RUBY)
def something
[1, 2, [foo, bar]]
baz
end
RUBY
end

it 'registers an offense for an array literal composed entirely of literals in a method definition' do
expect_offense(<<~RUBY)
def something
[1, 2]
^^^^^^ Literal `[1, 2]` used in void context.
baz
end
RUBY
end

it 'registers an offense for a nested array literal composed entirely of literals in a method definition' do
expect_offense(<<~RUBY)
def something
[1, 2, [3]]
^^^^^^^^^^^ Literal `[1, 2, [3]]` used in void context.
baz
end
RUBY
end

it 'does not register an offense for a hash literal that includes non-literal value elements in a method definition' do
expect_no_offenses(<<~RUBY)
def something
{k1: foo, k2: bar}
baz
end
RUBY
end

it 'does not register an offense for a nested hash literal that includes non-literal value elements in a method definition' do
expect_no_offenses(<<~RUBY)
def something
{k0: {k1: foo, k2: bar}}
baz
end
RUBY
end

it 'does not register an offense for a hash literal that includes non-literal key elements in a method definition' do
expect_no_offenses(<<~RUBY)
def something
{foo => 1, bar => 2}
baz
end
RUBY
end

it 'does not register an offense for a nested hash literal that includes non-literal key elements in a method definition' do
expect_no_offenses(<<~RUBY)
def something
{foo: 1, bar: {baz => 2}}
baz
end
RUBY
end

it 'registers an offense for a hash literal composed entirely of literals in a method definition' do
expect_offense(<<~RUBY)
def something
{k1: 1, k2: 2}
^^^^^^^^^^^^^^ Literal `{k1: 1, k2: 2}` used in void context.
baz
end
RUBY

expect_correction(<<~RUBY)
def something
baz
end
RUBY
end

it 'registers an offense for a nested hash literal composed entirely of literals in a method definition' do
expect_offense(<<~RUBY)
def something
{x: {k1: 1, k2: 2}}
^^^^^^^^^^^^^^^^^^^ Literal `{x: {k1: 1, k2: 2}}` used in void context.
baz
end
RUBY

expect_correction(<<~RUBY)
def something
baz
end
RUBY
end

it 'does not register an offense for a hash literal that includes array literal key within non-literal elements in a method definition' do
expect_no_offenses(<<~RUBY)
def something
{[foo, bar] => :foo}
baz
end
RUBY
end

it 'registers an offense for a hash literal that includes array literal key within literal elements in a method definition' do
expect_offense(<<~RUBY)
def something
{[1, 2] => :foo}
^^^^^^^^^^^^^^^^ Literal `{[1, 2] => :foo}` used in void context.
baz
end
RUBY
end

it 'registers an offense for void literal in a method definition' do
expect_offense(<<~RUBY)
def something
Expand Down

0 comments on commit 4c40a2d

Please sign in to comment.