Unnamed repository; edit this file 'description' to name the repository.
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]>
bors[bot] 2021-09-18
parent a435e49 · parent 11a17c8 · commit 6cb33c3
-rw-r--r--crates/ide/src/goto_definition.rs65
1 files changed, 55 insertions, 10 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index e8aee21f67..b2d0fead87 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -8,6 +8,7 @@ use ide_db::{
helpers::{pick_best_token, try_resolve_derive_input_at},
RootDatabase,
};
+use itertools::Itertools;
use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T};
use crate::{
@@ -52,8 +53,8 @@ pub(crate) fn goto_definition(
let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?;
return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
}
-
- let navs = sema.descend_into_macros_many(original_token.clone())
+ let navs = sema
+ .descend_into_macros_many(original_token.clone())
.into_iter()
.filter_map(|token| {
let parent = token.parent()?;
@@ -65,28 +66,34 @@ pub(crate) fn goto_definition(
ast::Name(name) => {
match NameClass::classify(&sema, &name)? {
NameClass::Definition(def) | NameClass::ConstReference(def) => {
- try_find_trait_item_definition(sema.db, &def).unwrap_or_else(|| def_to_nav(sema.db, def))
+ try_find_trait_item_definition(sema.db, &def)
+ .unwrap_or_else(|| def_to_nav(sema.db, def))
}
NameClass::PatFieldShorthand { local_def, field_ref } => {
local_and_field_to_nav(sema.db, local_def, field_ref)
},
}
},
- ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
- match name_class {
- NameClass::Definition(def) => def_to_nav(sema.db, def),
- _ => return None,
+ ast::Lifetime(lt) => {
+ match NameClass::classify_lifetime(&sema, &lt) {
+ Some(name_class) => {
+ match name_class {
+ NameClass::Definition(def) => def_to_nav(sema.db, def),
+ _ => return None,
+ }
+ }
+ None => reference_definition(&sema, Either::Left(&lt)),
}
- } else {
- reference_definition(&sema, Either::Left(&lt))
},
- ast::TokenTree(tt) => try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?,
+ ast::TokenTree(tt) =>
+ try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?,
_ => return None,
}
};
Some(navs)
})
.flatten()
+ .unique()
.collect::<Vec<NavigationTarget>>();
Some(RangeInfo::new(original_token.text_range(), navs))
@@ -199,6 +206,7 @@ mod tests {
use crate::fixture;
+ #[track_caller]
fn check(ra_fixture: &str) {
let (analysis, position, expected) = fixture::annotations(ra_fixture);
let navs = analysis.goto_definition(position).unwrap().expect("no definition found").info;
@@ -1447,4 +1455,41 @@ struct Foo;
"#,
);
}
+
+ #[test]
+ fn goto_def_in_macro_multi() {
+ check(
+ r#"
+struct Foo {
+ foo: ()
+ //^^^
+}
+macro_rules! foo {
+ ($ident:ident) => {
+ fn $ident(Foo { $ident }: Foo) {}
+ }
+}
+foo!(foo$0);
+ //^^^
+ //^^^
+"#,
+ );
+ check(
+ r#"
+fn bar() {}
+ //^^^
+struct bar;
+ //^^^
+macro_rules! foo {
+ ($ident:ident) => {
+ fn foo() {
+ let _: $ident = $ident;
+ }
+ }
+}
+
+foo!(bar$0);
+"#,
+ );
+ }
}