Skip to content

Commit

Permalink
Merge pull request #451 from crystal-ameba/tweak-useless-assign
Browse files Browse the repository at this point in the history
Refactor `Lint/UselessAssign` rule a bit
  • Loading branch information
Sija authored Jan 20, 2024
2 parents 7f50ff9 + 3bea264 commit 590640b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
8 changes: 4 additions & 4 deletions spec/ameba/rule/lint/useless_assign_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ module Ameba::Rule::Lint
expect_issue subject, <<-CRYSTAL
class A
foo : String? = "foo"
# ^^^^^^^^^^^^^^^^^^^^^ error: Useless assignment to variable `foo`
# ^^^ error: Useless assignment to variable `foo`
def method
foo = "bar"
Expand Down Expand Up @@ -992,15 +992,15 @@ module Ameba::Rule::Lint
it "reports if it's not referenced at a top level" do
expect_issue subject, <<-CRYSTAL
a : String?
# ^^^^^^^^^ error: Useless assignment to variable `a`
# ^{} error: Useless assignment to variable `a`
CRYSTAL
end

it "reports if it's not referenced in a method" do
expect_issue subject, <<-CRYSTAL
def foo
a : String?
# ^^^^^^^^^^^ error: Useless assignment to variable `a`
# ^ error: Useless assignment to variable `a`
end
CRYSTAL
end
Expand All @@ -1009,7 +1009,7 @@ module Ameba::Rule::Lint
expect_issue subject, <<-CRYSTAL
class Foo
a : String?
# ^^^^^^^^^^^ error: Useless assignment to variable `a`
# ^ error: Useless assignment to variable `a`
end
CRYSTAL
end
Expand Down
27 changes: 20 additions & 7 deletions src/ameba/rule/lint/useless_assign.cr
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,31 @@ module Ameba::Rule::Lint

scope.variables.each do |var|
next if var.ignored? || var.used_in_macro? || var.captured_by_block?

if scope.assigns_type_dec?(var.name)
next if exclude_type_declarations?
# exclude type declarations within calls
if node.is_a?(Crystal::Expressions)
next if node.expressions.first?.is_a?(Crystal::Call)
end
next if exclude_type_declarations? || expressions_with_call?(node)
end

var.assignments.each do |assign|
next if assign.referenced?
issue_for assign.target_node, MSG % var.name
check_assignment(source, assign, var)
end
end
end

private def expressions_with_call?(node)
node.is_a?(Crystal::Expressions) &&
node.expressions.first?.is_a?(Crystal::Call)
end

private def check_assignment(source, assign, var)
return if assign.referenced?

case target_node = assign.target_node
when Crystal::TypeDeclaration
issue_for target_node.var, MSG % var.name
else
issue_for target_node, MSG % var.name
end
end
end
end

0 comments on commit 590640b

Please sign in to comment.