Skip to content

Commit 71964bf

Browse files
committed
Add recursive support in original_range
1 parent ae0aeb1 commit 71964bf

File tree

2 files changed

+60
-12
lines changed

2 files changed

+60
-12
lines changed

crates/ra_ide/src/expand.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
11
//! Utilities to work with files, produced by macros.
22
use std::iter::successors;
33

4-
use hir::{InFile, Origin};
4+
use hir::{db::AstDatabase, InFile, Origin};
55
use ra_db::FileId;
66
use ra_ide_db::RootDatabase;
7-
use ra_syntax::{ast, AstNode, SyntaxNode, SyntaxToken, TextRange};
7+
use ra_syntax::{
8+
algo::find_covering_element, ast, AstNode, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken,
9+
TextRange,
10+
};
811

912
use crate::FileRange;
1013

1114
pub(crate) fn original_range(db: &RootDatabase, node: InFile<&SyntaxNode>) -> FileRange {
12-
if let Some((range, Origin::Call)) = original_range_and_origin(db, node) {
13-
return range;
15+
let mut elem: InFile<SyntaxElement> = node.map(|n| n.clone().into());
16+
17+
while let Some((range, Origin::Call)) = original_range_and_origin(db, elem.as_ref()) {
18+
let original_file = range.file_id.original_file(db);
19+
20+
if range.file_id == original_file.into() {
21+
return FileRange { file_id: original_file, range: range.value };
22+
}
23+
24+
// Fail to mapping up more, return the original file range instead
25+
if elem.file_id == range.file_id {
26+
log::error!("Fail to mapping up more for {:?}", range);
27+
return FileRange { file_id: range.file_id.original_file(db), range: range.value };
28+
}
29+
30+
if let Some(root) = db.parse_or_expand(range.file_id) {
31+
let n = find_covering_element(&root, range.value);
32+
elem = range.with_value(n);
33+
} else {
34+
break;
35+
}
1436
}
1537

38+
// Fall back to whole macro call
1639
if let Some(expansion) = node.file_id.expansion_info(db) {
1740
if let Some(call_node) = expansion.call_node() {
1841
return FileRange {
@@ -27,14 +50,21 @@ pub(crate) fn original_range(db: &RootDatabase, node: InFile<&SyntaxNode>) -> Fi
2750

2851
fn original_range_and_origin(
2952
db: &RootDatabase,
30-
node: InFile<&SyntaxNode>,
31-
) -> Option<(FileRange, Origin)> {
32-
let expansion = node.file_id.expansion_info(db)?;
53+
elem: InFile<&SyntaxElement>,
54+
) -> Option<(InFile<TextRange>, Origin)> {
55+
let expansion = elem.file_id.expansion_info(db)?;
56+
57+
let node = match elem.as_ref().value {
58+
NodeOrToken::Node(it) => elem.with_value(it),
59+
NodeOrToken::Token(tt) => {
60+
let (tt, origin) = expansion.map_token_up(elem.with_value(tt))?;
61+
return Some((tt.with_value(tt.value.text_range()), origin));
62+
}
63+
};
3364

3465
// the input node has only one token ?
3566
let single = node.value.first_token()? == node.value.last_token()?;
3667

37-
// FIXME: We should handle recurside macro expansions
3868
let (range, origin) = node.value.descendants().find_map(|it| {
3969
let first = it.first_token()?;
4070
let last = it.last_token()?;
@@ -58,10 +88,7 @@ fn original_range_and_origin(
5888
))
5989
})?;
6090

61-
return Some((
62-
FileRange { file_id: range.file_id.original_file(db), range: range.value },
63-
origin,
64-
));
91+
return Some((range, origin));
6592

6693
fn union_range(a: TextRange, b: TextRange) -> TextRange {
6794
let start = a.start().min(b.start());

crates/ra_ide/src/hover.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,27 @@ fn func(foo: i32) { if true { <|>foo; }; }
754754
assert_eq!(hover_on, "bar")
755755
}
756756

757+
#[test]
758+
fn test_hover_through_expr_in_macro_recursive() {
759+
let hover_on = check_hover_result(
760+
"
761+
//- /lib.rs
762+
macro_rules! id_deep {
763+
($($tt:tt)*) => { $($tt)* }
764+
}
765+
macro_rules! id {
766+
($($tt:tt)*) => { id_deep!($($tt)*) }
767+
}
768+
fn foo(bar:u32) {
769+
let a = id!(ba<|>r);
770+
}
771+
",
772+
&["u32"],
773+
);
774+
775+
assert_eq!(hover_on, "bar")
776+
}
777+
757778
#[test]
758779
fn test_hover_non_ascii_space_doc() {
759780
check_hover_result(

0 commit comments

Comments
 (0)