class SyntaxTree::WithScope::Scope

inside a particular scope.
The scope class is used to keep track of local variables and arguments

def add_local_definition(identifier, type)

registered.
that it's not possible to change the type of a local after it has been
hash or append a new definition location to an existing local. Notice
Adding a local definition will either insert a new entry in the locals
def add_local_definition(identifier, type)
  name = identifier.value.delete_suffix(":")
  local =
    if type == :argument
      locals[name] ||= Local.new(type)
    else
      resolve_local(name, type)
    end
  local.add_definition(identifier.location)
end

def add_local_usage(identifier, type)

registered.
it's not possible to change the type of a local after it has been
hash or append a new usage location to an existing local. Notice that
Adding a local usage will either insert a new entry in the locals
def add_local_usage(identifier, type)
  name = identifier.value.delete_suffix(":")
  resolve_local(name, type).add_usage(identifier.location)
end

def find_local(name)

parents.
Try to find the local given its name in this scope or any of its
def find_local(name)
  locals[name] || parent&.find_local(name)
end

def initialize(id, parent = nil)

def initialize(id, parent = nil)
  @id = id
  @parent = parent
  @locals = {}
end

def resolve_local(name, type)

def resolve_local(name, type)
  local = find_local(name)
  unless local
    local = Local.new(type)
    locals[name] = local
  end
  local
end