diff --git a/lib/ruby_indexer/lib/ruby_indexer/entry.rb b/lib/ruby_indexer/lib/ruby_indexer/entry.rb index 1e4cc445c..13d663a27 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/entry.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/entry.rb @@ -492,7 +492,7 @@ class UnresolvedMethodAlias < Entry old_name: String, owner: T.nilable(Entry::Namespace), file_path: String, - location: Prism::Location, + location: T.any(Prism::Location, RubyIndexer::Location), comments: T::Array[String], ).void end diff --git a/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb b/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb index 713175bc8..57f6c2da8 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb @@ -69,6 +69,8 @@ def handle_class_or_module_declaration(declaration, pathname) handle_method(member, entry) when RBS::AST::Declarations::Constant handle_constant(member, nesting, file_path) + when RBS::AST::Members::Alias # NOTE: This is a signature alias, not a Ruby method alias + handle_signature_alias(member, entry) end end end @@ -243,5 +245,22 @@ def handle_constant(declaration, nesting, file_path) Array(declaration.comment&.string), )) end + + sig { params(member: RBS::AST::Members::Alias, owner_entry: Entry::Namespace).void } + def handle_signature_alias(member, owner_entry) + file_path = member.location.buffer.name + comments = Array(member.comment&.string) + + entry = Entry::UnresolvedMethodAlias.new( + member.new_name.to_s, + member.old_name.to_s, + owner_entry, + file_path, + to_ruby_indexer_location(member.location), + comments, + ) + + @index.add(entry) + end end end diff --git a/lib/ruby_indexer/test/rbs_indexer_test.rb b/lib/ruby_indexer/test/rbs_indexer_test.rb index 45471636a..f47ab52a2 100644 --- a/lib/ruby_indexer/test/rbs_indexer_test.rb +++ b/lib/ruby_indexer/test/rbs_indexer_test.rb @@ -331,6 +331,23 @@ def self?.open: (String name, ?String mode, ?Integer perm) -> IO? assert_kind_of(Entry::BlockParameter, parameters[3]) end + def test_signature_alias + # In RBS, an alias means that two methods have the same signature. It does not mean the same thing as a Ruby + # alias. + any_entries = @index["any?"] + + assert_equal(["Array", "Enumerable", "Hash"], any_entries.map { _1.owner.name }) + + entry = any_entries.find { |entry| entry.owner.name == "Array" } + + assert_kind_of(RubyIndexer::Entry::UnresolvedMethodAlias, entry) + assert_equal("any?", entry.name) + assert_equal("all?", entry.old_name) + assert_equal("Array", entry.owner.name) + assert(entry.file_path.end_with?("core/array.rbs")) + assert_includes(entry.comments[0], "Returns `true` if any element of `self` meets a given criterion.") + end + private def parse_rbs_methods(rbs, method_name)