mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Do not report if variable is assigned and referenced in MacroFor/MacroIf/MacroExpression
closes #194
This commit is contained in:
parent
4958fa2315
commit
7aa7efd4bd
2 changed files with 83 additions and 10 deletions
|
@ -944,6 +944,66 @@ module Ameba::Rule::Lint
|
|||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if assignment is referenced in a macro expression as string" do
|
||||
s = Source.new %(
|
||||
foo = 1
|
||||
puts {{ "foo".id }}
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if assignement is referenced in for macro in exp" do
|
||||
s = Source.new %(
|
||||
foo = 22
|
||||
|
||||
{% for x in %w(foo) %}
|
||||
add({{x.id}})
|
||||
{% end %}
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if assignement is referenced in for macro in body" do
|
||||
s = Source.new %(
|
||||
foo = 22
|
||||
|
||||
{% for x in %w(bar) %}
|
||||
puts {{ "foo".id }}
|
||||
{% end %}
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if assignement is referenced in if macro in cond" do
|
||||
s = Source.new %(
|
||||
foo = 22
|
||||
{% if "foo".id %}
|
||||
{% end %}
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if assignement is referenced in if macro in then" do
|
||||
s = Source.new %(
|
||||
foo = 22
|
||||
{% if true %}
|
||||
puts {{ "foo".id }}
|
||||
{% end %}
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
|
||||
it "doesn't report if assignement is referenced in if macro in else" do
|
||||
s = Source.new %(
|
||||
foo = 22
|
||||
{% if true %}
|
||||
{% else %}
|
||||
puts {{ "foo".id }}
|
||||
{% end %}
|
||||
)
|
||||
subject.catch(s).should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "uninitialized" do
|
||||
|
|
|
@ -120,12 +120,13 @@ module Ameba::AST
|
|||
false
|
||||
end
|
||||
|
||||
# Returns true if current variable potentially referenced in a macro literal,
|
||||
# Returns true if current variable potentially referenced in a macro,
|
||||
# false if not.
|
||||
def used_in_macro?(scope = @scope)
|
||||
scope.inner_scopes.each do |inner_scope|
|
||||
return true if MacroLiteralFinder.new(inner_scope.node).references? node
|
||||
return true if MacroReferenceFinder.new(inner_scope.node, node.name).references
|
||||
end
|
||||
return true if MacroReferenceFinder.new(scope.node, node.name).references
|
||||
return true if (outer_scope = scope.outer_scope) && used_in_macro?(outer_scope)
|
||||
false
|
||||
end
|
||||
|
@ -167,23 +168,35 @@ module Ameba::AST
|
|||
var_location.column_number < node_location.column_number)
|
||||
end
|
||||
|
||||
private class MacroLiteralFinder < Crystal::Visitor
|
||||
@macro_literals = [] of Crystal::MacroLiteral
|
||||
private class MacroReferenceFinder < Crystal::Visitor
|
||||
property references = false
|
||||
|
||||
def initialize(node)
|
||||
def initialize(node, @reference : String = reference)
|
||||
node.accept self
|
||||
end
|
||||
|
||||
def references?(node : Crystal::Var)
|
||||
@macro_literals.any? { |literal| literal.value.includes? node.name }
|
||||
end
|
||||
|
||||
def visit(node : Crystal::ASTNode)
|
||||
true
|
||||
end
|
||||
|
||||
def visit(node : Crystal::MacroLiteral)
|
||||
@macro_literals << node
|
||||
!(self.references ||= node.value.includes?(@reference))
|
||||
end
|
||||
|
||||
def visit(node : Crystal::MacroExpression)
|
||||
!(self.references ||= node.exp.to_s.includes?(@reference))
|
||||
end
|
||||
|
||||
def visit(node : Crystal::MacroFor)
|
||||
exp, body = node.exp, node.body
|
||||
!(self.references ||= exp.to_s.includes?(@reference) ||
|
||||
body.to_s.includes?(@reference))
|
||||
end
|
||||
|
||||
def visit(node : Crystal::MacroIf)
|
||||
!(self.references ||= node.cond.to_s.includes?(@reference) ||
|
||||
node.then.to_s.includes?(@reference) ||
|
||||
node.else.to_s.includes?(@reference))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue