# typed: strict # frozen_string_literal: true module RubyLsp module Requests # The [type hierarchy supertypes # request](https://microsoft.github.io/language-server-protocol/specification#typeHierarchy_supertypes) # displays the list of ancestors (supertypes) for the selected type. class TypeHierarchySupertypes < Request extend T::Sig include Support::Common sig { params(index: RubyIndexer::Index, item: T::Hash[Symbol, T.untyped]).void } def initialize(index, item) super() @index = index @item = item end sig { override.returns(T.nilable(T::Array[Interface::TypeHierarchyItem])) } def perform name = @item[:name] entries = @index[name] parents = T.let(Set.new, T::Set[RubyIndexer::Entry::Namespace]) return unless entries&.any? entries.each do |entry| next unless entry.is_a?(RubyIndexer::Entry::Namespace) if entry.is_a?(RubyIndexer::Entry::Class) parent_class_name = entry.parent_class if parent_class_name resolved_parent_entries = @index.resolve(parent_class_name, entry.nesting) resolved_parent_entries&.each do |entry| next unless entry.is_a?(RubyIndexer::Entry::Class) parents << entry end end end entry.mixin_operations.each do |mixin_operation| mixin_name = mixin_operation.module_name resolved_mixin_entries = @index.resolve(mixin_name, entry.nesting) next unless resolved_mixin_entries resolved_mixin_entries.each do |mixin_entry| next unless mixin_entry.is_a?(RubyIndexer::Entry::Module) parents << mixin_entry end end end parents.map { |entry| hierarchy_item(entry) } end private sig { params(entry: RubyIndexer::Entry).returns(Interface::TypeHierarchyItem) } def hierarchy_item(entry) Interface::TypeHierarchyItem.new( name: entry.name, kind: kind_for_entry(entry), uri: URI::Generic.from_path(path: entry.file_path).to_s, range: range_from_location(entry.location), selection_range: range_from_location(entry.name_location), detail: entry.file_name, ) end end end end