diff options
author | Lukas Wirth <[email protected]> | 2021-03-21 19:08:08 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-03-23 10:32:10 +0000 |
commit | bad4e48672f928644457cece3b7e21dd78ea1e9b (patch) | |
tree | ae9a17f4f08b05204b78a5d015ff7ece1305e88d | |
parent | 1efd220f2f844596dd22bfd73a8a0c596354be38 (diff) |
Set up a search scope when searching for mbe macro references
-rw-r--r-- | crates/hir/src/lib.rs | 5 | ||||
-rw-r--r-- | crates/ide/src/references.rs | 30 | ||||
-rw-r--r-- | crates/ide_db/src/search.rs | 25 |
3 files changed, 56 insertions, 4 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 68f4551c0..ea0a60961 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -1150,6 +1150,11 @@ impl MacroDef { | |||
1150 | // FIXME: wrong for `ProcMacro` | 1150 | // FIXME: wrong for `ProcMacro` |
1151 | matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..)) | 1151 | matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..)) |
1152 | } | 1152 | } |
1153 | |||
1154 | /// Indicate it is a declarative macro | ||
1155 | pub fn is_declarative(&self) -> bool { | ||
1156 | matches!(self.id.kind, MacroDefKind::Declarative(..)) | ||
1157 | } | ||
1153 | } | 1158 | } |
1154 | 1159 | ||
1155 | /// Invariant: `inner.as_assoc_item(db).is_some()` | 1160 | /// Invariant: `inner.as_assoc_item(db).is_some()` |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 379674530..95ed8a045 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -1294,4 +1294,34 @@ pub use level1::Foo; | |||
1294 | "#]], | 1294 | "#]], |
1295 | ); | 1295 | ); |
1296 | } | 1296 | } |
1297 | |||
1298 | #[test] | ||
1299 | fn test_decl_macro_references() { | ||
1300 | check( | ||
1301 | r#" | ||
1302 | //- /lib.rs crate:lib | ||
1303 | #[macro_use] | ||
1304 | mod qux; | ||
1305 | mod bar; | ||
1306 | |||
1307 | pub use self::foo; | ||
1308 | //- /qux.rs | ||
1309 | #[macro_export] | ||
1310 | macro_rules! foo$0 { | ||
1311 | () => {struct Foo;}; | ||
1312 | } | ||
1313 | //- /bar.rs | ||
1314 | foo!(); | ||
1315 | //- /other.rs crate:other deps:lib new_source_root: | ||
1316 | lib::foo!(); | ||
1317 | "#, | ||
1318 | expect![[r#" | ||
1319 | foo Macro FileId(1) 0..61 29..32 | ||
1320 | |||
1321 | FileId(0) 46..49 | ||
1322 | FileId(2) 0..3 | ||
1323 | FileId(3) 5..8 | ||
1324 | "#]], | ||
1325 | ); | ||
1326 | } | ||
1297 | } | 1327 | } |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 8e93de277..5fdcb13cf 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -7,7 +7,7 @@ | |||
7 | use std::{convert::TryInto, mem}; | 7 | use std::{convert::TryInto, mem}; |
8 | 8 | ||
9 | use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt}; | 9 | use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt}; |
10 | use hir::{DefWithBody, HasSource, Module, ModuleSource, Semantics, Visibility}; | 10 | use hir::{DefWithBody, HasAttrs, HasSource, Module, ModuleSource, Semantics, Visibility}; |
11 | use once_cell::unsync::Lazy; | 11 | use once_cell::unsync::Lazy; |
12 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
13 | use syntax::{ast, match_ast, AstNode, TextRange, TextSize}; | 13 | use syntax::{ast, match_ast, AstNode, TextRange, TextSize}; |
@@ -244,9 +244,8 @@ impl Definition { | |||
244 | return SearchScope::new(res); | 244 | return SearchScope::new(res); |
245 | } | 245 | } |
246 | 246 | ||
247 | if let Some(Visibility::Public) = vis { | 247 | let rev_dep_scope = || { |
248 | let mut res = FxHashMap::default(); | 248 | let mut res = FxHashMap::default(); |
249 | |||
250 | let krate = module.krate(); | 249 | let krate = module.krate(); |
251 | for rev_dep in krate.transitive_reverse_dependencies(db) { | 250 | for rev_dep in krate.transitive_reverse_dependencies(db) { |
252 | let root_file = rev_dep.root_file(db); | 251 | let root_file = rev_dep.root_file(db); |
@@ -254,7 +253,25 @@ impl Definition { | |||
254 | let source_root = db.source_root(source_root_id); | 253 | let source_root = db.source_root(source_root_id); |
255 | res.extend(source_root.iter().map(|id| (id, None))); | 254 | res.extend(source_root.iter().map(|id| (id, None))); |
256 | } | 255 | } |
257 | return SearchScope::new(res); | 256 | SearchScope::new(res) |
257 | }; | ||
258 | |||
259 | if let Definition::Macro(macro_def) = self { | ||
260 | if macro_def.is_declarative() { | ||
261 | return if macro_def.attrs(db).by_key("macro_export").exists() { | ||
262 | rev_dep_scope() | ||
263 | } else { | ||
264 | let source_root_id = db.file_source_root(file_id); | ||
265 | let source_root = db.source_root(source_root_id); | ||
266 | SearchScope::new( | ||
267 | source_root.iter().map(|id| (id, None)).collect::<FxHashMap<_, _>>(), | ||
268 | ) | ||
269 | }; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | if let Some(Visibility::Public) = vis { | ||
274 | return rev_dep_scope(); | ||
258 | } | 275 | } |
259 | 276 | ||
260 | let mut res = FxHashMap::default(); | 277 | let mut res = FxHashMap::default(); |