mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Incorporate changes for shadowing outer local var
This commit is contained in:
parent
ddbcf5cb3f
commit
14a9ec3a75
6 changed files with 64 additions and 1 deletions
|
@ -136,6 +136,19 @@ module Ameba::Rule::Lint
|
|||
CRYSTAL
|
||||
end
|
||||
|
||||
it "doesn't report if it shadows type definition" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
class FooBar
|
||||
getter index : String
|
||||
|
||||
def bar
|
||||
3.times do |index|
|
||||
end
|
||||
end
|
||||
end
|
||||
CRYSTAL
|
||||
end
|
||||
|
||||
it "doesn't report if it shadows throwaway arguments" do
|
||||
expect_no_issues subject, <<-CRYSTAL
|
||||
data = [{1, "a"}, {2, "b"}, {3, "c"}]
|
||||
|
|
|
@ -19,6 +19,9 @@ module Ameba::AST
|
|||
# Link to the instance variables used in current scope
|
||||
getter ivariables = [] of InstanceVariable
|
||||
|
||||
# Link to the type declaration variables used in current scope
|
||||
getter type_dec_variables = [] of TypeDecVariable
|
||||
|
||||
# Link to the outer scope
|
||||
getter outer_scope : Scope?
|
||||
|
||||
|
@ -74,6 +77,16 @@ module Ameba::AST
|
|||
ivariables << InstanceVariable.new(node)
|
||||
end
|
||||
|
||||
# Adds a new type declaration variable to the current scope.
|
||||
#
|
||||
# ```
|
||||
# scope = Scope.new(class_node, nil)
|
||||
# scope.add_type_dec_variable(node)
|
||||
# ```
|
||||
def add_type_dec_variable(node)
|
||||
type_dec_variables << TypeDecVariable.new(node)
|
||||
end
|
||||
|
||||
# Returns variable by its name or `nil` if it does not exist.
|
||||
#
|
||||
# ```
|
||||
|
@ -126,6 +139,11 @@ module Ameba::AST
|
|||
ivariables.find(&.name.== "@#{name}")
|
||||
end
|
||||
|
||||
# Returns `true` if type declaration variable is assigned in this scope.
|
||||
def assigns_type_dec?(name)
|
||||
type_dec_variables.find(&.name.== name) || outer_scope.try(&.assigns_type_dec?(name))
|
||||
end
|
||||
|
||||
# Returns `true` if and only if current scope represents some
|
||||
# type definition, for example a class.
|
||||
def type_definition?
|
||||
|
|
29
src/ameba/ast/variabling/type_def_variable.cr
Normal file
29
src/ameba/ast/variabling/type_def_variable.cr
Normal file
|
@ -0,0 +1,29 @@
|
|||
module Ameba::AST
|
||||
class TypeDecVariable
|
||||
getter node : Crystal::TypeDeclaration
|
||||
|
||||
delegate location, to: @node
|
||||
delegate end_location, to: @node
|
||||
delegate to_s, to: @node
|
||||
|
||||
def initialize(@node)
|
||||
end
|
||||
|
||||
def name
|
||||
var = @node.var
|
||||
|
||||
case var
|
||||
when Crystal::Var
|
||||
var.name
|
||||
when Crystal::InstanceVar
|
||||
var.name
|
||||
when Crystal::ClassVar
|
||||
var.name
|
||||
when Crystal::Global
|
||||
var.name
|
||||
else
|
||||
raise "unsupported type declaration var node"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -105,13 +105,14 @@ module Ameba::AST
|
|||
return unless (var = node.var).is_a?(Crystal::Var)
|
||||
|
||||
@current_scope.add_variable(var)
|
||||
@current_scope.add_type_dec_variable(node)
|
||||
@current_assign = node.value unless node.value.nil?
|
||||
end
|
||||
|
||||
def end_visit(node : Crystal::TypeDeclaration)
|
||||
return unless (var = node.var).is_a?(Crystal::Var)
|
||||
|
||||
on_assign_end(node.var, node)
|
||||
on_assign_end(var, node)
|
||||
@current_assign = nil
|
||||
on_scope_end(node) if @current_scope.eql?(node)
|
||||
end
|
||||
|
|
|
@ -57,6 +57,7 @@ module Ameba::Rule::Lint
|
|||
|
||||
next if variable.nil? || !variable.declared_before?(arg)
|
||||
next if outer_scope.assigns_ivar?(arg.name)
|
||||
next if outer_scope.assigns_type_dec?(arg.name)
|
||||
|
||||
issue_for arg.node, MSG % arg.name
|
||||
end
|
||||
|
|
|
@ -39,6 +39,7 @@ module Ameba::Rule::Lint
|
|||
def test(source, node, scope : AST::Scope)
|
||||
scope.variables.each do |var|
|
||||
next if var.ignored? || var.used_in_macro? || var.captured_by_block?
|
||||
next if scope.assigns_type_dec?(var.name)
|
||||
|
||||
var.assignments.each do |assign|
|
||||
next if assign.referenced? || assign.transformed?
|
||||
|
|
Loading…
Reference in a new issue