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