class RBS::DefinitionBuilder::AncestorBuilder

def instance_ancestors(type_name, building_ancestors: [])

def instance_ancestors(type_name, building_ancestors: [])
  as = instance_ancestors_cache[type_name] and return as
  entry = env.class_decls[type_name] or raise "Unknown name for instance_ancestors: #{type_name}"
  params = entry.type_params.each.map(&:name)
  args = entry.type_params.map do |type_param|
    Types::Variable.new(name: type_param.name, location: type_param.location)
  end
  self_ancestor = Definition::Ancestor::Instance.new(name: type_name, args: args, source: nil)
  RecursiveAncestorError.check!(self_ancestor,
                                ancestors: building_ancestors,
                                location: entry.primary.decl.location)
  building_ancestors.push self_ancestor
  one_ancestors = one_instance_ancestors(type_name)
  # @type var ancestors: Array[::RBS::Definition::Ancestor::t]
  ancestors = []
  case entry
  when Environment::ClassEntry
    if super_class = one_ancestors.super_class
      # @type var super_class: Definition::Ancestor::Instance
      super_name = super_class.name
      super_args = super_class.args
      super_ancestors =
        instance_ancestors(super_name, building_ancestors: building_ancestors)
          .apply(super_args, env: env, location: entry.primary.decl.super_class&.location)
      super_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: super_name, source: :super) }
      ancestors.unshift(*super_ancestors)
    end
  end
  if self_types = one_ancestors.self_types
    self_types.each do |mod|
      if mod.name.class?
        # Ensure there is no loop in ancestors chain
        instance_ancestors(mod.name, building_ancestors: building_ancestors)
      end
    end
  end
  if included_modules = one_ancestors.included_modules
    included_modules.each do |mod|
      name = mod.name
      arg_types = mod.args
      mod.source.is_a?(AST::Members::Include) or raise
      mod_ancestors =
        instance_ancestors(name, building_ancestors: building_ancestors)
          .apply(arg_types, env: env, location: mod.source.location)
      mod_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: name, source: mod.source) }
      ancestors.unshift(*mod_ancestors)
    end
  end
  ancestors.unshift(self_ancestor)
  if prepended_modules = one_ancestors.prepended_modules
    prepended_modules.each do |mod|
      name = mod.name
      arg_types = mod.args
      mod.source.is_a?(AST::Members::Prepend) or raise
      mod_ancestors =
        instance_ancestors(name, building_ancestors: building_ancestors)
          .apply(arg_types, env: env, location: mod.source.location)
      mod_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: name, source: mod.source) }
      ancestors.unshift(*mod_ancestors)
    end
  end
  building_ancestors.pop
  instance_ancestors_cache[type_name] = Definition::InstanceAncestors.new(
    type_name: type_name,
    params: params,
    ancestors: ancestors
  )
end