From a0d55edc3873c7788ab2f91e394e53a5a77c16b8 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 27 Oct 2019 12:26:44 -0400 Subject: Be more precise with function signatures Fixes #2093 --- crates/ra_ide_api/src/call_info.rs | 40 ++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 7d18be483..c95133343 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -2,7 +2,7 @@ use ra_db::SourceDatabase; use ra_syntax::{ - algo::find_node_at_offset, + algo::ancestors_at_offset, ast::{self, ArgListOwner}, AstNode, SyntaxNode, TextUnit, }; @@ -82,13 +82,15 @@ enum FnCallNode { impl FnCallNode { fn with_node(syntax: &SyntaxNode, offset: TextUnit) -> Option { - if let Some(expr) = find_node_at_offset::(syntax, offset) { - return Some(FnCallNode::CallExpr(expr)); - } - if let Some(expr) = find_node_at_offset::(syntax, offset) { - return Some(FnCallNode::MethodCallExpr(expr)); - } - None + ancestors_at_offset(syntax, offset).find_map(|node| { + if let Some(expr) = ast::CallExpr::cast(node.clone()) { + Some(FnCallNode::CallExpr(expr)) + } else if let Some(expr) = ast::MethodCallExpr::cast(node.clone()) { + Some(FnCallNode::MethodCallExpr(expr)) + } else { + None + } + }) } fn name_ref(&self) -> Option { @@ -438,4 +440,26 @@ By default this method stops actor's `Context`."# let call_info = analysis.call_info(position).unwrap(); 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)"); + } } -- cgit v1.2.3