diff options
Diffstat (limited to 'crates/ra_ide/src/call_info.rs')
-rw-r--r-- | crates/ra_ide/src/call_info.rs | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index b3c323d38..2da9c4e76 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs | |||
@@ -1,22 +1,22 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use ra_db::SourceDatabase; | 3 | use hir::db::AstDatabase; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
5 | algo::ancestors_at_offset, | ||
6 | ast::{self, ArgListOwner}, | 5 | ast::{self, ArgListOwner}, |
7 | match_ast, AstNode, SyntaxNode, TextUnit, | 6 | match_ast, AstNode, SyntaxNode, |
8 | }; | 7 | }; |
9 | use test_utils::tested_by; | 8 | use test_utils::tested_by; |
10 | 9 | ||
11 | use crate::{db::RootDatabase, CallInfo, FilePosition, FunctionSignature}; | 10 | use crate::{db::RootDatabase, expand::descend_into_macros, CallInfo, FilePosition, FunctionSignature}; |
12 | 11 | ||
13 | /// Computes parameter information for the given call expression. | 12 | /// Computes parameter information for the given call expression. |
14 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { | 13 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { |
15 | let parse = db.parse(position.file_id); | 14 | let file = db.parse_or_expand(position.file_id.into())?; |
16 | let syntax = parse.tree().syntax().clone(); | 15 | let token = file.token_at_offset(position.offset).next()?; |
16 | let token = descend_into_macros(db, position.file_id, token); | ||
17 | 17 | ||
18 | // Find the calling expression and it's NameRef | 18 | // Find the calling expression and it's NameRef |
19 | let calling_node = FnCallNode::with_node(&syntax, position.offset)?; | 19 | let calling_node = FnCallNode::with_node(&token.value.parent())?; |
20 | let name_ref = calling_node.name_ref()?; | 20 | let name_ref = calling_node.name_ref()?; |
21 | let name_ref = hir::InFile::new(position.file_id.into(), name_ref.syntax()); | 21 | let name_ref = hir::InFile::new(position.file_id.into(), name_ref.syntax()); |
22 | 22 | ||
@@ -93,8 +93,8 @@ enum FnCallNode { | |||
93 | } | 93 | } |
94 | 94 | ||
95 | impl FnCallNode { | 95 | impl FnCallNode { |
96 | fn with_node(syntax: &SyntaxNode, offset: TextUnit) -> Option<FnCallNode> { | 96 | fn with_node(syntax: &SyntaxNode) -> Option<FnCallNode> { |
97 | ancestors_at_offset(syntax, offset).find_map(|node| { | 97 | syntax.ancestors().find_map(|node| { |
98 | match_ast! { | 98 | match_ast! { |
99 | match node { | 99 | match node { |
100 | ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, | 100 | ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, |
@@ -589,4 +589,25 @@ fn f() { | |||
589 | assert_eq!(info.label(), "foo!()"); | 589 | assert_eq!(info.label(), "foo!()"); |
590 | assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string())); | 590 | assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string())); |
591 | } | 591 | } |
592 | |||
593 | #[test] | ||
594 | fn fn_signature_for_call_in_macro() { | ||
595 | let info = call_info( | ||
596 | r#" | ||
597 | macro_rules! id { | ||
598 | ($($tt:tt)*) => { $($tt)* } | ||
599 | } | ||
600 | fn foo() { | ||
601 | |||
602 | } | ||
603 | id! { | ||
604 | fn bar() { | ||
605 | foo(<|>); | ||
606 | } | ||
607 | } | ||
608 | "#, | ||
609 | ); | ||
610 | |||
611 | assert_eq!(info.label(), "fn foo()"); | ||
612 | } | ||
592 | } | 613 | } |