Refactor `ScopeVisitor` to ignore accessor macros

This commit is contained in:
Sijawusz Pur Rahnama 2023-12-27 23:47:58 +01:00
parent 9745637cf9
commit 1b661d633d
2 changed files with 30 additions and 13 deletions

View File

@ -186,6 +186,16 @@ module Ameba::AST
node.is_a?(Crystal::Def)
end
# Returns `true` if current scope is a class, `false` otherwise.
def class_def?
node.is_a?(Crystal::ClassDef)
end
# Returns `true` if current scope is a module, `false` otherwise.
def module_def?
node.is_a?(Crystal::ModuleDef)
end
# Returns `true` if this scope is a top level scope, `false` otherwise.
def top_level?
outer_scope.nil? || type_definition?

View File

@ -170,22 +170,29 @@ module Ameba::AST
# :nodoc:
def visit(node : Crystal::Call)
case
when @current_scope.def?
if node.name.in?(SPECIAL_NODE_NAMES) && node.args.empty?
@current_scope.arguments.each do |arg|
variable = arg.variable
scope = @current_scope
ref = variable.reference(variable.node, @current_scope)
ref.explicit = false
end
case
when scope.top_level? && record_macro?(node) then return false
when scope.type_definition? && record_macro?(node) then return false
when scope.type_definition? && accessor_macro?(node) then return false
when scope.def? && special_node?(node)
scope.arguments.each do |arg|
variable = arg.variable
ref = variable.reference(variable.node, scope)
ref.explicit = false
end
true
when @current_scope.top_level? && record_macro?(node)
false
else
true
end
true
end
private def special_node?(node)
node.name.in?(SPECIAL_NODE_NAMES) && node.args.empty?
end
private def accessor_macro?(node)
node.name.matches? /^(class_)?(getter[?!]?|setter|property[?!]?)$/
end
private def record_macro?(node)