diff --git a/src/ameba/ast/scope.cr b/src/ameba/ast/scope.cr index e8f763d5..ba0459c3 100644 --- a/src/ameba/ast/scope.cr +++ b/src/ameba/ast/scope.cr @@ -4,6 +4,9 @@ module Ameba::AST # Represents a context of the local variable visibility. # This is where the local variables belong to. class Scope + # Whether the scope yields. + setter yields = false + # Link to local variables getter variables = [] of Variable @@ -143,6 +146,14 @@ module Ameba::AST end || variable.used_in_macro? end + # Returns `true` if current scope (or any of inner scopes) yields, + # `false` otherwise. + def yields?(check_inner_scopes = true) + return true if @yields + return inner_scopes.any?(&.yields?) if check_inner_scopes + false + end + # Returns `true` if current scope is a def, `false` otherwise. def def? node.is_a?(Crystal::Def) diff --git a/src/ameba/ast/visitors/scope_visitor.cr b/src/ameba/ast/visitors/scope_visitor.cr index be369b2c..f3fc3674 100644 --- a/src/ameba/ast/visitors/scope_visitor.cr +++ b/src/ameba/ast/visitors/scope_visitor.cr @@ -64,6 +64,11 @@ module Ameba::AST end {% end %} + # :nodoc: + def visit(node : Crystal::Yield) + @current_scope.yields = true + end + # :nodoc: def visit(node : Crystal::Def) node.name == "->" || on_scope_enter(node)