Skip to content

Commit

Permalink
Merge pull request #11907 from koic/fix_an_error_for_lint_useless_ass…
Browse files Browse the repository at this point in the history
…ignment

[Fix #11905] Fix an error for `Lint/UselessAssignment`
  • Loading branch information
koic committed Jun 1, 2023
2 parents 1884a46 + 63ede93 commit 172cc75
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog/fix_an_error_for_lint_useless_assignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#11905](https://github.com/rubocop/rubocop/issues/11905): Fix an error for `Lint/UselessAssignment` when a variable is assigned with rest assignment and unreferenced. ([@koic][])
4 changes: 3 additions & 1 deletion lib/rubocop/cop/lint/useless_assignment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ def variable_like_method_invocation?(node)
node.receiver.nil? && !node.arguments?
end

# rubocop:disable Metrics/AbcSize
def autocorrect(corrector, assignment)
if assignment.exception_assignment?
remove_exception_assignment_part(corrector, assignment.node)
elsif assignment.multiple_assignment?
elsif assignment.multiple_assignment? || assignment.rest_assignment?
rename_variable_with_underscore(corrector, assignment.node)
elsif assignment.operator_assignment?
remove_trailing_character_from_operator(corrector, assignment.node)
Expand All @@ -146,6 +147,7 @@ def autocorrect(corrector, assignment)
remove_local_variable_assignment_part(corrector, assignment.node)
end
end
# rubocop:enable Metrics/AbcSize

def remove_exception_assignment_part(corrector, node)
corrector.remove(
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/variable_force.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class VariableForce < Force # rubocop:disable Metrics/ClassLength
OPERATOR_ASSIGNMENT_TYPES = (LOGICAL_OPERATOR_ASSIGNMENT_TYPES + [:op_asgn]).freeze

MULTIPLE_ASSIGNMENT_TYPE = :masgn
REST_ASSIGNMENT_TYPE = :splat

VARIABLE_REFERENCE_TYPE = :lvar

Expand Down
17 changes: 16 additions & 1 deletion lib/rubocop/cop/variable_force/assignment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,22 @@ def multiple_assignment?
meta_assignment_node.type == MULTIPLE_ASSIGNMENT_TYPE
end

def rest_assignment?
return false unless meta_assignment_node

meta_assignment_node.type == REST_ASSIGNMENT_TYPE
end

def operator
assignment_node = meta_assignment_node || @node
assignment_node.loc.operator.source
end

def meta_assignment_node
unless instance_variable_defined?(:@meta_assignment_node)
@meta_assignment_node = operator_assignment_node || multiple_assignment_node
@meta_assignment_node = operator_assignment_node ||
multiple_assignment_node ||
rest_assignment_node
end

@meta_assignment_node
Expand All @@ -94,6 +102,13 @@ def multiple_assignment_node

grandparent_node
end

def rest_assignment_node
return nil unless node.parent
return nil unless node.parent.type == REST_ASSIGNMENT_TYPE

node.parent
end
end
end
end
Expand Down
19 changes: 19 additions & 0 deletions spec/rubocop/cop/lint/useless_assignment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,25 @@ def some_method
end
end

context 'when a variable is assigned with rest assignment and unreferenced' do
it 'registers an offense' do
expect_offense(<<~RUBY)
def some_method
foo, *bar = do_something
^^^ Useless assignment to variable - `bar`.
puts foo
end
RUBY

expect_correction(<<~RUBY)
def some_method
foo, *_ = do_something
puts foo
end
RUBY
end
end

context 'when a variable is assigned in loop body and referenced in post while condition' do
it 'accepts' do
expect_no_offenses(<<~RUBY)
Expand Down
14 changes: 14 additions & 0 deletions spec/rubocop/cop/variable_force/assignment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ def some_method
expect(assignment.meta_assignment_node.type).to eq(:masgn)
end
end

context 'when it is rest assignment' do
let(:source) do
<<~RUBY
def some_method
*foo = [1, 2]
end
RUBY
end

it 'returns splat node' do
expect(assignment.meta_assignment_node.type).to eq(:splat)
end
end
end

describe '#operator' do
Expand Down

0 comments on commit 172cc75

Please sign in to comment.