Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide_db/src/symbol_index.rs')
| -rw-r--r-- | crates/ide_db/src/symbol_index.rs | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 3a0dfd066c..53fa3f0881 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -32,10 +32,12 @@ use base_db::{ salsa::{self, ParallelDatabase}, CrateId, FileId, FileRange, SourceDatabaseExt, SourceRootId, Upcast, }; +use either::Either; use fst::{self, Streamer}; use hir::{ - db::DefDatabase, AdtId, AssocContainerId, AssocItemId, AssocItemLoc, DefHasSource, - DefWithBodyId, HirFileId, ImplId, InFile, ItemLoc, ItemTreeNode, Lookup, ModuleDefId, ModuleId, + db::{DefDatabase, HirDatabase}, + AdtId, AssocContainerId, AssocItemId, AssocItemLoc, DefHasSource, DefWithBodyId, HasSource, + HirFileId, ImplId, InFile, ItemLoc, ItemTreeNode, Lookup, MacroDef, ModuleDefId, ModuleId, Semantics, TraitId, }; use rayon::prelude::*; @@ -94,7 +96,7 @@ impl Query { } #[salsa::query_group(SymbolsDatabaseStorage)] -pub trait SymbolsDatabase: hir::db::HirDatabase + SourceDatabaseExt { +pub trait SymbolsDatabase: HirDatabase + SourceDatabaseExt + Upcast<dyn HirDatabase> { fn module_symbols(&self, module_id: ModuleId) -> Arc<SymbolIndex>; fn library_symbols(&self) -> Arc<FxHashMap<SourceRootId, SymbolIndex>>; /// The set of "local" (that is, from the current workspace) roots. @@ -129,7 +131,7 @@ fn library_symbols(db: &dyn SymbolsDatabase) -> Arc<FxHashMap<SourceRootId, Symb } fn module_symbols(db: &dyn SymbolsDatabase, module_id: ModuleId) -> Arc<SymbolIndex> { - let symbols = SymbolCollector::collect(db.upcast(), module_id); + let symbols = SymbolCollector::collect(db, module_id); Arc::new(SymbolIndex::new(symbols)) } @@ -205,10 +207,6 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec<Fil .map_with(snap, |snap, &module_id| snap.0.module_symbols(module_id)) .collect(); - for i in &buf { - dbg!(&i.symbols); - } - let buf = buf.iter().map(|it| &**it).collect::<Vec<_>>(); query.search(&buf) } @@ -446,14 +444,16 @@ enum SymbolCollectorWorkItem { } struct SymbolCollector<'a> { - db: &'a dyn DefDatabase, + db: &'a dyn SymbolsDatabase, symbols: Vec<FileSymbol>, work: Vec<SymbolCollectorWorkItem>, container_name_stack: Vec<SmolStr>, } +/// Given a [`ModuleId`] and a [`SymbolsDatabase`], use the DefMap for the module's crate to collect all symbols that should be +/// indexed for the given module. impl<'a> SymbolCollector<'a> { - fn collect(db: &dyn DefDatabase, module_id: ModuleId) -> Vec<FileSymbol> { + fn collect(db: &dyn SymbolsDatabase, module_id: ModuleId) -> Vec<FileSymbol> { let mut symbol_collector = SymbolCollector { db, symbols: Default::default(), @@ -486,10 +486,12 @@ impl<'a> SymbolCollector<'a> { } fn collect_from_module(&mut self, module_id: ModuleId) { - let def_map = module_id.def_map(self.db); + let def_map = module_id.def_map(self.db.upcast()); let module_data = &def_map[module_id.local_id]; let scope = &module_data.scope; + dbg!(scope); + for module_def_id in scope.declarations() { match module_def_id { ModuleDefId::ModuleId(id) => self.push_module(id), @@ -531,14 +533,23 @@ impl<'a> SymbolCollector<'a> { self.work.push(SymbolCollectorWorkItem::Body { body: const_id.into() }) } - // todo: collect macros. + // Collect legacy macros from the root module only: + if module_data.parent.is_none() { + for (_, macro_def_id) in scope.legacy_macros() { + self.push_decl_macro(macro_def_id.into()); + } + } + + for macro_def_id in scope.macro_declarations() { + self.push_decl_macro(macro_def_id.into()); + } } fn collect_from_body(&mut self, body_id: DefWithBodyId) { let body = self.db.body(body_id); // Descend into the blocks and enqueue collection of all modules within. - for (_, def_map) in body.blocks(self.db) { + for (_, def_map) in body.blocks(self.db.upcast()) { for (id, _) in def_map.modules() { self.work.push(SymbolCollectorWorkItem::Module { module_id: def_map.module_id(id), @@ -578,15 +589,15 @@ impl<'a> SymbolCollector<'a> { fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option<SmolStr> { match body_id { - DefWithBodyId::FunctionId(id) => { - Some(id.lookup(self.db).source(self.db).value.name()?.text().into()) - } - DefWithBodyId::StaticId(id) => { - Some(id.lookup(self.db).source(self.db).value.name()?.text().into()) - } - DefWithBodyId::ConstId(id) => { - Some(id.lookup(self.db).source(self.db).value.name()?.text().into()) - } + DefWithBodyId::FunctionId(id) => Some( + id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), + ), + DefWithBodyId::StaticId(id) => Some( + id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), + ), + DefWithBodyId::ConstId(id) => Some( + id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(), + ), } } @@ -624,11 +635,11 @@ impl<'a> SymbolCollector<'a> { } self.push_file_symbol(|s| { - let loc = id.lookup(s.db); - let source = loc.source(s.db); + let loc = id.lookup(s.db.upcast()); + let source = loc.source(s.db.upcast()); let name_node = source.value.name()?; let container_name = - container_name(s.db, loc.container).or_else(|| s.current_container_name()); + container_name(s.db.upcast(), loc.container).or_else(|| s.current_container_name()); Some(FileSymbol { name: name_node.text().into(), @@ -650,8 +661,8 @@ impl<'a> SymbolCollector<'a> { <T as ItemTreeNode>::Source: HasName, { self.push_file_symbol(|s| { - let loc = id.lookup(s.db); - let source = loc.source(s.db); + let loc = id.lookup(s.db.upcast()); + let source = loc.source(s.db.upcast()); let name_node = source.value.name()?; Some(FileSymbol { @@ -669,7 +680,7 @@ impl<'a> SymbolCollector<'a> { fn push_module(&mut self, module_id: ModuleId) { self.push_file_symbol(|s| { - let def_map = module_id.def_map(s.db); + let def_map = module_id.def_map(s.db.upcast()); let module_data = &def_map[module_id.local_id]; let declaration = module_data.origin.declaration()?; let module = declaration.to_node(s.db.upcast()); @@ -688,6 +699,29 @@ impl<'a> SymbolCollector<'a> { }) } + pub(crate) fn push_decl_macro(&mut self, macro_def: MacroDef) { + self.push_file_symbol(|s| { + let name = macro_def.name(s.db.upcast())?.as_text()?; + let source = macro_def.source(s.db.upcast())?; + + let (ptr, name_ptr) = match source.value { + Either::Left(m) => { + (SyntaxNodePtr::new(m.syntax()), SyntaxNodePtr::new(m.name()?.syntax())) + } + Either::Right(f) => { + (SyntaxNodePtr::new(f.syntax()), SyntaxNodePtr::new(f.name()?.syntax())) + } + }; + + Some(FileSymbol { + name, + kind: FileSymbolKind::Macro, + container_name: s.current_container_name(), + loc: DeclarationLocation { hir_file_id: source.file_id, name_ptr, ptr }, + }) + }) + } + fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option<FileSymbol>) { if let Some(file_symbol) = f(self) { self.symbols.push(file_symbol); |