diff options
| author | Anatol Ulrich <anatol.ulrich@ferrous-systems.com> | 2021-10-26 19:31:49 +0200 |
|---|---|---|
| committer | Anatol Ulrich <anatol.ulrich@ferrous-systems.com> | 2021-10-26 19:31:49 +0200 |
| commit | d8ed15b6a67bb4dd04ebc6548253b9eb553ad023 (patch) | |
| tree | 8795a66683c819989b802823ef5eff388b736a89 | |
| parent | ee1d6cffbfbecc99a70be77fe697af817ed6cfac (diff) | |
| download | rust-d8ed15b6a67bb4dd04ebc6548253b9eb553ad023.tar.gz rust-d8ed15b6a67bb4dd04ebc6548253b9eb553ad023.zip | |
fix: make `goto_declaration` multi-token mapping aware
| -rw-r--r-- | crates/ide/src/goto_declaration.rs | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/crates/ide/src/goto_declaration.rs b/crates/ide/src/goto_declaration.rs index 2c5a24b1d2e..c79015c7160 100644 --- a/crates/ide/src/goto_declaration.rs +++ b/crates/ide/src/goto_declaration.rs @@ -19,28 +19,35 @@ pub(crate) fn goto_declaration( let original_token = file .token_at_offset(position.offset) .find(|it| matches!(it.kind(), IDENT | T![self] | T![super] | T![crate]))?; - let token = sema.descend_into_macros_single(original_token.clone()); - let parent = token.parent()?; - let def = match_ast! { - match parent { - ast::NameRef(name_ref) => match NameRefClass::classify(&sema, &name_ref)? { - NameRefClass::Definition(it) => Some(it), - _ => None - }, - ast::Name(name) => match NameClass::classify(&sema, &name)? { - NameClass::Definition(it) => Some(it), - _ => None - }, - _ => None, - } - }; - match def? { - Definition::ModuleDef(hir::ModuleDef::Module(module)) => Some(RangeInfo::new( - original_token.text_range(), - vec![NavigationTarget::from_module_to_decl(db, module)], - )), - _ => None, - } + let range = original_token.text_range(); + let info: Vec<NavigationTarget> = sema + .descend_into_macros(original_token) + .iter() + .filter_map(|token| { + let parent = token.parent()?; + let def = match_ast! { + match parent { + ast::NameRef(name_ref) => match NameRefClass::classify(&sema, &name_ref)? { + NameRefClass::Definition(it) => Some(it), + _ => None + }, + ast::Name(name) => match NameClass::classify(&sema, &name)? { + NameClass::Definition(it) => Some(it), + _ => None + }, + _ => None + } + }; + match def? { + Definition::ModuleDef(hir::ModuleDef::Module(module)) => { + Some(NavigationTarget::from_module_to_decl(db, module)) + } + _ => None, + } + }) + .collect(); + + Some(RangeInfo::new(range, info)) } #[cfg(test)] |
