Skip to content

Commit

Permalink
Indicate multiple signatures for Hover and Completion Resolve (#2415)
Browse files Browse the repository at this point in the history
* Indicate multiple signatures for Hover and Completion Resolve

* Extract common behaviour
  • Loading branch information
andyw8 authored Aug 8, 2024
1 parent d92ea6e commit b6ba7da
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 1 deletion.
23 changes: 23 additions & 0 deletions lib/ruby_indexer/lib/ruby_indexer/entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,19 @@ def decorated_parameters

"(#{first_signature.format})"
end

sig { returns(String) }
def formatted_signatures
overloads_count = signatures.size
case overloads_count
when 1
""
when 2
"\n(+1 overload)"
else
"\n(+#{overloads_count - 1} overloads)"
end
end
end

class Accessor < Member
Expand Down Expand Up @@ -542,6 +555,16 @@ def parameters
def decorated_parameters
@target.decorated_parameters
end

sig { returns(String) }
def formatted_signatures
@target.formatted_signatures
end

sig { returns(T::Array[Signature]) }
def signatures
@target.signatures
end
end

# Ruby doesn't support method overloading, so a method will have only one signature.
Expand Down
5 changes: 4 additions & 1 deletion lib/ruby_lsp/listeners/hover.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,10 @@ def handle_method_hover(message, inherited_only: false)
methods = @index.resolve_method(message, type.name, inherited_only: inherited_only)
return unless methods

title = "#{message}#{T.must(methods.first).decorated_parameters}"
first_method = T.must(methods.first)

title = "#{message}#{first_method.decorated_parameters}"
title << first_method.formatted_signatures

if type.is_a?(TypeInferrer::GuessedType)
title << "\n\nGuessed receiver: #{type.name}"
Expand Down
1 change: 1 addition & 0 deletions lib/ruby_lsp/requests/completion_resolve.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def perform

if first_entry.is_a?(RubyIndexer::Entry::Member)
label = +"#{label}#{first_entry.decorated_parameters}"
label << first_entry.formatted_signatures
end

guessed_type = @item.dig(:data, :guessed_type)
Expand Down
22 changes: 22 additions & 0 deletions test/requests/completion_resolve_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,28 @@ def bar
end
end

def test_indicates_signature_count_in_label_details
source = +<<~RUBY
String.try_convert
RUBY

with_server(source, stub_no_typechecker: true) do |server, _uri|
index = server.instance_variable_get(:@global_state).index
RubyIndexer::RBSIndexer.new(index).index_ruby_core
existing_item = {
label: "try_convert",
kind: RubyLsp::Constant::CompletionItemKind::METHOD,
data: { owner_name: "String::<Class:String>" },
}

server.process_message(id: 1, method: "completionItem/resolve", params: existing_item)

result = server.pop_response.response
assert_match("try_convert(object)", result[:documentation].value)
assert_match("(+2 overloads)", result[:documentation].value)
end
end

def test_completion_documentation_for_guessed_types
source = +<<~RUBY
class User
Expand Down
20 changes: 20 additions & 0 deletions test/requests/hover_expectations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,26 @@ def baz
end
end

def test_hover_for_methods_shows_overload_count
source = <<~RUBY
String.try_convert
RUBY

with_server(source) do |server, uri|
index = server.instance_variable_get(:@global_state).index
RubyIndexer::RBSIndexer.new(index).index_ruby_core
server.process_message(
id: 1,
method: "textDocument/hover",
params: { textDocument: { uri: uri }, position: { character: 8, line: 0 } },
)

contents = server.pop_response.response.contents.value
assert_match("try_convert(object)", contents)
assert_match("(+2 overloads)", contents)
end
end

def test_hover_for_singleton_methods
source = <<~RUBY
class Foo
Expand Down

0 comments on commit b6ba7da

Please sign in to comment.