Don’t treat crystal paths as literals in Lint/LiteralsComparison

This commit is contained in:
Sijawusz Pur Rahnama 2022-12-08 13:55:29 +01:00
parent 150ba6c70f
commit 2cb8c1381f
2 changed files with 3 additions and 32 deletions

View file

@ -41,26 +41,13 @@ module Ameba::Rule::Lint
CRYSTAL
end
it "reports if there is a static path comparison evaluating to false" do
expect_issue subject, <<-CRYSTAL
String == Nil
# ^^^^^^^^^^^ error: Comparison always evaluates to false
CRYSTAL
end
context "macro" do
pending "reports in macro scope" do
it "reports in macro scope" do
expect_issue subject, <<-CRYSTAL
{{ "foo" == "foo" }}
# ^^^^^^^^^^^^^^ error: Comparison always evaluates to true
CRYSTAL
end
it "passes for free variables comparisons in macro scope" do
expect_no_issues subject, <<-CRYSTAL
{{ T == Nil }}
CRYSTAL
end
end
it "reports rule, pos and message" do

View file

@ -29,28 +29,12 @@ module Ameba::Rule::Lint
MSG = "Comparison always evaluates to %s"
MSG_LIKELY = "Comparison most likely evaluates to %s"
# Edge-case: `{{ T == Nil }}`
#
# Current implementation just skips all macro contexts,
# regardless of the free variable being present.
#
# Ideally we should only check whether either of the sides
# is a free var
def test(source)
AST::NodeVisitor.new self, source, skip: [
Crystal::Macro,
Crystal::MacroExpression,
Crystal::MacroIf,
Crystal::MacroFor,
]
end
def test(source, node : Crystal::Call)
return unless node.name.in?(OP_NAMES)
return unless (obj = node.obj) && (arg = node.args.first?)
obj_is_literal, obj_is_static = literal_kind?(obj, include_paths: true)
arg_is_literal, arg_is_static = literal_kind?(arg, include_paths: true)
obj_is_literal, obj_is_static = literal_kind?(obj)
arg_is_literal, arg_is_static = literal_kind?(arg)
return unless obj_is_literal && arg_is_literal