aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorkjeremy <[email protected]>2019-11-18 23:08:39 +0000
committerJeremy Kolb <[email protected]>2019-12-18 13:49:06 +0000
commit7ec43ee07a26667bb1458990ec667f82670aff22 (patch)
treef5af8c599ddd4d07ece0446fade974e607d62ff6 /crates/ra_ide
parent242f0ae1d8e6766091a6050431c3d417a43a2a3e (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/ra_ide')
-rw-r--r--crates/ra_ide/src/call_info.rs39
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
3use ra_db::SourceDatabase; 3use hir::db::AstDatabase;
4use ra_syntax::{ 4use 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};
9use test_utils::tested_by; 8use test_utils::tested_by;
10 9
11use crate::{db::RootDatabase, CallInfo, FilePosition, FunctionSignature}; 10use 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.
14pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { 13pub(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
95impl FnCallNode { 95impl 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}