diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-12-18 16:44:35 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-12-18 16:44:35 +0000 |
commit | b63c7ecab960ab4478b28bb3ea2b4f9a2e78a00f (patch) | |
tree | 9c1b5996fa17d279e049b80f65bd23e6c24c3c8b /crates/ra_ide/src | |
parent | 7ea578086712d0a6a81dc2d77a15d868f496deb0 (diff) | |
parent | 83dc5e79497bdded6143c812c97e009ddc783f1a (diff) |
Merge #2311
2311: See through Macros for SignatureHelp r=matklad a=kjeremy
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 which is obviously wrong.
Fixes #2310
Co-authored-by: kjeremy <[email protected]>
Co-authored-by: Jeremy Kolb <[email protected]>
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/call_info.rs | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index b3c323d38..2c2b6fa48 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs | |||
@@ -1,24 +1,26 @@ | |||
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::{ |
11 | db::RootDatabase, expand::descend_into_macros, CallInfo, FilePosition, FunctionSignature, | ||
12 | }; | ||
12 | 13 | ||
13 | /// Computes parameter information for the given call expression. | 14 | /// Computes parameter information for the given call expression. |
14 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { | 15 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { |
15 | let parse = db.parse(position.file_id); | 16 | let file = db.parse_or_expand(position.file_id.into())?; |
16 | let syntax = parse.tree().syntax().clone(); | 17 | let token = file.token_at_offset(position.offset).next()?; |
18 | let token = descend_into_macros(db, position.file_id, token); | ||
17 | 19 | ||
18 | // Find the calling expression and it's NameRef | 20 | // Find the calling expression and it's NameRef |
19 | let calling_node = FnCallNode::with_node(&syntax, position.offset)?; | 21 | let calling_node = FnCallNode::with_node(&token.value.parent())?; |
20 | let name_ref = calling_node.name_ref()?; | 22 | let name_ref = calling_node.name_ref()?; |
21 | let name_ref = hir::InFile::new(position.file_id.into(), name_ref.syntax()); | 23 | let name_ref = token.with_value(name_ref.syntax()); |
22 | 24 | ||
23 | let analyzer = hir::SourceAnalyzer::new(db, name_ref, None); | 25 | let analyzer = hir::SourceAnalyzer::new(db, name_ref, None); |
24 | let (mut call_info, has_self) = match &calling_node { | 26 | let (mut call_info, has_self) = match &calling_node { |
@@ -93,8 +95,8 @@ enum FnCallNode { | |||
93 | } | 95 | } |
94 | 96 | ||
95 | impl FnCallNode { | 97 | impl FnCallNode { |
96 | fn with_node(syntax: &SyntaxNode, offset: TextUnit) -> Option<FnCallNode> { | 98 | fn with_node(syntax: &SyntaxNode) -> Option<FnCallNode> { |
97 | ancestors_at_offset(syntax, offset).find_map(|node| { | 99 | syntax.ancestors().find_map(|node| { |
98 | match_ast! { | 100 | match_ast! { |
99 | match node { | 101 | match node { |
100 | ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, | 102 | ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) }, |
@@ -589,4 +591,25 @@ fn f() { | |||
589 | assert_eq!(info.label(), "foo!()"); | 591 | assert_eq!(info.label(), "foo!()"); |
590 | assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string())); | 592 | assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string())); |
591 | } | 593 | } |
594 | |||
595 | #[test] | ||
596 | fn fn_signature_for_call_in_macro() { | ||
597 | let info = call_info( | ||
598 | r#" | ||
599 | macro_rules! id { | ||
600 | ($($tt:tt)*) => { $($tt)* } | ||
601 | } | ||
602 | fn foo() { | ||
603 | |||
604 | } | ||
605 | id! { | ||
606 | fn bar() { | ||
607 | foo(<|>); | ||
608 | } | ||
609 | } | ||
610 | "#, | ||
611 | ); | ||
612 | |||
613 | assert_eq!(info.label(), "fn foo()"); | ||
614 | } | ||
592 | } | 615 | } |