mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Go to definition for macros in #[macro_use(...)]
This commit is contained in:
parent
0e4902467f
commit
3b8801c3ac
1 changed files with 70 additions and 1 deletions
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
doc_links::token_as_doc_comment, navigation_target::ToNav, FilePosition, NavigationTarget,
|
doc_links::token_as_doc_comment, navigation_target::ToNav, FilePosition, NavigationTarget,
|
||||||
RangeInfo, TryToNav,
|
RangeInfo, TryToNav,
|
||||||
};
|
};
|
||||||
use hir::{AsAssocItem, AssocItem, DescendPreference, Semantics};
|
use hir::{AsAssocItem, AssocItem, DescendPreference, ModuleDef, Semantics};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{AnchoredPath, FileId, FileLoader},
|
base_db::{AnchoredPath, FileId, FileLoader},
|
||||||
defs::{Definition, IdentClass},
|
defs::{Definition, IdentClass},
|
||||||
|
@ -73,10 +73,15 @@ pub(crate) fn goto_definition(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|token| {
|
.filter_map(|token| {
|
||||||
let parent = token.parent()?;
|
let parent = token.parent()?;
|
||||||
|
|
||||||
if let Some(tt) = ast::TokenTree::cast(parent.clone()) {
|
if let Some(tt) = ast::TokenTree::cast(parent.clone()) {
|
||||||
if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), file_id) {
|
if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), file_id) {
|
||||||
return Some(vec![x]);
|
return Some(vec![x]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(x) = try_lookup_macro_def_in_macro_use(sema, token.clone()) {
|
||||||
|
return Some(vec![x]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(
|
Some(
|
||||||
IdentClass::classify_node(sema, &parent)?
|
IdentClass::classify_node(sema, &parent)?
|
||||||
|
@ -140,6 +145,27 @@ fn try_lookup_include_path(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_lookup_macro_def_in_macro_use(
|
||||||
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
|
token: SyntaxToken,
|
||||||
|
) -> Option<NavigationTarget> {
|
||||||
|
let extern_crate = token.parent()?.ancestors().find_map(ast::ExternCrate::cast)?;
|
||||||
|
let extern_crate = sema.to_def(&extern_crate)?;
|
||||||
|
let krate = extern_crate.resolved_crate(sema.db)?;
|
||||||
|
|
||||||
|
for mod_def in krate.root_module().declarations(sema.db) {
|
||||||
|
if let ModuleDef::Macro(mac) = mod_def {
|
||||||
|
if mac.name(sema.db).as_str() == Some(token.text()) {
|
||||||
|
if let Some(nav) = mac.try_to_nav(sema.db) {
|
||||||
|
return Some(nav.call_site);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// finds the trait definition of an impl'd item, except function
|
/// finds the trait definition of an impl'd item, except function
|
||||||
/// e.g.
|
/// e.g.
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -2077,6 +2103,49 @@ fn test() {
|
||||||
let a = "world";
|
let a = "world";
|
||||||
// ^
|
// ^
|
||||||
format_args!("hello {a$0}");
|
format_args!("hello {a$0}");
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn goto_macro_def_from_macro_use() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- /main.rs crate:main deps:mac
|
||||||
|
#[macro_use(foo$0)]
|
||||||
|
extern crate mac;
|
||||||
|
|
||||||
|
//- /mac.rs crate:mac
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! foo {
|
||||||
|
//^^^
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- /main.rs crate:main deps:mac
|
||||||
|
#[macro_use(foo, bar$0, baz)]
|
||||||
|
extern crate mac;
|
||||||
|
|
||||||
|
//- /mac.rs crate:mac
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! foo {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! bar {
|
||||||
|
//^^^
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! baz {
|
||||||
|
() => {};
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue