From 865595288659fe596c920eaf7374c29fa1cddd3c Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:46:17 -0400 Subject: [PATCH] Use RBS to index Ruby core methods --- .../lib/ruby_indexer/rbs_indexer.rb | 34 +++++++++++++++++++ lib/ruby_indexer/test/rbs_indexer_test.rb | 14 ++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb b/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb index 0988621958..e670a51332 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb @@ -66,6 +66,11 @@ def handle_class_declaration(declaration, pathname) end @index << class_entry + declaration.members.each do |member| + next unless member.is_a?(RBS::AST::Members::MethodDefinition) + + handle_member(member, class_entry) + end end sig { params(declaration: RBS::AST::Declarations::Module, pathname: Pathname).void } @@ -76,8 +81,15 @@ def handle_module_declaration(declaration, pathname) comments = Array(declaration.comment&.string) class_entry = Entry::Module.new(nesting, file_path, location, comments) @index << class_entry + declaration.members.each do |member| + next unless member.is_a?(RBS::AST::Members::MethodDefinition) + + handle_member(member, class_entry) + end end + Array.new(1) + sig { params(rbs_location: RBS::Location).returns(RubyIndexer::Location) } def to_ruby_indexer_location(rbs_location) RubyIndexer::Location.new( @@ -87,5 +99,27 @@ def to_ruby_indexer_location(rbs_location) rbs_location.end_column, ) end + + sig { params(member: RBS::AST::Members::MethodDefinition, class_entry: T.any(Entry::Class, Entry::Module)).void } + def handle_member(member, class_entry) + name = member.name.name + file_path = member.location.buffer.name + location = to_ruby_indexer_location(member.location) + comments = Array(member.comment&.string) + parameters_node = nil + visibility = Entry::Visibility::PUBLIC + owner = class_entry + + klass = member.instance? ? Entry::InstanceMethod : Entry::SingletonMethod + entry = klass.new( + name, + file_path, + location, + comments, + parameters_node, + visibility, + owner) + @index << entry if 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 9007278ca1..da5a9a6e85 100644 --- a/lib/ruby_indexer/test/rbs_indexer_test.rb +++ b/lib/ruby_indexer/test/rbs_indexer_test.rb @@ -43,5 +43,19 @@ def test_index_core_modules assert_equal(0, entry.location.start_column) assert_operator(entry.location.end_column, :>, 0) end + + def test_index_methods + entries = @index["initialize"] + refute_nil(entries) + entry = entries.find { |entry| entry.owner.name == "Array" } + assert_match(%r{/gems/rbs-.*/core/array.rbs}, entry.file_path) + assert_equal("array.rbs", entry.file_name) + + # Using fixed positions would be fragile, so let's just check some basics. + assert_operator(entry.location.start_line, :>, 0) + assert_operator(entry.location.end_line, :>, entry.location.start_line) + assert_equal(2, entry.location.start_column) + assert_operator(entry.location.end_column, :>, 0) + end end end