class Steep::Services::TypeNameCompletion

def each_outer_module(context = self.context, &block)

def each_outer_module(context = self.context, &block)
  if block
    if (parent, con = context)
      namespace = each_outer_module(parent, &block)
      case con
      when false
        namespace
      when RBS::TypeName
        ns = con.with_prefix(namespace).to_namespace
        yield(ns)
        ns
      end
    else
      yield(RBS::Namespace.root)
      RBS::Namespace.root
    end
  else
    enum_for :each_outer_module
  end
end

def each_type_name(&block)

def each_type_name(&block)
  if block
    env = self.env
    map.instance_eval do
      @map.each_key do |name|
        relative_name = RBS::TypeName.new(name: name, namespace: RBS::Namespace.empty)
        if absolute_name = resolve?(relative_name)
          if env.type_name?(absolute_name)
            # Yields only if the relative type name resolves to existing absolute type name
            yield relative_name
          end
        end
      end
    end
    env.class_decls.each_key(&block)
    env.class_alias_decls.each_key(&block)
    env.type_alias_decls.each_key(&block)
    env.interface_decls.each_key(&block)
  else
    enum_for :each_type_name
  end
end

def find_type_names(prefix)

def find_type_names(prefix)
  case prefix
  when Prefix::RawIdentPrefix
    each_type_name.filter do |type_name|
      type_name.split.any? {|sym| sym.to_s.downcase.include?(prefix.ident.downcase) }
    end
  when Prefix::NamespacedIdentPrefix
    absolute_namespace = type_name_resolver.resolve(prefix.namespace.to_type_name, context: context)&.to_namespace || prefix.namespace
    each_type_name.filter do|name|
      name.namespace == absolute_namespace &&
        name.name.to_s.downcase.include?(prefix.ident.downcase)
    end
  when Prefix::NamespacePrefix
    absolute_namespace = type_name_resolver.resolve(prefix.namespace.to_type_name, context: context)&.to_namespace || prefix.namespace
    each_type_name.filter {|name| name.namespace == absolute_namespace }
  else
    # Returns all of the accessible type names from the context
    namespaces = each_outer_module.to_set
    # Relative type name means a *use*d type name
    each_type_name.filter {|name| namespaces.include?(name.namespace) || !name.absolute? }
  end
end

def initialize(env:, context:, dirs:)

def initialize(env:, context:, dirs:)
  @env = env
  @context = context
  table = RBS::Environment::UseMap::Table.new()
  table.known_types.merge(env.class_decls.keys)
  table.known_types.merge(env.class_alias_decls.keys)
  table.known_types.merge(env.type_alias_decls.keys)
  table.known_types.merge(env.interface_decls.keys)
  table.compute_children
  @map = RBS::Environment::UseMap.new(table: table)
  dirs.each do |dir|
    dir.clauses.each do |clause|
      @map.build_map(clause)
    end
  end
  @type_name_resolver = RBS::Resolver::TypeNameResolver.new(env)
end

def resolve_name_in_context(name)

def resolve_name_in_context(name)
  if resolved_name = map.resolve?(name)
    return [resolved_name, name]
  end
  name.absolute? or raise
  name.namespace.path.reverse_each.inject(RBS::TypeName.new(namespace: RBS::Namespace.empty, name: name.name)) do |relative_name, component|
    if type_name_resolver.resolve(relative_name, context: context) == name
      return [name, relative_name]
    end
    RBS::TypeName.new(
      namespace: RBS::Namespace.new(path: [component, *relative_name.namespace.path], absolute: false),
      name: name.name
    )
  end
  if type_name_resolver.resolve(name.relative!, context: context) == name && !map.resolve?(name.relative!)
    [name, name.relative!]
  else
    [name, name]
  end
end