class Steep::Index::RBSIndex::Builder

def env(env)

def env(env)
  env.class_decls.each do |name, decl|
    decl.decls.each do |d|
      index.add_type_declaration(name, d.decl)
      case d.decl
      when RBS::AST::Declarations::Class
        if super_class = d.decl.super_class
          index.add_type_reference(super_class.name, d.decl)
          super_class.args.each do |type|
            type_reference(type, from: d.decl)
          end
        end
      when RBS::AST::Declarations::Module
        d.decl.self_types.each do |self_type|
          index.add_type_reference(self_type.name, d.decl)
          self_type.args.each do |type|
            type_reference(type, from: d.decl)
          end
        end
      end
      d.decl.members.each do |member|
        member(name, member)
      end
    end
  end
  env.class_alias_decls.each do |name, entry|
    index.add_type_declaration(name, entry.decl)
    index.add_type_reference(entry.decl.old_name, entry.decl)
  end
  env.interface_decls.each do |name, decl|
    index.add_type_declaration(name, decl.decl)
    decl.decl.members.each do |member|
      member(name, member)
    end
  end
  env.type_alias_decls.each do |name, decl|
    index.add_type_declaration(name, decl.decl)
    type_reference decl.decl.type, from: decl.decl
  end
  env.constant_decls.each do |name, decl|
    index.add_constant_declaration(name, decl.decl)
    type_reference decl.decl.type, from: decl.decl
  end
  env.global_decls.each do |name, decl|
    index.add_global_declaration(name, decl.decl)
    type_reference decl.decl.type, from: decl.decl
  end
end

def initialize(index:)

def initialize(index:)
  @index = index
end

def member(type_name, member)

def member(type_name, member)
  case member
  when RBS::AST::Members::MethodDefinition
    member.overloads.each do |overload|
      overload.method_type.each_type do |type|
        type_reference type, from: member
      end
    end
    if member.instance?
      method_name = InstanceMethodName.new(type_name: type_name, method_name: member.name)
      index.add_method_declaration(method_name, member)
    end
    if member.singleton?
      method_name = SingletonMethodName.new(type_name: type_name, method_name: member.name)
      index.add_method_declaration(method_name, member)
    end
  when RBS::AST::Members::AttrAccessor, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter
    type_reference member.type, from: member
    if member.is_a?(RBS::AST::Members::AttrReader) || member.is_a?(RBS::AST::Members::AttrAccessor)
      method_name = case member.kind
                    when :instance
                      InstanceMethodName.new(type_name: type_name, method_name: member.name)
                    when :singleton
                      SingletonMethodName.new(type_name: type_name, method_name: member.name)
                    else
                      raise
                    end
      index.add_method_declaration(method_name, member)
    end
    if member.is_a?(RBS::AST::Members::AttrWriter) || member.is_a?(RBS::AST::Members::AttrAccessor)
      method_name = case member.kind
                    when :instance
                      InstanceMethodName.new(type_name: type_name, method_name: "#{member.name}=".to_sym)
                    when :singleton
                      SingletonMethodName.new(type_name: type_name, method_name: "#{member.name}=".to_sym)
                    else
                      raise
                    end
      index.add_method_declaration(method_name, member)
    end
  when RBS::AST::Members::InstanceVariable, RBS::AST::Members::ClassVariable, RBS::AST::Members::ClassInstanceVariable
    type_reference member.type, from: member
  when RBS::AST::Members::Include, RBS::AST::Members::Extend
    index.add_type_reference member.name, member
    member.args.each do |type|
      type_reference type, from: member
    end
  when RBS::AST::Members::Alias
    if member.instance?
      new_name = InstanceMethodName.new(type_name: type_name, method_name: member.new_name)
      index.add_method_declaration(new_name, member)
    end
    if member.singleton?
      new_name = SingletonMethodName.new(type_name: type_name, method_name: member.new_name)
      index.add_method_declaration(new_name, member)
    end
  end
end

def type_reference(type, from:)

def type_reference(type, from:)
  case type
  when RBS::Types::ClassInstance, RBS::Types::ClassSingleton, RBS::Types::Alias, RBS::Types::Interface
    index.add_type_reference(type.name, from)
  end
  type.each_type do |ty|
    type_reference ty, from: from
  end
end