diff options
| author | kjeremy <[email protected]> | 2019-11-18 23:08:39 +0000 |
|---|---|---|
| committer | Jeremy Kolb <[email protected]> | 2019-12-18 13:49:06 +0000 |
| commit | 7ec43ee07a26667bb1458990ec667f82670aff22 (patch) | |
| tree | f5af8c599ddd4d07ece0446fade974e607d62ff6 /crates | |
| parent | 242f0ae1d8e6766091a6050431c3d417a43a2a3e (diff) | |
WIP: See through Macros for SignatureHelp
Note: we meed to skip the trivia filter to make sure that
`covers!(call_info_bad_offset)` succeeds otherwise we exit call_info
too early.
Also the test doesn't pass: `FnCallNode::with_node` always detects
a MacroCall.
Diffstat (limited to 'crates')
| -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 | } |
