Skip to content

Commit 6cb33c3

Browse files
bors[bot]Veykril
andauthored
Merge #10273
10273: minor: Add multi-token mapping test for goto_definition r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents a435e49 + 11a17c8 commit 6cb33c3

File tree

1 file changed

+55
-10
lines changed

1 file changed

+55
-10
lines changed

crates/ide/src/goto_definition.rs

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use ide_db::{
88
helpers::{pick_best_token, try_resolve_derive_input_at},
99
RootDatabase,
1010
};
11+
use itertools::Itertools;
1112
use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T};
1213

1314
use crate::{
@@ -52,8 +53,8 @@ pub(crate) fn goto_definition(
5253
let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?;
5354
return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
5455
}
55-
56-
let navs = sema.descend_into_macros_many(original_token.clone())
56+
let navs = sema
57+
.descend_into_macros_many(original_token.clone())
5758
.into_iter()
5859
.filter_map(|token| {
5960
let parent = token.parent()?;
@@ -65,28 +66,34 @@ pub(crate) fn goto_definition(
6566
ast::Name(name) => {
6667
match NameClass::classify(&sema, &name)? {
6768
NameClass::Definition(def) | NameClass::ConstReference(def) => {
68-
try_find_trait_item_definition(sema.db, &def).unwrap_or_else(|| def_to_nav(sema.db, def))
69+
try_find_trait_item_definition(sema.db, &def)
70+
.unwrap_or_else(|| def_to_nav(sema.db, def))
6971
}
7072
NameClass::PatFieldShorthand { local_def, field_ref } => {
7173
local_and_field_to_nav(sema.db, local_def, field_ref)
7274
},
7375
}
7476
},
75-
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
76-
match name_class {
77-
NameClass::Definition(def) => def_to_nav(sema.db, def),
78-
_ => return None,
77+
ast::Lifetime(lt) => {
78+
match NameClass::classify_lifetime(&sema, &lt) {
79+
Some(name_class) => {
80+
match name_class {
81+
NameClass::Definition(def) => def_to_nav(sema.db, def),
82+
_ => return None,
83+
}
84+
}
85+
None => reference_definition(&sema, Either::Left(&lt)),
7986
}
80-
} else {
81-
reference_definition(&sema, Either::Left(&lt))
8287
},
83-
ast::TokenTree(tt) => try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?,
88+
ast::TokenTree(tt) =>
89+
try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?,
8490
_ => return None,
8591
}
8692
};
8793
Some(navs)
8894
})
8995
.flatten()
96+
.unique()
9097
.collect::<Vec<NavigationTarget>>();
9198

9299
Some(RangeInfo::new(original_token.text_range(), navs))
@@ -199,6 +206,7 @@ mod tests {
199206

200207
use crate::fixture;
201208

209+
#[track_caller]
202210
fn check(ra_fixture: &str) {
203211
let (analysis, position, expected) = fixture::annotations(ra_fixture);
204212
let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
@@ -1447,4 +1455,41 @@ struct Foo;
14471455
"#,
14481456
);
14491457
}
1458+
1459+
#[test]
1460+
fn goto_def_in_macro_multi() {
1461+
check(
1462+
r#"
1463+
struct Foo {
1464+
foo: ()
1465+
//^^^
1466+
}
1467+
macro_rules! foo {
1468+
($ident:ident) => {
1469+
fn $ident(Foo { $ident }: Foo) {}
1470+
}
1471+
}
1472+
foo!(foo$0);
1473+
//^^^
1474+
//^^^
1475+
"#,
1476+
);
1477+
check(
1478+
r#"
1479+
fn bar() {}
1480+
//^^^
1481+
struct bar;
1482+
//^^^
1483+
macro_rules! foo {
1484+
($ident:ident) => {
1485+
fn foo() {
1486+
let _: $ident = $ident;
1487+
}
1488+
}
1489+
}
1490+
1491+
foo!(bar$0);
1492+
"#,
1493+
);
1494+
}
14501495
}

0 commit comments

Comments
 (0)