diff --git a/spec/ameba/rule/lint/unused_class_variable_access_spec.cr b/spec/ameba/rule/lint/unused_class_variable_access_spec.cr new file mode 100644 index 000000000..f15458d8d --- /dev/null +++ b/spec/ameba/rule/lint/unused_class_variable_access_spec.cr @@ -0,0 +1,46 @@ +require "../../../spec_helper" + +module Ameba::Rule::Lint + describe UnusedClassVariableAccess do + subject = UnusedClassVariableAccess.new + + it "passes if class variables are used for assignment" do + expect_no_issues subject, <<-CRYSTAL + class MyClass + a = @@ivar + B = @@ivar + end + CRYSTAL + end + + it "passes if an class variable is used as a target in multi-assignment" do + expect_no_issues subject, <<-CRYSTAL + class MyClass + @@a, @@b = 1, 2 + end + CRYSTAL + end + + it "fails if class variables are unused in void context of class" do + expect_issue subject, <<-CRYSTAL + class Actor + @@name : String = "George" + + @@name + # ^^^^^^ error: Value from class variable access is unused + end + CRYSTAL + end + + it "fails if class variables are unused in void context of method" do + expect_issue subject, <<-CRYSTAL + def hello : String + @@name + # ^^^^^^ error: Value from class variable access is unused + + "Hello, \#{@@name}!" + end + CRYSTAL + end + end +end diff --git a/src/ameba/rule/lint/unused_class_variable_access.cr b/src/ameba/rule/lint/unused_class_variable_access.cr new file mode 100644 index 000000000..49118c05a --- /dev/null +++ b/src/ameba/rule/lint/unused_class_variable_access.cr @@ -0,0 +1,58 @@ +module Ameba::Rule::Lint + # A rule that disallows unused class variable access. + # + # For example, this is considered invalid: + # + # ``` + # class MyClass + # @@my_var : String = "hello" + # + # @@my_var + # + # def hello : String + # @@my_var + # + # "hello, world!" + # end + # end + # ``` + # + # And these are considered valid: + # + # ``` + # class MyClass + # @@my_var : String = "hello" + # + # @@my_other_var = @@my_var + # + # def hello : String + # return @@my_var if @@my_var == "hello" + # + # "hello, world!" + # end + # end + # ``` + # + # YAML configuration example: + # + # ``` + # Lint/UnusedClassVariableAccess: + # Enabled: true + # ``` + class UnusedClassVariableAccess < Base + properties do + since_version "1.7.0" + description "Disallows unused access to class variables" + end + + MSG = "Value from class variable access is unused" + + def test(source : Source) + AST::ImplicitReturnVisitor.new(self, source) + end + + def test(source, node : Crystal::ClassVar, in_macro : Bool) + issue_for node, MSG + end + end +end