Set up a search scope when searching for mbe macro references

This commit is contained in:
Lukas Wirth 2021-03-21 20:08:08 +01:00
parent 1efd220f2f
commit bad4e48672
3 changed files with 56 additions and 4 deletions

View File

@ -1150,6 +1150,11 @@ pub fn is_derive_macro(&self) -> bool {
// FIXME: wrong for `ProcMacro`
matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..))
}
/// Indicate it is a declarative macro
pub fn is_declarative(&self) -> bool {
matches!(self.id.kind, MacroDefKind::Declarative(..))
}
}
/// Invariant: `inner.as_assoc_item(db).is_some()`

View File

@ -1294,4 +1294,34 @@ fn test_transitive() {
"#]],
);
}
#[test]
fn test_decl_macro_references() {
check(
r#"
//- /lib.rs crate:lib
#[macro_use]
mod qux;
mod bar;
pub use self::foo;
//- /qux.rs
#[macro_export]
macro_rules! foo$0 {
() => {struct Foo;};
}
//- /bar.rs
foo!();
//- /other.rs crate:other deps:lib new_source_root:
lib::foo!();
"#,
expect![[r#"
foo Macro FileId(1) 0..61 29..32
FileId(0) 46..49
FileId(2) 0..3
FileId(3) 5..8
"#]],
);
}
}

View File

@ -7,7 +7,7 @@
use std::{convert::TryInto, mem};
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility};
use hir::{DefWithBody, HasAttrs, HasSource, Module, ModuleSource, Semantics, Visibility};
use once_cell::unsync::Lazy;
use rustc_hash::FxHashMap;
use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
@ -244,9 +244,8 @@ fn search_scope(&self, db: &RootDatabase) -> SearchScope {
return SearchScope::new(res);
}
if let Some(Visibility::Public) = vis {
let rev_dep_scope = || {
let mut res = FxHashMap::default();
let krate = module.krate();
for rev_dep in krate.transitive_reverse_dependencies(db) {
let root_file = rev_dep.root_file(db);
@ -254,7 +253,25 @@ fn search_scope(&self, db: &RootDatabase) -> SearchScope {
let source_root = db.source_root(source_root_id);
res.extend(source_root.iter().map(|id| (id, None)));
}
return SearchScope::new(res);
SearchScope::new(res)
};
if let Definition::Macro(macro_def) = self {
if macro_def.is_declarative() {
return if macro_def.attrs(db).by_key("macro_export").exists() {
rev_dep_scope()
} else {
let source_root_id = db.file_source_root(file_id);
let source_root = db.source_root(source_root_id);
SearchScope::new(
source_root.iter().map(|id| (id, None)).collect::<FxHashMap<_, _>>(),
)
};
}
}
if let Some(Visibility::Public) = vis {
return rev_dep_scope();
}
let mut res = FxHashMap::default();