Be more precise with function signatures

Fixes #2093
This commit is contained in:
Jeremy Kolb 2019-10-27 12:26:44 -04:00
parent ad950830d0
commit a0d55edc38

View File

@ -2,7 +2,7 @@
use ra_db::SourceDatabase; use ra_db::SourceDatabase;
use ra_syntax::{ use ra_syntax::{
algo::find_node_at_offset, algo::ancestors_at_offset,
ast::{self, ArgListOwner}, ast::{self, ArgListOwner},
AstNode, SyntaxNode, TextUnit, AstNode, SyntaxNode, TextUnit,
}; };
@ -82,13 +82,15 @@ enum FnCallNode {
impl FnCallNode { impl FnCallNode {
fn with_node(syntax: &SyntaxNode, offset: TextUnit) -> Option<FnCallNode> { fn with_node(syntax: &SyntaxNode, offset: TextUnit) -> Option<FnCallNode> {
if let Some(expr) = find_node_at_offset::<ast::CallExpr>(syntax, offset) { ancestors_at_offset(syntax, offset).find_map(|node| {
return Some(FnCallNode::CallExpr(expr)); if let Some(expr) = ast::CallExpr::cast(node.clone()) {
} Some(FnCallNode::CallExpr(expr))
if let Some(expr) = find_node_at_offset::<ast::MethodCallExpr>(syntax, offset) { } else if let Some(expr) = ast::MethodCallExpr::cast(node.clone()) {
return Some(FnCallNode::MethodCallExpr(expr)); Some(FnCallNode::MethodCallExpr(expr))
} } else {
None None
}
})
} }
fn name_ref(&self) -> Option<ast::NameRef> { fn name_ref(&self) -> Option<ast::NameRef> {
@ -438,4 +440,26 @@ fn call_info_bad_offset() {
let call_info = analysis.call_info(position).unwrap(); let call_info = analysis.call_info(position).unwrap();
assert!(call_info.is_none()); assert!(call_info.is_none());
} }
#[test]
fn test_nested_method_in_lamba() {
let info = call_info(
r#"struct Foo;
impl Foo {
fn bar(&self, _: u32) { }
}
fn bar(_: u32) { }
fn main() {
let foo = Foo;
std::thread::spawn(move || foo.bar(<|>));
}"#,
);
assert_eq!(info.parameters(), ["&self", "_: u32"]);
assert_eq!(info.active_parameter, Some(1));
assert_eq!(info.label(), "fn bar(&self, _: u32)");
}
} }