Skip to content

Commit

Permalink
Merge pull request #538 from soutaro/csend-call
Browse files Browse the repository at this point in the history
Better send support in MethodCall
  • Loading branch information
soutaro committed Apr 23, 2022
2 parents 8fafe42 + 345c65a commit 4069856
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 2 deletions.
5 changes: 4 additions & 1 deletion lib/steep/server/lsp_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ def format_hover_content(content)
builder.push do |s|
case call
when TypeInference::MethodCall::Typed
s << "```rbs\n#{call.actual_method_type.to_s}\n```\n\n"
mt = call.actual_method_type.with(
type: call.actual_method_type.type.with(return_type: call.return_type)
)
s << "```rbs\n#{mt.to_s}\n```\n\n"
when TypeInference::MethodCall::Error
s << "```rbs\n( ??? ) -> #{call.return_type.to_s}\n```\n\n"
end
Expand Down
5 changes: 5 additions & 0 deletions lib/steep/type_construction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2910,6 +2910,11 @@ def type_send_interface(node, interface:, receiver:, receiver_type:, method_name
call = call.with_return_type(typing.type_of(node: arguments.last))
end
end

if node.type == :csend || ((node.type == :block || node.type == :numblock) && node.children[0].type == :csend)
optional_type = AST::Types::Union.build(types: [call.return_type, AST::Builtin.nil_type])
call = call.with_return_type(optional_type)
end
else
error = Diagnostic::Ruby::UnresolvedOverloading.new(
node: node,
Expand Down
2 changes: 1 addition & 1 deletion test/ruby_hover_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def test_method_call_csend
assert_equal [5, 7]...[5, 11], [content.location.line,content.location.column]...[content.location.last_line, content.location.last_column]
assert_instance_of TypeInference::MethodCall::Typed, content.method_call
assert_equal [MethodName("::Array#join")], content.method_call.method_decls.map(&:method_name)
assert_equal "::String", content.method_call.return_type.to_s
assert_equal "(::String | nil)", content.method_call.return_type.to_s
end
end
end
Expand Down
41 changes: 41 additions & 0 deletions test/server/lsp_formatter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,47 @@ def test_ruby_hover_method_call
Returns an Enumerator if no `replacement` and no block given.
Related: String#sub, String#sub!, String#gsub!.
EOM
end
end

def test_ruby_hover_method_call_csend
with_factory do
typing = type_check(<<RUBY)
""&.gsub(/foo/, "bar")
RUBY

call = typing.call_of(node: typing.source.node)

content = Services::HoverProvider::Ruby::MethodCallContent.new(
node: nil,
method_call: call,
location: nil
)

comment = Server::LSPFormatter.format_hover_content(content)
assert_equal <<EOM.chomp, comment
```rbs
((::Regexp | ::string), ::string) -> (::String | nil)
```
- `::String#gsub`
----
**::String#gsub**
```rbs
(::Regexp | ::string pattern, ::string replacement) -> ::String
```
Returns a copy of `self` with all occurrences of the given `pattern` replaced.
See [Substitution Methods](#class-String-label-Substitution+Methods).
Returns an Enumerator if no `replacement` and no block given.
Related: String#sub, String#sub!, String#gsub!.
EOM
end
Expand Down
1 change: 1 addition & 0 deletions test/type_construction_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3468,6 +3468,7 @@ def test_csend_unwrap

assert_equal parse_type("::Integer?"), pair.type
assert_equal parse_type("::Integer?"), pair.context.lvar_env[:z]
assert_equal parse_type("::Integer?"), typing.call_of(node: dig(source.node, 1, 1)).return_type
end
end
end
Expand Down

0 comments on commit 4069856

Please sign in to comment.