diff --git a/spec/ameba/rule/lint/useless_assign_spec.cr b/spec/ameba/rule/lint/useless_assign_spec.cr index 33f32213..d5325397 100644 --- a/spec/ameba/rule/lint/useless_assign_spec.cr +++ b/spec/ameba/rule/lint/useless_assign_spec.cr @@ -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" @@ -992,7 +992,7 @@ 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 @@ -1000,7 +1000,7 @@ module Ameba::Rule::Lint expect_issue subject, <<-CRYSTAL def foo a : String? - # ^^^^^^^^^^^ error: Useless assignment to variable `a` + # ^ error: Useless assignment to variable `a` end CRYSTAL end @@ -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 diff --git a/src/ameba/rule/lint/useless_assign.cr b/src/ameba/rule/lint/useless_assign.cr index fbf0c0d3..444eda8c 100644 --- a/src/ameba/rule/lint/useless_assign.cr +++ b/src/ameba/rule/lint/useless_assign.cr @@ -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