From 0447be7589445826a859ee6aa117e70c0bb179ef Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Sat, 27 Nov 2021 11:25:05 +0000 Subject: [PATCH 01/24] wip --- crates/hir/src/lib.rs | 20 ++-- crates/hir_def/src/nameres.rs | 2 +- crates/ide/src/navigation_target.rs | 10 +- crates/ide_db/src/items_locator.rs | 3 +- crates/ide_db/src/symbol_index.rs | 176 +++++++++++++++++++++++----- 5 files changed, 170 insertions(+), 41 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 3946f51642..afa773aaa4 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -40,16 +40,13 @@ use hir_def::{ adt::{ReprKind, VariantData}, body::{BodyDiagnostic, SyntheticSyntax}, expr::{BindingAnnotation, LabelId, Pat, PatId}, - item_tree::ItemTreeNode, lang_item::LangItemTarget, nameres, per_ns::PerNs, resolver::{HasResolver, Resolver}, - src::HasSource as _, - AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, - DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, - LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, - TypeParamId, UnionId, + AssocContainerId, AssocItemId, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, + FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, + StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, }; use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind}; use hir_ty::{ @@ -109,10 +106,19 @@ pub use { attr::{Attr, Attrs, AttrsWithOwner, Documentation}, find_path::PrefixKind, import_map, - nameres::ModuleSource, + item_scope::ItemScope, + item_tree::ItemTreeNode, + nameres::{DefMap, ModuleData, ModuleOrigin, ModuleSource}, path::{ModPath, PathKind}, + src::HasSource as DefHasSource, // xx: I don't like this shadowing of HasSource... :( type_ref::{Mutability, TypeRef}, visibility::Visibility, + AdtId, + AssocItemLoc, + ItemLoc, + Lookup, + ModuleDefId, + ModuleId, }, hir_expand::{ name::{known, Name}, diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 882d54c996..cf670e5cc1 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs @@ -148,7 +148,7 @@ pub enum ModuleOrigin { } impl ModuleOrigin { - fn declaration(&self) -> Option> { + pub fn declaration(&self) -> Option> { match self { ModuleOrigin::File { declaration: module, .. } | ModuleOrigin::Inline { definition: module, .. } => Some(*module), diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index 3121cdd4a2..f7cdb3ce8d 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -4,8 +4,8 @@ use std::fmt; use either::Either; use hir::{ - AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay, InFile, ModuleSource, - Semantics, + db::AstDatabase, AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay, + InFile, ModuleSource, Semantics, }; use ide_db::{ base_db::{FileId, FileRange}, @@ -170,7 +170,7 @@ impl NavigationTarget { impl ToNav for FileSymbol { fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { NavigationTarget { - file_id: self.file_id, + file_id: self.file_id.original_file(db), name: self.name.clone(), kind: Some(match self.kind { FileSymbolKind::Function => SymbolKind::Function, @@ -517,8 +517,8 @@ impl TryToNav for hir::ConstParam { /// e.g. `struct Name`, `enum Name`, `fn Name` pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option { let sema = Semantics::new(db); - let parse = sema.parse(symbol.file_id); - let node = symbol.ptr.to_node(parse.syntax()); + let syntax = sema.db.parse_or_expand(symbol.file_id)?; + let node = symbol.ptr.to_node(&syntax); match_ast! { match node { diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs index a3ea3edc97..33bb14adde 100644 --- a/crates/ide_db/src/items_locator.rs +++ b/crates/ide_db/src/items_locator.rs @@ -4,6 +4,7 @@ //! are located in different caches, with different APIs. use either::Either; use hir::{ + db::AstDatabase, import_map::{self, ImportKind}, AsAssocItem, Crate, ItemInNs, Semantics, }; @@ -135,7 +136,7 @@ fn get_name_definition( let _p = profile::span("get_name_definition"); let file_id = import_candidate.file_id; - let candidate_node = import_candidate.ptr.to_node(sema.parse(file_id).syntax()); + let candidate_node = import_candidate.ptr.to_node(&sema.db.parse_or_expand(file_id)?); let candidate_name_node = if candidate_node.kind() != NAME { candidate_node.children().find(|it| it.kind() == NAME)? } else { diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 54ceafa67f..5bea5837a7 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -33,7 +33,10 @@ use base_db::{ CrateId, FileId, SourceDatabaseExt, SourceRootId, }; use fst::{self, Streamer}; -use hir::db::DefDatabase; +use hir::{ + db::DefDatabase, AdtId, AssocItemLoc, DefHasSource, HirFileId, ItemLoc, ItemScope, + ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, +}; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ @@ -202,21 +205,29 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec>(); - let buf = buf.iter().map(|it| &**it).collect::>(); + // let buf = files + // .par_iter() + // .map_with(snap, |db, &file_id| db.0.file_symbols(file_id)) + // .collect::>(); + + // todo: make this fast!!! + // how do i salsa this? + + let buf: Vec<_> = def_map + .modules() + .map(|(_, module_data)| SymbolIndex::new(module_data_to_file_symbols(db, module_data))) + .collect(); + let buf = buf.iter().collect::>(); query.search(&buf) } @@ -364,7 +375,7 @@ impl Query { /// possible. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FileSymbol { - pub file_id: FileId, + pub file_id: HirFileId, pub name: SmolStr, pub kind: FileSymbolKind, pub range: TextRange, @@ -456,23 +467,134 @@ fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option { to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol { name, kind: match node.kind() { - FN => FileSymbolKind::Function, - STRUCT => FileSymbolKind::Struct, - ENUM => FileSymbolKind::Enum, - TRAIT => FileSymbolKind::Trait, - MODULE => FileSymbolKind::Module, - TYPE_ALIAS => FileSymbolKind::TypeAlias, - CONST => FileSymbolKind::Const, - STATIC => FileSymbolKind::Static, - MACRO_RULES => FileSymbolKind::Macro, - MACRO_DEF => FileSymbolKind::Macro, - UNION => FileSymbolKind::Union, + FN => FileSymbolKind::Function, // FunctionId + STRUCT => FileSymbolKind::Struct, // AdtId::StructId + ENUM => FileSymbolKind::Enum, // AdtId::EnumId + TRAIT => FileSymbolKind::Trait, // TraitId + MODULE => FileSymbolKind::Module, // ModuleId + TYPE_ALIAS => FileSymbolKind::TypeAlias, // TypeAliasId + CONST => FileSymbolKind::Const, // ConstId + STATIC => FileSymbolKind::Static, // StaticId + MACRO_RULES => FileSymbolKind::Macro, // via ItemScope::macros + MACRO_DEF => FileSymbolKind::Macro, // via ItemScope::macros + UNION => FileSymbolKind::Union, // AdtId::UnionId kind => unreachable!("{:?}", kind), }, range: node.text_range(), ptr, - file_id, + file_id: file_id.into(), name_range: Some(name_range), container_name: None, }) } + +fn module_data_to_file_symbols(db: &dyn DefDatabase, module_data: &ModuleData) -> Vec { + let mut symbols = Vec::new(); + collect_symbols_from_item_scope(db, &mut symbols, &module_data.scope); + // todo: collect macros from scope.macros(). + symbols +} + +fn collect_symbols_from_item_scope( + db: &dyn DefDatabase, + symbols: &mut Vec, + scope: &ItemScope, +) { + // todo: dedupe code. + fn decl_assoc(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option + where + L: Lookup>, + T: ItemTreeNode, + ::Source: HasName, + { + let loc = id.lookup(db); + let source = loc.source(db); + let name = source.value.name()?; + let file_id = loc.id.file_id(); + + let name_range = name.syntax().text_range(); + let name = name.text().into(); + let ptr = SyntaxNodePtr::new(source.value.syntax()); + + Some(FileSymbol { + name, + kind, + range: source.value.syntax().text_range(), + // todo: fill out based on loc.container. + container_name: None, + file_id, + name_range: Some(name_range), + ptr, + }) + } + fn decl(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option + where + L: Lookup>, + T: ItemTreeNode, + ::Source: HasName, + { + let loc = id.lookup(db); + let source = loc.source(db); + let name = source.value.name()?; + let file_id = loc.id.file_id(); + let name_range = name.syntax().text_range(); + let name = name.text().into(); + let ptr = SyntaxNodePtr::new(source.value.syntax()); + + Some(FileSymbol { + name, + kind, + range: source.value.syntax().text_range(), + container_name: None, + file_id, + name_range: Some(name_range), + ptr, + }) + } + + fn decl_module(db: &dyn DefDatabase, module_id: ModuleId) -> Option { + let def_map = module_id.def_map(db); + let module_data = &def_map[module_id.local_id]; + let declaration = module_data.origin.declaration()?; + let file_id = match module_data.origin.file_id() { + Some(file_id) => file_id.into(), + None => declaration.file_id, + }; + + let module = declaration.to_node(db.upcast()); + let name = module.name()?; + let name_range = name.syntax().text_range(); + let name = name.text().into(); + let ptr = SyntaxNodePtr::new(module.syntax()); + + Some(FileSymbol { + name, + kind: FileSymbolKind::Module, + range: module.syntax().text_range(), + container_name: None, + file_id, + name_range: Some(name_range), + ptr, + }) + } + + let symbols_iter = scope.declarations().filter_map(|module_def_id| match module_def_id { + ModuleDefId::ModuleId(module_id) => decl_module(db, module_id), + ModuleDefId::FunctionId(function_id) => { + decl_assoc(db, function_id, FileSymbolKind::Function) + } + ModuleDefId::AdtId(AdtId::StructId(struct_id)) => { + decl(db, struct_id, FileSymbolKind::Struct) + } + ModuleDefId::AdtId(AdtId::EnumId(enum_id)) => decl(db, enum_id, FileSymbolKind::Enum), + ModuleDefId::AdtId(AdtId::UnionId(union_id)) => decl(db, union_id, FileSymbolKind::Union), + ModuleDefId::EnumVariantId(_) => None, + ModuleDefId::ConstId(const_id) => decl_assoc(db, const_id, FileSymbolKind::Const), + ModuleDefId::StaticId(static_id) => decl(db, static_id, FileSymbolKind::Static), + ModuleDefId::TraitId(trait_id) => decl(db, trait_id, FileSymbolKind::Trait), + ModuleDefId::TypeAliasId(alias_id) => decl_assoc(db, alias_id, FileSymbolKind::TypeAlias), + ModuleDefId::BuiltinType(_) => None, + }); + + symbols.extend(symbols_iter); +} From a69af9daa3e9b3f61ce83d904b0b27022d759869 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Sat, 27 Nov 2021 11:49:51 +0000 Subject: [PATCH 02/24] sema parse_or_expand --- crates/hir/src/semantics.rs | 10 ++++++++++ crates/ide_db/src/items_locator.rs | 3 +-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 281e6c65dc..27ba42ce1a 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -143,6 +143,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.parse(file_id) } + pub fn parse_or_expand(&self, file_id: HirFileId) -> Option { + self.imp.parse_or_expand(file_id) + } + pub fn expand(&self, macro_call: &ast::MacroCall) -> Option { self.imp.expand(macro_call) } @@ -416,6 +420,12 @@ impl<'db> SemanticsImpl<'db> { tree } + fn parse_or_expand(&self, file_id: HirFileId) -> Option { + let node = self.db.parse_or_expand(file_id)?; + self.cache(node.clone(), file_id); + Some(node) + } + fn expand(&self, macro_call: &ast::MacroCall) -> Option { let sa = self.analyze(macro_call.syntax()); let file_id = sa.expand(self.db, InFile::new(sa.file_id, macro_call))?; diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs index 33bb14adde..788cfdc039 100644 --- a/crates/ide_db/src/items_locator.rs +++ b/crates/ide_db/src/items_locator.rs @@ -4,7 +4,6 @@ //! are located in different caches, with different APIs. use either::Either; use hir::{ - db::AstDatabase, import_map::{self, ImportKind}, AsAssocItem, Crate, ItemInNs, Semantics, }; @@ -136,7 +135,7 @@ fn get_name_definition( let _p = profile::span("get_name_definition"); let file_id = import_candidate.file_id; - let candidate_node = import_candidate.ptr.to_node(&sema.db.parse_or_expand(file_id)?); + let candidate_node = import_candidate.ptr.to_node(&sema.parse_or_expand(file_id)?); let candidate_name_node = if candidate_node.kind() != NAME { candidate_node.children().find(|it| it.kind() == NAME)? } else { From a1030b07ab80ceb4588d2b8582e6beb66ce624fe Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Sat, 27 Nov 2021 11:55:03 +0000 Subject: [PATCH 03/24] use Semantics::parse_or_expand in another place --- crates/ide/src/navigation_target.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index f7cdb3ce8d..c115f57364 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -4,8 +4,8 @@ use std::fmt; use either::Either; use hir::{ - db::AstDatabase, AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay, - InFile, ModuleSource, Semantics, + AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay, InFile, ModuleSource, + Semantics, }; use ide_db::{ base_db::{FileId, FileRange}, @@ -517,7 +517,7 @@ impl TryToNav for hir::ConstParam { /// e.g. `struct Name`, `enum Name`, `fn Name` pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option { let sema = Semantics::new(db); - let syntax = sema.db.parse_or_expand(symbol.file_id)?; + let syntax = sema.parse_or_expand(symbol.file_id)?; let node = symbol.ptr.to_node(&syntax); match_ast! { From 377162c0f81d415941a3f8f16bf5e4b6799628a6 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Sat, 27 Nov 2021 12:26:03 +0000 Subject: [PATCH 04/24] container name? --- crates/hir/src/lib.rs | 7 ++++--- crates/ide_db/src/symbol_index.rs | 24 ++++++++++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index afa773aaa4..c112b94e01 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -44,9 +44,9 @@ use hir_def::{ nameres, per_ns::PerNs, resolver::{HasResolver, Resolver}, - AssocContainerId, AssocItemId, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, - FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, - StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, + AssocItemId, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, FunctionId, GenericDefId, + HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, StaticId, StructId, + TraitId, TypeAliasId, TypeParamId, UnionId, }; use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind}; use hir_ty::{ @@ -114,6 +114,7 @@ pub use { type_ref::{Mutability, TypeRef}, visibility::Visibility, AdtId, + AssocContainerId, AssocItemLoc, ItemLoc, Lookup, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 5bea5837a7..f5f67dcc9b 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -34,8 +34,8 @@ use base_db::{ }; use fst::{self, Streamer}; use hir::{ - db::DefDatabase, AdtId, AssocItemLoc, DefHasSource, HirFileId, ItemLoc, ItemScope, - ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, + db::DefDatabase, AdtId, AssocContainerId, AssocItemLoc, DefHasSource, HirFileId, ItemLoc, + ItemScope, ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, }; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; @@ -516,12 +516,28 @@ fn collect_symbols_from_item_scope( let name = name.text().into(); let ptr = SyntaxNodePtr::new(source.value.syntax()); + let container_name = match loc.container { + AssocContainerId::ModuleId(module_id) => { + let def_map = module_id.def_map(db); + let module_data = &def_map[module_id.local_id]; + module_data + .origin + .declaration() + .and_then(|s| s.to_node(db.upcast()).name().map(|n| n.text().into())) + } + AssocContainerId::TraitId(trait_id) => { + let loc = trait_id.lookup(db); + let source = loc.source(db); + source.value.name().map(|n| n.text().into()) + } + AssocContainerId::ImplId(_) => None, + }; + Some(FileSymbol { name, kind, range: source.value.syntax().text_range(), - // todo: fill out based on loc.container. - container_name: None, + container_name, file_id, name_range: Some(name_range), ptr, From a7370c57256d2f4e9f32454e6e95ec3a311eb8be Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Sat, 27 Nov 2021 13:00:02 +0000 Subject: [PATCH 05/24] remove file symbols --- crates/ide_db/src/apply_change.rs | 2 +- crates/ide_db/src/symbol_index.rs | 73 ++++++++++++++----------------- 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/crates/ide_db/src/apply_change.rs b/crates/ide_db/src/apply_change.rs index bba270421c..6c085ffc97 100644 --- a/crates/ide_db/src/apply_change.rs +++ b/crates/ide_db/src/apply_change.rs @@ -137,7 +137,7 @@ impl RootDatabase { hir::db::InternTypeParamIdQuery // SymbolsDatabase - crate::symbol_index::FileSymbolsQuery + crate::symbol_index::ModuleSymbolsQuery crate::symbol_index::LibrarySymbolsQuery crate::symbol_index::LocalRootsQuery crate::symbol_index::LibraryRootsQuery diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index f5f67dcc9b..e85a846de5 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -96,7 +96,7 @@ impl Query { #[salsa::query_group(SymbolsDatabaseStorage)] pub trait SymbolsDatabase: hir::db::HirDatabase + SourceDatabaseExt { - fn file_symbols(&self, file_id: FileId) -> Arc; + fn module_symbols(&self, module_id: ModuleId) -> Arc; fn library_symbols(&self) -> Arc>; /// The set of "local" (that is, from the current workspace) roots. /// Files in local roots are assumed to change frequently. @@ -129,13 +129,13 @@ fn library_symbols(db: &dyn SymbolsDatabase) -> Arc Arc { +fn module_symbols(db: &dyn SymbolsDatabase, module_id: ModuleId) -> Arc { db.unwind_if_cancelled(); - let parse = db.parse(file_id); - let symbols = source_file_to_file_symbols(&parse.tree(), file_id); + let def_map = module_id.def_map(db.upcast()); + let module_data = &def_map[module_id.local_id]; - // FIXME: add macros here + let symbols = module_data_to_file_symbols(db.upcast(), module_data); Arc::new(SymbolIndex::new(symbols)) } @@ -183,16 +183,19 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { tmp1 = db.library_symbols(); tmp1.values().collect() } else { - let mut files = Vec::new(); + let mut module_ids = Vec::new(); + for &root in db.local_roots().iter() { - let sr = db.source_root(root); - files.extend(sr.iter()) + let crates = db.source_root_crates(root); + for &krate in crates.iter() { + module_ids.extend(module_ids_for_crate(db, krate)); + } } let snap = Snap(db.snapshot()); - tmp2 = files + tmp2 = module_ids .par_iter() - .map_with(snap, |db, &file_id| db.0.file_symbols(file_id)) + .map_with(snap, |snap, &module_id| snap.0.module_symbols(module_id)) .collect::>(); tmp2.iter().map(|it| &**it).collect() }; @@ -201,37 +204,30 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec { let _p = profile::span("crate_symbols").detail(|| format!("{:?}", query)); - // FIXME(#4842): This now depends on DefMap, why not build the entire symbol index from - // that instead? - let def_map = db.crate_def_map(krate); - // let mut files = Vec::new(); - // let mut modules = vec![def_map.root()]; - // while let Some(module) = modules.pop() { - // let data = &def_map[module]; - // files.extend(data.origin.file_id()); - // modules.extend(data.children.values()); - // } - - // let snap = Snap(db.snapshot()); - - // let buf = files - // .par_iter() - // .map_with(snap, |db, &file_id| db.0.file_symbols(file_id)) - // .collect::>(); - - // todo: make this fast!!! - // how do i salsa this? - - let buf: Vec<_> = def_map - .modules() - .map(|(_, module_data)| SymbolIndex::new(module_data_to_file_symbols(db, module_data))) + let module_ids = module_ids_for_crate(db, krate); + let snap = Snap(db.snapshot()); + let buf: Vec<_> = module_ids + .par_iter() + .map_with(snap, |snap, &module_id| snap.0.module_symbols(module_id)) .collect(); - let buf = buf.iter().collect::>(); - + let buf = buf.iter().map(|it| &**it).collect::>(); query.search(&buf) } +fn module_ids_for_crate(db: &RootDatabase, krate: CrateId) -> Vec { + let def_map = db.crate_def_map(krate); + let mut module_ids = Vec::new(); + let mut modules = vec![def_map.root()]; + while let Some(module) = modules.pop() { + let data = &def_map[module]; + module_ids.push(def_map.module_id(module)); + modules.extend(data.children.values()); + } + + module_ids +} + pub fn index_resolve(db: &RootDatabase, name: &str) -> Vec { let mut query = Query::new(name.to_string()); query.exact(); @@ -572,10 +568,7 @@ fn collect_symbols_from_item_scope( let def_map = module_id.def_map(db); let module_data = &def_map[module_id.local_id]; let declaration = module_data.origin.declaration()?; - let file_id = match module_data.origin.file_id() { - Some(file_id) => file_id.into(), - None => declaration.file_id, - }; + let file_id = declaration.file_id; let module = declaration.to_node(db.upcast()); let name = module.name()?; From e033d8c2a24ce7670d03054e7b932e387d32dcec Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Sat, 27 Nov 2021 13:48:50 +0000 Subject: [PATCH 06/24] make navigation target go to original file location --- crates/ide/src/navigation_target.rs | 4 +-- crates/ide_db/src/items_locator.rs | 2 +- crates/ide_db/src/symbol_index.rs | 42 ++++++++++++++++------------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index c115f57364..a566a75893 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -170,7 +170,7 @@ impl NavigationTarget { impl ToNav for FileSymbol { fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { NavigationTarget { - file_id: self.file_id.original_file(db), + file_id: self.original_file_id, name: self.name.clone(), kind: Some(match self.kind { FileSymbolKind::Function => SymbolKind::Function, @@ -517,7 +517,7 @@ impl TryToNav for hir::ConstParam { /// e.g. `struct Name`, `enum Name`, `fn Name` pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option { let sema = Semantics::new(db); - let syntax = sema.parse_or_expand(symbol.file_id)?; + let syntax = sema.parse_or_expand(symbol.hir_file_id)?; let node = symbol.ptr.to_node(&syntax); match_ast! { diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs index 788cfdc039..fb62d2e7d7 100644 --- a/crates/ide_db/src/items_locator.rs +++ b/crates/ide_db/src/items_locator.rs @@ -133,7 +133,7 @@ fn get_name_definition( import_candidate: &FileSymbol, ) -> Option { let _p = profile::span("get_name_definition"); - let file_id = import_candidate.file_id; + let file_id = import_candidate.hir_file_id; let candidate_node = import_candidate.ptr.to_node(&sema.parse_or_expand(file_id)?); let candidate_name_node = if candidate_node.kind() != NAME { diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index e85a846de5..401056aaaf 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -371,7 +371,8 @@ impl Query { /// possible. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FileSymbol { - pub file_id: HirFileId, + pub hir_file_id: HirFileId, + pub original_file_id: FileId, pub name: SmolStr, pub kind: FileSymbolKind, pub range: TextRange, @@ -478,7 +479,8 @@ fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option { }, range: node.text_range(), ptr, - file_id: file_id.into(), + hir_file_id: file_id.into(), + original_file_id: file_id, name_range: Some(name_range), container_name: None, }) @@ -505,10 +507,11 @@ fn collect_symbols_from_item_scope( { let loc = id.lookup(db); let source = loc.source(db); - let name = source.value.name()?; - let file_id = loc.id.file_id(); - let name_range = name.syntax().text_range(); + let name = source.value.name()?; + let name_range = source.with_value(name.syntax()).original_file_range(db.upcast()); + let hir_file_id = loc.id.file_id(); + let name = name.text().into(); let ptr = SyntaxNodePtr::new(source.value.syntax()); @@ -532,10 +535,11 @@ fn collect_symbols_from_item_scope( Some(FileSymbol { name, kind, - range: source.value.syntax().text_range(), + range: source.with_value(source.value.syntax()).original_file_range(db.upcast()).range, container_name, - file_id, - name_range: Some(name_range), + hir_file_id, + original_file_id: name_range.file_id, + name_range: Some(name_range.range), ptr, }) } @@ -548,18 +552,19 @@ fn collect_symbols_from_item_scope( let loc = id.lookup(db); let source = loc.source(db); let name = source.value.name()?; - let file_id = loc.id.file_id(); - let name_range = name.syntax().text_range(); + let name_range = source.with_value(name.syntax()).original_file_range(db.upcast()); + let hir_file_id = loc.id.file_id(); let name = name.text().into(); let ptr = SyntaxNodePtr::new(source.value.syntax()); Some(FileSymbol { name, kind, - range: source.value.syntax().text_range(), + range: source.with_value(source.value.syntax()).original_file_range(db.upcast()).range, container_name: None, - file_id, - name_range: Some(name_range), + hir_file_id, + original_file_id: name_range.file_id, + name_range: Some(name_range.range), ptr, }) } @@ -568,21 +573,22 @@ fn collect_symbols_from_item_scope( let def_map = module_id.def_map(db); let module_data = &def_map[module_id.local_id]; let declaration = module_data.origin.declaration()?; - let file_id = declaration.file_id; + let hir_file_id = declaration.file_id; let module = declaration.to_node(db.upcast()); let name = module.name()?; - let name_range = name.syntax().text_range(); + let name_range = declaration.with_value(name.syntax()).original_file_range(db.upcast()); let name = name.text().into(); let ptr = SyntaxNodePtr::new(module.syntax()); Some(FileSymbol { name, kind: FileSymbolKind::Module, - range: module.syntax().text_range(), + range: declaration.with_value(module.syntax()).original_file_range(db.upcast()).range, container_name: None, - file_id, - name_range: Some(name_range), + hir_file_id, + original_file_id: name_range.file_id, + name_range: Some(name_range.range), ptr, }) } From 8307d38dc1c1eb8a26d4a9e1a8e40832d1fd1257 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Sun, 28 Nov 2021 00:42:42 +0000 Subject: [PATCH 07/24] cleanups --- crates/ide/src/lib.rs | 4 +- crates/ide/src/navigation_target.rs | 21 +-- crates/ide_db/src/items_locator.rs | 3 +- crates/ide_db/src/symbol_index.rs | 219 +++++++++++----------------- 4 files changed, 99 insertions(+), 148 deletions(-) diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 034a511793..970d37b9cb 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -364,8 +364,8 @@ impl Analysis { pub fn symbol_search(&self, query: Query) -> Cancellable> { self.with_db(|db| { symbol_index::world_symbols(db, query) - .into_iter() - .map(|s| s.to_nav(db)) + .into_iter() // xx: should we make this a par iter? + .filter_map(|s| s.try_to_nav(db)) .collect::>() }) } diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index a566a75893..76ec99ce9e 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -167,10 +167,14 @@ impl NavigationTarget { } } -impl ToNav for FileSymbol { - fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { - NavigationTarget { - file_id: self.original_file_id, +impl TryToNav for FileSymbol { + fn try_to_nav(&self, db: &RootDatabase) -> Option { + let semantics = Semantics::new(db); + let full_range = self.loc.original_range(&semantics)?; + let name_range = self.loc.original_name_range(&semantics)?; + + Some(NavigationTarget { + file_id: full_range.file_id, name: self.name.clone(), kind: Some(match self.kind { FileSymbolKind::Function => SymbolKind::Function, @@ -184,12 +188,12 @@ impl ToNav for FileSymbol { FileSymbolKind::Macro => SymbolKind::Macro, FileSymbolKind::Union => SymbolKind::Union, }), - full_range: self.range, - focus_range: self.name_range, + full_range: full_range.range, + focus_range: Some(name_range.range), container_name: self.container_name.clone(), description: description_from_symbol(db, self), docs: None, - } + }) } } @@ -517,8 +521,7 @@ impl TryToNav for hir::ConstParam { /// e.g. `struct Name`, `enum Name`, `fn Name` pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option { let sema = Semantics::new(db); - let syntax = sema.parse_or_expand(symbol.hir_file_id)?; - let node = symbol.ptr.to_node(&syntax); + let node = symbol.loc.syntax(&sema)?; match_ast! { match node { diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs index fb62d2e7d7..e0dbe6caf0 100644 --- a/crates/ide_db/src/items_locator.rs +++ b/crates/ide_db/src/items_locator.rs @@ -133,9 +133,8 @@ fn get_name_definition( import_candidate: &FileSymbol, ) -> Option { let _p = profile::span("get_name_definition"); - let file_id = import_candidate.hir_file_id; - let candidate_node = import_candidate.ptr.to_node(&sema.parse_or_expand(file_id)?); + let candidate_node = import_candidate.loc.syntax(sema)?; let candidate_name_node = if candidate_node.kind() != NAME { candidate_node.children().find(|it| it.kind() == NAME)? } else { diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 401056aaaf..93d00118dc 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -30,20 +30,18 @@ use std::{ use base_db::{ salsa::{self, ParallelDatabase}, - CrateId, FileId, SourceDatabaseExt, SourceRootId, + CrateId, FileId, FileRange, SourceDatabaseExt, SourceRootId, Upcast, }; use fst::{self, Streamer}; use hir::{ - db::DefDatabase, AdtId, AssocContainerId, AssocItemLoc, DefHasSource, HirFileId, ItemLoc, - ItemScope, ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, + db::DefDatabase, AdtId, AssocContainerId, AssocItemLoc, DefHasSource, HirFileId, InFile, + ItemLoc, ItemScope, ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, Semantics, }; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ ast::{self, HasName}, - match_ast, AstNode, Parse, SmolStr, SourceFile, - SyntaxKind::*, - SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent, + AstNode, Parse, SmolStr, SourceFile, SyntaxNode, SyntaxNodePtr, }; use crate::RootDatabase; @@ -371,16 +369,52 @@ impl Query { /// possible. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FileSymbol { - pub hir_file_id: HirFileId, - pub original_file_id: FileId, pub name: SmolStr, + pub loc: DeclarationLocation, pub kind: FileSymbolKind, - pub range: TextRange, - pub ptr: SyntaxNodePtr, - pub name_range: Option, pub container_name: Option, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct DeclarationLocation { + /// The file id for both the `ptr` and `name_ptr`. + pub hir_file_id: HirFileId, + /// This points to the whole syntax node of the declaration. + pub ptr: SyntaxNodePtr, + /// This points to the [`syntax::ast::Name`] identifier of the declaration. + pub name_ptr: SyntaxNodePtr, +} + +impl DeclarationLocation { + pub fn syntax(&self, semantics: &Semantics<'_, RootDatabase>) -> Option { + let root = semantics.parse_or_expand(self.hir_file_id)?; + Some(self.ptr.to_node(&root)) + } + + pub fn original_range(&self, semantics: &Semantics<'_, RootDatabase>) -> Option { + find_original_file_range(semantics, self.hir_file_id, &self.ptr) + } + + pub fn original_name_range( + &self, + semantics: &Semantics<'_, RootDatabase>, + ) -> Option { + find_original_file_range(semantics, self.hir_file_id, &self.name_ptr) + } +} + +fn find_original_file_range( + semantics: &Semantics<'_, RootDatabase>, + file_id: HirFileId, + ptr: &SyntaxNodePtr, +) -> Option { + let root = semantics.parse_or_expand(file_id)?; + let node = ptr.to_node(&root); + let node = InFile::new(file_id, &node); + + Some(node.original_file_range(semantics.db.upcast())) +} + #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum FileSymbolKind { Const, @@ -408,82 +442,9 @@ impl FileSymbolKind { } } -fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec { - let mut symbols = Vec::new(); - let mut stack = Vec::new(); - - for event in source_file.syntax().preorder() { - match event { - WalkEvent::Enter(node) => { - if let Some(mut symbol) = to_file_symbol(&node, file_id) { - symbol.container_name = stack.last().cloned(); - - stack.push(symbol.name.clone()); - symbols.push(symbol); - } - } - - WalkEvent::Leave(node) => { - if to_symbol(&node).is_some() { - stack.pop(); - } - } - } - } - - symbols -} - -fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { - fn decl(node: N) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { - let name = node.name()?; - let name_range = name.syntax().text_range(); - let name = name.text().into(); - let ptr = SyntaxNodePtr::new(node.syntax()); - - Some((name, ptr, name_range)) - } - match_ast! { - match node { - ast::Fn(it) => decl(it), - ast::Struct(it) => decl(it), - ast::Enum(it) => decl(it), - ast::Trait(it) => decl(it), - ast::Module(it) => decl(it), - ast::TypeAlias(it) => decl(it), - ast::Const(it) => decl(it), - ast::Static(it) => decl(it), - ast::Macro(it) => decl(it), - ast::Union(it) => decl(it), - _ => None, - } - } -} - -fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option { - to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol { - name, - kind: match node.kind() { - FN => FileSymbolKind::Function, // FunctionId - STRUCT => FileSymbolKind::Struct, // AdtId::StructId - ENUM => FileSymbolKind::Enum, // AdtId::EnumId - TRAIT => FileSymbolKind::Trait, // TraitId - MODULE => FileSymbolKind::Module, // ModuleId - TYPE_ALIAS => FileSymbolKind::TypeAlias, // TypeAliasId - CONST => FileSymbolKind::Const, // ConstId - STATIC => FileSymbolKind::Static, // StaticId - MACRO_RULES => FileSymbolKind::Macro, // via ItemScope::macros - MACRO_DEF => FileSymbolKind::Macro, // via ItemScope::macros - UNION => FileSymbolKind::Union, // AdtId::UnionId - kind => unreachable!("{:?}", kind), - }, - range: node.text_range(), - ptr, - hir_file_id: file_id.into(), - original_file_id: file_id, - name_range: Some(name_range), - container_name: None, - }) +fn source_file_to_file_symbols(_source_file: &SourceFile, _file_id: FileId) -> Vec { + // todo: delete this. + vec![] } fn module_data_to_file_symbols(db: &dyn DefDatabase, module_data: &ModuleData) -> Vec { @@ -498,24 +459,8 @@ fn collect_symbols_from_item_scope( symbols: &mut Vec, scope: &ItemScope, ) { - // todo: dedupe code. - fn decl_assoc(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option - where - L: Lookup>, - T: ItemTreeNode, - ::Source: HasName, - { - let loc = id.lookup(db); - let source = loc.source(db); - - let name = source.value.name()?; - let name_range = source.with_value(name.syntax()).original_file_range(db.upcast()); - let hir_file_id = loc.id.file_id(); - - let name = name.text().into(); - let ptr = SyntaxNodePtr::new(source.value.syntax()); - - let container_name = match loc.container { + fn container_name(db: &dyn DefDatabase, container: AssocContainerId) -> Option { + match container { AssocContainerId::ModuleId(module_id) => { let def_map = module_id.def_map(db); let module_data = &def_map[module_id.local_id]; @@ -530,19 +475,32 @@ fn collect_symbols_from_item_scope( source.value.name().map(|n| n.text().into()) } AssocContainerId::ImplId(_) => None, - }; + } + } + + fn decl_assoc(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option + where + L: Lookup>, + T: ItemTreeNode, + ::Source: HasName, + { + let loc = id.lookup(db); + let source = loc.source(db); + let name_node = source.value.name()?; + let container_name = container_name(db, loc.container); Some(FileSymbol { - name, + name: name_node.text().into(), kind, - range: source.with_value(source.value.syntax()).original_file_range(db.upcast()).range, container_name, - hir_file_id, - original_file_id: name_range.file_id, - name_range: Some(name_range.range), - ptr, + loc: DeclarationLocation { + hir_file_id: source.file_id, + ptr: SyntaxNodePtr::new(source.value.syntax()), + name_ptr: SyntaxNodePtr::new(name_node.syntax()), + }, }) } + fn decl(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option where L: Lookup>, @@ -551,21 +509,17 @@ fn collect_symbols_from_item_scope( { let loc = id.lookup(db); let source = loc.source(db); - let name = source.value.name()?; - let name_range = source.with_value(name.syntax()).original_file_range(db.upcast()); - let hir_file_id = loc.id.file_id(); - let name = name.text().into(); - let ptr = SyntaxNodePtr::new(source.value.syntax()); + let name_node = source.value.name()?; Some(FileSymbol { - name, + name: name_node.text().into(), kind, - range: source.with_value(source.value.syntax()).original_file_range(db.upcast()).range, container_name: None, - hir_file_id, - original_file_id: name_range.file_id, - name_range: Some(name_range.range), - ptr, + loc: DeclarationLocation { + hir_file_id: source.file_id, + ptr: SyntaxNodePtr::new(source.value.syntax()), + name_ptr: SyntaxNodePtr::new(name_node.syntax()), + }, }) } @@ -573,23 +527,18 @@ fn collect_symbols_from_item_scope( let def_map = module_id.def_map(db); let module_data = &def_map[module_id.local_id]; let declaration = module_data.origin.declaration()?; - let hir_file_id = declaration.file_id; - let module = declaration.to_node(db.upcast()); - let name = module.name()?; - let name_range = declaration.with_value(name.syntax()).original_file_range(db.upcast()); - let name = name.text().into(); - let ptr = SyntaxNodePtr::new(module.syntax()); + let name_node = module.name()?; Some(FileSymbol { - name, + name: name_node.text().into(), kind: FileSymbolKind::Module, - range: declaration.with_value(module.syntax()).original_file_range(db.upcast()).range, container_name: None, - hir_file_id, - original_file_id: name_range.file_id, - name_range: Some(name_range.range), - ptr, + loc: DeclarationLocation { + hir_file_id: declaration.file_id, + ptr: SyntaxNodePtr::new(module.syntax()), + name_ptr: SyntaxNodePtr::new(name_node.syntax()), + }, }) } From 8850ea0b4fd282c615c70217306e83771c106773 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 01:09:39 +0000 Subject: [PATCH 08/24] collect defs from body blocks --- crates/hir/src/lib.rs | 7 +-- crates/ide_db/src/symbol_index.rs | 72 ++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c112b94e01..3308170773 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -44,9 +44,9 @@ use hir_def::{ nameres, per_ns::PerNs, resolver::{HasResolver, Resolver}, - AssocItemId, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, FunctionId, GenericDefId, - HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, StaticId, StructId, - TraitId, TypeAliasId, TypeParamId, UnionId, + AssocItemId, AttrDefId, ConstId, ConstParamId, EnumId, FunctionId, GenericDefId, HasModule, + ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, StaticId, StructId, TraitId, + TypeAliasId, TypeParamId, UnionId, }; use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind}; use hir_ty::{ @@ -116,6 +116,7 @@ pub use { AdtId, AssocContainerId, AssocItemLoc, + DefWithBodyId, ItemLoc, Lookup, ModuleDefId, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 93d00118dc..c4e02ba1da 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -34,8 +34,8 @@ use base_db::{ }; use fst::{self, Streamer}; use hir::{ - db::DefDatabase, AdtId, AssocContainerId, AssocItemLoc, DefHasSource, HirFileId, InFile, - ItemLoc, ItemScope, ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, Semantics, + db::DefDatabase, AdtId, AssocContainerId, AssocItemLoc, DefHasSource, DefWithBodyId, HirFileId, + InFile, ItemLoc, ItemScope, ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, Semantics, }; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; @@ -542,23 +542,55 @@ fn collect_symbols_from_item_scope( }) } - let symbols_iter = scope.declarations().filter_map(|module_def_id| match module_def_id { - ModuleDefId::ModuleId(module_id) => decl_module(db, module_id), - ModuleDefId::FunctionId(function_id) => { - decl_assoc(db, function_id, FileSymbolKind::Function) - } - ModuleDefId::AdtId(AdtId::StructId(struct_id)) => { - decl(db, struct_id, FileSymbolKind::Struct) - } - ModuleDefId::AdtId(AdtId::EnumId(enum_id)) => decl(db, enum_id, FileSymbolKind::Enum), - ModuleDefId::AdtId(AdtId::UnionId(union_id)) => decl(db, union_id, FileSymbolKind::Union), - ModuleDefId::EnumVariantId(_) => None, - ModuleDefId::ConstId(const_id) => decl_assoc(db, const_id, FileSymbolKind::Const), - ModuleDefId::StaticId(static_id) => decl(db, static_id, FileSymbolKind::Static), - ModuleDefId::TraitId(trait_id) => decl(db, trait_id, FileSymbolKind::Trait), - ModuleDefId::TypeAliasId(alias_id) => decl_assoc(db, alias_id, FileSymbolKind::TypeAlias), - ModuleDefId::BuiltinType(_) => None, - }); + let collect_symbols_from_scope = + |scope: &ItemScope, + symbols: &mut Vec, + bodies_to_traverse: &mut Vec| { + let symbols_iter = + scope.declarations().filter_map(|module_def_id| match module_def_id { + ModuleDefId::ModuleId(module_id) => decl_module(db, module_id), + ModuleDefId::FunctionId(function_id) => { + bodies_to_traverse.push(function_id.into()); + decl_assoc(db, function_id, FileSymbolKind::Function) + } + ModuleDefId::AdtId(AdtId::StructId(struct_id)) => { + decl(db, struct_id, FileSymbolKind::Struct) + } + ModuleDefId::AdtId(AdtId::EnumId(enum_id)) => { + decl(db, enum_id, FileSymbolKind::Enum) + } + ModuleDefId::AdtId(AdtId::UnionId(union_id)) => { + decl(db, union_id, FileSymbolKind::Union) + } + ModuleDefId::ConstId(const_id) => { + bodies_to_traverse.push(const_id.into()); + decl_assoc(db, const_id, FileSymbolKind::Const) + } + ModuleDefId::StaticId(static_id) => { + bodies_to_traverse.push(static_id.into()); + decl(db, static_id, FileSymbolKind::Static) + } + ModuleDefId::TraitId(trait_id) => decl(db, trait_id, FileSymbolKind::Trait), + ModuleDefId::TypeAliasId(alias_id) => { + decl_assoc(db, alias_id, FileSymbolKind::TypeAlias) + } + ModuleDefId::BuiltinType(_) => None, + ModuleDefId::EnumVariantId(_) => None, + }); - symbols.extend(symbols_iter); + symbols.extend(symbols_iter); + }; + + let mut bodies_to_traverse = Vec::new(); + collect_symbols_from_scope(scope, symbols, &mut bodies_to_traverse); + + while let Some(body) = bodies_to_traverse.pop() { + let body = db.body(body); + + for (_, block_def_map) in body.blocks(db) { + for (_, module_data) in block_def_map.modules() { + collect_symbols_from_scope(&module_data.scope, symbols, &mut bodies_to_traverse); + } + } + } } From 8fa1d9bb479c3af2b300b4f19656b7222495f2c7 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 01:11:31 +0000 Subject: [PATCH 09/24] collect blocks from unnamed consts too --- crates/ide_db/src/symbol_index.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index c4e02ba1da..3281d4b810 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -579,6 +579,10 @@ fn collect_symbols_from_item_scope( }); symbols.extend(symbols_iter); + + for const_id in scope.unnamed_consts() { + bodies_to_traverse.push(const_id.into()) + } }; let mut bodies_to_traverse = Vec::new(); From 9387e2d91941a62d008a67de5b8d47cba6ba3b85 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 01:32:47 +0000 Subject: [PATCH 10/24] populate container name when traversing down blocks --- crates/ide_db/src/symbol_index.rs | 55 +++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 3281d4b810..3ff45b4b08 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -545,13 +545,19 @@ fn collect_symbols_from_item_scope( let collect_symbols_from_scope = |scope: &ItemScope, symbols: &mut Vec, - bodies_to_traverse: &mut Vec| { - let symbols_iter = - scope.declarations().filter_map(|module_def_id| match module_def_id { + bodies_to_traverse: &mut Vec<(Option, DefWithBodyId)>, + container_name: &Option| { + let symbols_iter = scope + .declarations() + .filter_map(|module_def_id| match module_def_id { ModuleDefId::ModuleId(module_id) => decl_module(db, module_id), ModuleDefId::FunctionId(function_id) => { - bodies_to_traverse.push(function_id.into()); - decl_assoc(db, function_id, FileSymbolKind::Function) + let symbol = decl_assoc(db, function_id, FileSymbolKind::Function); + bodies_to_traverse.push(( + symbol.as_ref().and_then(|x| Some(x.name.clone())), + function_id.into(), + )); + symbol } ModuleDefId::AdtId(AdtId::StructId(struct_id)) => { decl(db, struct_id, FileSymbolKind::Struct) @@ -563,12 +569,20 @@ fn collect_symbols_from_item_scope( decl(db, union_id, FileSymbolKind::Union) } ModuleDefId::ConstId(const_id) => { - bodies_to_traverse.push(const_id.into()); - decl_assoc(db, const_id, FileSymbolKind::Const) + let symbol = decl_assoc(db, const_id, FileSymbolKind::Const); + bodies_to_traverse.push(( + symbol.as_ref().and_then(|x| Some(x.name.clone())), + const_id.into(), + )); + symbol } ModuleDefId::StaticId(static_id) => { - bodies_to_traverse.push(static_id.into()); - decl(db, static_id, FileSymbolKind::Static) + let symbol = decl(db, static_id, FileSymbolKind::Static); + bodies_to_traverse.push(( + symbol.as_ref().and_then(|x| Some(x.name.clone())), + static_id.into(), + )); + symbol } ModuleDefId::TraitId(trait_id) => decl(db, trait_id, FileSymbolKind::Trait), ModuleDefId::TypeAliasId(alias_id) => { @@ -576,24 +590,39 @@ fn collect_symbols_from_item_scope( } ModuleDefId::BuiltinType(_) => None, ModuleDefId::EnumVariantId(_) => None, + }) + .map(|mut s| { + // If a container name was not provided in the symbol, but within the scope of our traversal, + // we'll update the container name here. + if let Some(container_name) = &container_name { + s.container_name.get_or_insert_with(|| container_name.clone()); + } + + s }); symbols.extend(symbols_iter); for const_id in scope.unnamed_consts() { - bodies_to_traverse.push(const_id.into()) + // since unnamed consts don't really have a name, we'll inherit parent scope's symbol name. + bodies_to_traverse.push((container_name.clone(), const_id.into())); } }; let mut bodies_to_traverse = Vec::new(); - collect_symbols_from_scope(scope, symbols, &mut bodies_to_traverse); + collect_symbols_from_scope(scope, symbols, &mut bodies_to_traverse, &None); - while let Some(body) = bodies_to_traverse.pop() { + while let Some((container_name, body)) = bodies_to_traverse.pop() { let body = db.body(body); for (_, block_def_map) in body.blocks(db) { for (_, module_data) in block_def_map.modules() { - collect_symbols_from_scope(&module_data.scope, symbols, &mut bodies_to_traverse); + collect_symbols_from_scope( + &module_data.scope, + symbols, + &mut bodies_to_traverse, + &container_name, + ); } } } From aecb9a378c8d61a355cb9e9fa247f9307799f7f8 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 02:07:16 +0000 Subject: [PATCH 11/24] traverse even more... --- crates/hir/src/lib.rs | 7 +-- crates/ide_db/src/symbol_index.rs | 71 +++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 3308170773..ae494c86e4 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -44,9 +44,9 @@ use hir_def::{ nameres, per_ns::PerNs, resolver::{HasResolver, Resolver}, - AssocItemId, AttrDefId, ConstId, ConstParamId, EnumId, FunctionId, GenericDefId, HasModule, - ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, StaticId, StructId, TraitId, - TypeAliasId, TypeParamId, UnionId, + AttrDefId, ConstId, ConstParamId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, + LifetimeParamId, LocalEnumVariantId, LocalFieldId, StaticId, StructId, TraitId, TypeAliasId, + TypeParamId, UnionId, }; use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind}; use hir_ty::{ @@ -115,6 +115,7 @@ pub use { visibility::Visibility, AdtId, AssocContainerId, + AssocItemId, AssocItemLoc, DefWithBodyId, ItemLoc, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 3ff45b4b08..01318b103e 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -34,8 +34,9 @@ use base_db::{ }; use fst::{self, Streamer}; use hir::{ - db::DefDatabase, AdtId, AssocContainerId, AssocItemLoc, DefHasSource, DefWithBodyId, HirFileId, - InFile, ItemLoc, ItemScope, ItemTreeNode, Lookup, ModuleData, ModuleDefId, ModuleId, Semantics, + db::DefDatabase, AdtId, AssocContainerId, AssocItemId, AssocItemLoc, DefHasSource, + DefWithBodyId, HirFileId, InFile, ItemLoc, ItemScope, ItemTreeNode, Lookup, ModuleData, + ModuleDefId, ModuleId, Semantics, }; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; @@ -209,21 +210,18 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec>(); query.search(&buf) } fn module_ids_for_crate(db: &RootDatabase, krate: CrateId) -> Vec { let def_map = db.crate_def_map(krate); - let mut module_ids = Vec::new(); - let mut modules = vec![def_map.root()]; - while let Some(module) = modules.pop() { - let data = &def_map[module]; - module_ids.push(def_map.module_id(module)); - modules.extend(data.children.values()); - } - - module_ids + def_map.modules().map(|(id, _)| def_map.module_id(id)).collect() } pub fn index_resolve(db: &RootDatabase, name: &str) -> Vec { @@ -547,7 +545,9 @@ fn collect_symbols_from_item_scope( symbols: &mut Vec, bodies_to_traverse: &mut Vec<(Option, DefWithBodyId)>, container_name: &Option| { - let symbols_iter = scope + let mut trait_ids = Vec::new(); + + let scope_declaration_symbols = scope .declarations() .filter_map(|module_def_id| match module_def_id { ModuleDefId::ModuleId(module_id) => decl_module(db, module_id), @@ -584,7 +584,10 @@ fn collect_symbols_from_item_scope( )); symbol } - ModuleDefId::TraitId(trait_id) => decl(db, trait_id, FileSymbolKind::Trait), + ModuleDefId::TraitId(trait_id) => { + trait_ids.push(trait_id); + decl(db, trait_id, FileSymbolKind::Trait) + } ModuleDefId::TypeAliasId(alias_id) => { decl_assoc(db, alias_id, FileSymbolKind::TypeAlias) } @@ -601,7 +604,47 @@ fn collect_symbols_from_item_scope( s }); - symbols.extend(symbols_iter); + symbols.extend(scope_declaration_symbols); + + // todo: we need to merge in container name to these too. + // also clean this up generally tooooo. + let scope_impl_symbols = scope + .impls() + .map(|impl_id| db.impl_data(impl_id)) + .flat_map(|d| d.items.clone()) // xx: clean up this clone?? + .filter_map(|assoc_item_id| match assoc_item_id { + AssocItemId::FunctionId(function_id) => { + decl_assoc(db, function_id, FileSymbolKind::Function) + } + AssocItemId::ConstId(const_id) => { + decl_assoc(db, const_id, FileSymbolKind::Const) + } + AssocItemId::TypeAliasId(type_alias_id) => { + decl_assoc(db, type_alias_id, FileSymbolKind::TypeAlias) + } + }); + + symbols.extend(scope_impl_symbols); + + // todo: we need to merge in container name to these too. + // also clean this up generally tooooo. + let scope_trait_symbols = trait_ids + .into_iter() + .map(|trait_id| db.trait_data(trait_id)) + .flat_map(|d| d.items.clone()) + .filter_map(|(_, assoc_item_id)| match assoc_item_id { + AssocItemId::FunctionId(function_id) => { + decl_assoc(db, function_id, FileSymbolKind::Function) + } + AssocItemId::ConstId(const_id) => { + decl_assoc(db, const_id, FileSymbolKind::Const) + } + AssocItemId::TypeAliasId(type_alias_id) => { + decl_assoc(db, type_alias_id, FileSymbolKind::TypeAlias) + } + }); + + symbols.extend(scope_trait_symbols); for const_id in scope.unnamed_consts() { // since unnamed consts don't really have a name, we'll inherit parent scope's symbol name. From d69e0dab5626d7ef7751951c2d0cc5cb9ef2499f Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 03:54:52 +0000 Subject: [PATCH 12/24] cleanup the whole thing... --- crates/hir/src/lib.rs | 7 +- crates/ide_db/src/symbol_index.rs | 430 ++++++++++++++++-------------- 2 files changed, 231 insertions(+), 206 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index ae494c86e4..f6d703fd9b 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -44,9 +44,8 @@ use hir_def::{ nameres, per_ns::PerNs, resolver::{HasResolver, Resolver}, - AttrDefId, ConstId, ConstParamId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, - LifetimeParamId, LocalEnumVariantId, LocalFieldId, StaticId, StructId, TraitId, TypeAliasId, - TypeParamId, UnionId, + AttrDefId, ConstId, ConstParamId, EnumId, FunctionId, GenericDefId, HasModule, LifetimeParamId, + LocalEnumVariantId, LocalFieldId, StaticId, StructId, TypeAliasId, TypeParamId, UnionId, }; use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind}; use hir_ty::{ @@ -118,10 +117,12 @@ pub use { AssocItemId, AssocItemLoc, DefWithBodyId, + ImplId, ItemLoc, Lookup, ModuleDefId, ModuleId, + TraitId, }, hir_expand::{ name::{known, Name}, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 01318b103e..3a0dfd066c 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -35,8 +35,8 @@ use base_db::{ use fst::{self, Streamer}; use hir::{ db::DefDatabase, AdtId, AssocContainerId, AssocItemId, AssocItemLoc, DefHasSource, - DefWithBodyId, HirFileId, InFile, ItemLoc, ItemScope, ItemTreeNode, Lookup, ModuleData, - ModuleDefId, ModuleId, Semantics, + DefWithBodyId, HirFileId, ImplId, InFile, ItemLoc, ItemTreeNode, Lookup, ModuleDefId, ModuleId, + Semantics, TraitId, }; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; @@ -129,13 +129,7 @@ fn library_symbols(db: &dyn SymbolsDatabase) -> Arc Arc { - db.unwind_if_cancelled(); - - let def_map = module_id.def_map(db.upcast()); - let module_data = &def_map[module_id.local_id]; - - let symbols = module_data_to_file_symbols(db.upcast(), module_data); - + let symbols = SymbolCollector::collect(db.upcast(), module_id); Arc::new(SymbolIndex::new(symbols)) } @@ -444,229 +438,259 @@ fn source_file_to_file_symbols(_source_file: &SourceFile, _file_id: FileId) -> V // todo: delete this. vec![] } - -fn module_data_to_file_symbols(db: &dyn DefDatabase, module_data: &ModuleData) -> Vec { - let mut symbols = Vec::new(); - collect_symbols_from_item_scope(db, &mut symbols, &module_data.scope); - // todo: collect macros from scope.macros(). - symbols +enum SymbolCollectorWorkItem { + Module { module_id: ModuleId, parent: Option }, + Body { body: DefWithBodyId }, + Impl { impl_id: ImplId }, + Trait { trait_id: TraitId }, } -fn collect_symbols_from_item_scope( - db: &dyn DefDatabase, - symbols: &mut Vec, - scope: &ItemScope, -) { - fn container_name(db: &dyn DefDatabase, container: AssocContainerId) -> Option { - match container { - AssocContainerId::ModuleId(module_id) => { - let def_map = module_id.def_map(db); - let module_data = &def_map[module_id.local_id]; - module_data - .origin - .declaration() - .and_then(|s| s.to_node(db.upcast()).name().map(|n| n.text().into())) +struct SymbolCollector<'a> { + db: &'a dyn DefDatabase, + symbols: Vec, + work: Vec, + container_name_stack: Vec, +} + +impl<'a> SymbolCollector<'a> { + fn collect(db: &dyn DefDatabase, module_id: ModuleId) -> Vec { + let mut symbol_collector = SymbolCollector { + db, + symbols: Default::default(), + container_name_stack: Default::default(), + work: vec![SymbolCollectorWorkItem::Module { module_id, parent: None }], + }; + + while let Some(work_item) = symbol_collector.work.pop() { + symbol_collector.do_work(work_item); + } + + symbol_collector.symbols + } + + fn do_work(&mut self, work_item: SymbolCollectorWorkItem) { + self.db.unwind_if_cancelled(); + + match work_item { + SymbolCollectorWorkItem::Module { module_id, parent } => { + let parent_name = parent.and_then(|id| self.def_with_body_id_name(id)); + self.with_container_name(parent_name, |s| s.collect_from_module(module_id)); } - AssocContainerId::TraitId(trait_id) => { - let loc = trait_id.lookup(db); - let source = loc.source(db); - source.value.name().map(|n| n.text().into()) + SymbolCollectorWorkItem::Body { body } => self.collect_from_body(body), + SymbolCollectorWorkItem::Impl { impl_id } => self.collect_from_impl(impl_id), + SymbolCollectorWorkItem::Trait { trait_id } => { + let trait_name = self.db.trait_data(trait_id).name.as_text(); + self.with_container_name(trait_name, |s| s.collect_from_trait(trait_id)); } - AssocContainerId::ImplId(_) => None, } } - fn decl_assoc(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option + fn collect_from_module(&mut self, module_id: ModuleId) { + let def_map = module_id.def_map(self.db); + let module_data = &def_map[module_id.local_id]; + let scope = &module_data.scope; + + for module_def_id in scope.declarations() { + match module_def_id { + ModuleDefId::ModuleId(id) => self.push_module(id), + ModuleDefId::FunctionId(id) => { + self.push_decl_assoc(id, FileSymbolKind::Function); + self.work.push(SymbolCollectorWorkItem::Body { body: id.into() }); + } + ModuleDefId::AdtId(AdtId::StructId(id)) => { + self.push_decl(id, FileSymbolKind::Struct) + } + ModuleDefId::AdtId(AdtId::EnumId(id)) => self.push_decl(id, FileSymbolKind::Enum), + ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id, FileSymbolKind::Union), + ModuleDefId::ConstId(id) => { + self.push_decl_assoc(id, FileSymbolKind::Const); + self.work.push(SymbolCollectorWorkItem::Body { body: id.into() }) + } + ModuleDefId::StaticId(id) => { + self.push_decl(id, FileSymbolKind::Static); + self.work.push(SymbolCollectorWorkItem::Body { body: id.into() }) + } + ModuleDefId::TraitId(id) => { + self.push_decl(id, FileSymbolKind::Trait); + self.work.push(SymbolCollectorWorkItem::Trait { trait_id: id }) + } + ModuleDefId::TypeAliasId(id) => { + self.push_decl_assoc(id, FileSymbolKind::TypeAlias); + } + // Don't index these. + ModuleDefId::BuiltinType(_) => {} + ModuleDefId::EnumVariantId(_) => {} + } + } + + for impl_id in scope.impls() { + self.work.push(SymbolCollectorWorkItem::Impl { impl_id }); + } + + for const_id in scope.unnamed_consts() { + self.work.push(SymbolCollectorWorkItem::Body { body: const_id.into() }) + } + + // todo: collect macros. + } + + 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 (id, _) in def_map.modules() { + self.work.push(SymbolCollectorWorkItem::Module { + module_id: def_map.module_id(id), + parent: Some(body_id), + }); + } + } + } + + fn collect_from_impl(&mut self, impl_id: ImplId) { + let impl_data = self.db.impl_data(impl_id); + for &assoc_item_id in &impl_data.items { + self.push_assoc_item(assoc_item_id) + } + } + + fn collect_from_trait(&mut self, trait_id: TraitId) { + let trait_data = self.db.trait_data(trait_id); + for &(_, assoc_item_id) in &trait_data.items { + self.push_assoc_item(assoc_item_id); + } + } + + fn with_container_name(&mut self, container_name: Option, f: impl FnOnce(&mut Self)) { + if let Some(container_name) = container_name { + self.container_name_stack.push(container_name); + f(self); + self.container_name_stack.pop(); + } else { + f(self); + } + } + + fn current_container_name(&self) -> Option { + self.container_name_stack.last().cloned() + } + + fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option { + 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()) + } + } + } + + fn push_assoc_item(&mut self, assoc_item_id: AssocItemId) { + match assoc_item_id { + AssocItemId::FunctionId(id) => self.push_decl_assoc(id, FileSymbolKind::Function), + AssocItemId::ConstId(id) => self.push_decl_assoc(id, FileSymbolKind::Const), + AssocItemId::TypeAliasId(id) => self.push_decl_assoc(id, FileSymbolKind::TypeAlias), + } + } + + fn push_decl_assoc(&mut self, id: L, kind: FileSymbolKind) where L: Lookup>, T: ItemTreeNode, ::Source: HasName, { - let loc = id.lookup(db); - let source = loc.source(db); - let name_node = source.value.name()?; - let container_name = container_name(db, loc.container); + fn container_name(db: &dyn DefDatabase, container: AssocContainerId) -> Option { + match container { + AssocContainerId::ModuleId(module_id) => { + let def_map = module_id.def_map(db); + let module_data = &def_map[module_id.local_id]; + module_data + .origin + .declaration() + .and_then(|s| s.to_node(db.upcast()).name().map(|n| n.text().into())) + } + AssocContainerId::TraitId(trait_id) => { + let loc = trait_id.lookup(db); + let source = loc.source(db); + source.value.name().map(|n| n.text().into()) + } + AssocContainerId::ImplId(_) => None, + } + } - Some(FileSymbol { - name: name_node.text().into(), - kind, - container_name, - loc: DeclarationLocation { - hir_file_id: source.file_id, - ptr: SyntaxNodePtr::new(source.value.syntax()), - name_ptr: SyntaxNodePtr::new(name_node.syntax()), - }, + self.push_file_symbol(|s| { + let loc = id.lookup(s.db); + let source = loc.source(s.db); + let name_node = source.value.name()?; + let container_name = + container_name(s.db, loc.container).or_else(|| s.current_container_name()); + + Some(FileSymbol { + name: name_node.text().into(), + kind, + container_name, + loc: DeclarationLocation { + hir_file_id: source.file_id, + ptr: SyntaxNodePtr::new(source.value.syntax()), + name_ptr: SyntaxNodePtr::new(name_node.syntax()), + }, + }) }) } - fn decl(db: &dyn DefDatabase, id: L, kind: FileSymbolKind) -> Option + fn push_decl(&mut self, id: L, kind: FileSymbolKind) where L: Lookup>, T: ItemTreeNode, ::Source: HasName, { - let loc = id.lookup(db); - let source = loc.source(db); - let name_node = source.value.name()?; + self.push_file_symbol(|s| { + let loc = id.lookup(s.db); + let source = loc.source(s.db); + let name_node = source.value.name()?; - Some(FileSymbol { - name: name_node.text().into(), - kind, - container_name: None, - loc: DeclarationLocation { - hir_file_id: source.file_id, - ptr: SyntaxNodePtr::new(source.value.syntax()), - name_ptr: SyntaxNodePtr::new(name_node.syntax()), - }, + Some(FileSymbol { + name: name_node.text().into(), + kind, + container_name: s.current_container_name(), + loc: DeclarationLocation { + hir_file_id: source.file_id, + ptr: SyntaxNodePtr::new(source.value.syntax()), + name_ptr: SyntaxNodePtr::new(name_node.syntax()), + }, + }) }) } - fn decl_module(db: &dyn DefDatabase, module_id: ModuleId) -> Option { - let def_map = module_id.def_map(db); - let module_data = &def_map[module_id.local_id]; - let declaration = module_data.origin.declaration()?; - let module = declaration.to_node(db.upcast()); - let name_node = module.name()?; + fn push_module(&mut self, module_id: ModuleId) { + self.push_file_symbol(|s| { + let def_map = module_id.def_map(s.db); + let module_data = &def_map[module_id.local_id]; + let declaration = module_data.origin.declaration()?; + let module = declaration.to_node(s.db.upcast()); + let name_node = module.name()?; - Some(FileSymbol { - name: name_node.text().into(), - kind: FileSymbolKind::Module, - container_name: None, - loc: DeclarationLocation { - hir_file_id: declaration.file_id, - ptr: SyntaxNodePtr::new(module.syntax()), - name_ptr: SyntaxNodePtr::new(name_node.syntax()), - }, + Some(FileSymbol { + name: name_node.text().into(), + kind: FileSymbolKind::Module, + container_name: s.current_container_name(), + loc: DeclarationLocation { + hir_file_id: declaration.file_id, + ptr: SyntaxNodePtr::new(module.syntax()), + name_ptr: SyntaxNodePtr::new(name_node.syntax()), + }, + }) }) } - let collect_symbols_from_scope = - |scope: &ItemScope, - symbols: &mut Vec, - bodies_to_traverse: &mut Vec<(Option, DefWithBodyId)>, - container_name: &Option| { - let mut trait_ids = Vec::new(); - - let scope_declaration_symbols = scope - .declarations() - .filter_map(|module_def_id| match module_def_id { - ModuleDefId::ModuleId(module_id) => decl_module(db, module_id), - ModuleDefId::FunctionId(function_id) => { - let symbol = decl_assoc(db, function_id, FileSymbolKind::Function); - bodies_to_traverse.push(( - symbol.as_ref().and_then(|x| Some(x.name.clone())), - function_id.into(), - )); - symbol - } - ModuleDefId::AdtId(AdtId::StructId(struct_id)) => { - decl(db, struct_id, FileSymbolKind::Struct) - } - ModuleDefId::AdtId(AdtId::EnumId(enum_id)) => { - decl(db, enum_id, FileSymbolKind::Enum) - } - ModuleDefId::AdtId(AdtId::UnionId(union_id)) => { - decl(db, union_id, FileSymbolKind::Union) - } - ModuleDefId::ConstId(const_id) => { - let symbol = decl_assoc(db, const_id, FileSymbolKind::Const); - bodies_to_traverse.push(( - symbol.as_ref().and_then(|x| Some(x.name.clone())), - const_id.into(), - )); - symbol - } - ModuleDefId::StaticId(static_id) => { - let symbol = decl(db, static_id, FileSymbolKind::Static); - bodies_to_traverse.push(( - symbol.as_ref().and_then(|x| Some(x.name.clone())), - static_id.into(), - )); - symbol - } - ModuleDefId::TraitId(trait_id) => { - trait_ids.push(trait_id); - decl(db, trait_id, FileSymbolKind::Trait) - } - ModuleDefId::TypeAliasId(alias_id) => { - decl_assoc(db, alias_id, FileSymbolKind::TypeAlias) - } - ModuleDefId::BuiltinType(_) => None, - ModuleDefId::EnumVariantId(_) => None, - }) - .map(|mut s| { - // If a container name was not provided in the symbol, but within the scope of our traversal, - // we'll update the container name here. - if let Some(container_name) = &container_name { - s.container_name.get_or_insert_with(|| container_name.clone()); - } - - s - }); - - symbols.extend(scope_declaration_symbols); - - // todo: we need to merge in container name to these too. - // also clean this up generally tooooo. - let scope_impl_symbols = scope - .impls() - .map(|impl_id| db.impl_data(impl_id)) - .flat_map(|d| d.items.clone()) // xx: clean up this clone?? - .filter_map(|assoc_item_id| match assoc_item_id { - AssocItemId::FunctionId(function_id) => { - decl_assoc(db, function_id, FileSymbolKind::Function) - } - AssocItemId::ConstId(const_id) => { - decl_assoc(db, const_id, FileSymbolKind::Const) - } - AssocItemId::TypeAliasId(type_alias_id) => { - decl_assoc(db, type_alias_id, FileSymbolKind::TypeAlias) - } - }); - - symbols.extend(scope_impl_symbols); - - // todo: we need to merge in container name to these too. - // also clean this up generally tooooo. - let scope_trait_symbols = trait_ids - .into_iter() - .map(|trait_id| db.trait_data(trait_id)) - .flat_map(|d| d.items.clone()) - .filter_map(|(_, assoc_item_id)| match assoc_item_id { - AssocItemId::FunctionId(function_id) => { - decl_assoc(db, function_id, FileSymbolKind::Function) - } - AssocItemId::ConstId(const_id) => { - decl_assoc(db, const_id, FileSymbolKind::Const) - } - AssocItemId::TypeAliasId(type_alias_id) => { - decl_assoc(db, type_alias_id, FileSymbolKind::TypeAlias) - } - }); - - symbols.extend(scope_trait_symbols); - - for const_id in scope.unnamed_consts() { - // since unnamed consts don't really have a name, we'll inherit parent scope's symbol name. - bodies_to_traverse.push((container_name.clone(), const_id.into())); - } - }; - - let mut bodies_to_traverse = Vec::new(); - collect_symbols_from_scope(scope, symbols, &mut bodies_to_traverse, &None); - - while let Some((container_name, body)) = bodies_to_traverse.pop() { - let body = db.body(body); - - for (_, block_def_map) in body.blocks(db) { - for (_, module_data) in block_def_map.modules() { - collect_symbols_from_scope( - &module_data.scope, - symbols, - &mut bodies_to_traverse, - &container_name, - ); - } + fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option) { + if let Some(file_symbol) = f(self) { + self.symbols.push(file_symbol); } } } From 1ed5699355cb6d29d1e1ef2cbb1188c2319c5e7f Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 05:22:30 +0000 Subject: [PATCH 13/24] collect macros --- crates/hir/src/lib.rs | 4 +- crates/hir_def/src/item_scope.rs | 18 ++++- crates/hir_def/src/nameres/collector.rs | 2 + crates/ide_db/src/symbol_index.rs | 90 +++++++++++++++++-------- 4 files changed, 81 insertions(+), 33 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index f6d703fd9b..becef49564 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -47,7 +47,7 @@ use hir_def::{ AttrDefId, ConstId, ConstParamId, EnumId, FunctionId, GenericDefId, HasModule, LifetimeParamId, LocalEnumVariantId, LocalFieldId, StaticId, StructId, TypeAliasId, TypeParamId, UnionId, }; -use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind}; +use hir_expand::{name::name, MacroCallKind, MacroDefKind}; use hir_ty::{ autoderef, consteval::ConstExt, @@ -126,7 +126,7 @@ pub use { }, hir_expand::{ name::{known, Name}, - ExpandResult, HirFileId, InFile, MacroFile, Origin, + ExpandResult, HirFileId, InFile, MacroDefId, MacroFile, Origin, }, hir_ty::display::HirDisplay, }; diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index 0a2a6719ed..8b5984bf12 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs @@ -44,6 +44,8 @@ pub struct ItemScope { /// The defs declared in this scope. Each def has a single scope where it is /// declared. declarations: Vec, + macro_declarations: Vec, + impls: Vec, unnamed_consts: Vec, /// Traits imported via `use Trait as _;`. @@ -101,6 +103,10 @@ impl ItemScope { self.declarations.iter().copied() } + pub fn macro_declarations(&self) -> impl Iterator + '_ { + self.macro_declarations.iter().copied() + } + pub fn impls(&self) -> impl Iterator + ExactSizeIterator + '_ { self.impls.iter().copied() } @@ -121,7 +127,7 @@ impl ItemScope { } /// Iterate over all legacy textual scoped macros visible at the end of the module - pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { + pub fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { self.legacy_macros.iter().map(|(name, def)| (name, *def)) } @@ -163,6 +169,10 @@ impl ItemScope { self.declarations.push(def) } + pub(crate) fn declare_macro(&mut self, def: MacroDefId) { + self.macro_declarations.push(def); + } + pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option { self.legacy_macros.get(name).copied() } @@ -336,7 +346,8 @@ impl ItemScope { values, macros, unresolved, - declarations: defs, + declarations, + macro_declarations, impls, unnamed_consts, unnamed_trait_imports, @@ -348,7 +359,8 @@ impl ItemScope { values.shrink_to_fit(); macros.shrink_to_fit(); unresolved.shrink_to_fit(); - defs.shrink_to_fit(); + declarations.shrink_to_fit(); + macro_declarations.shrink_to_fit(); impls.shrink_to_fit(); unnamed_consts.shrink_to_fit(); unnamed_trait_imports.shrink_to_fit(); diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index a0210bc503..49d2a7866a 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -632,6 +632,7 @@ impl DefCollector<'_> { ) { let vis = self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public); + self.def_map.modules[module_id].scope.declare_macro(macro_); self.update(module_id, &[(Some(name), PerNs::macros(macro_, vis))], vis, ImportType::Named); } @@ -640,6 +641,7 @@ impl DefCollector<'_> { /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped. /// And unconditionally exported. fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) { + self.def_map.modules[self.def_map.root].scope.declare_macro(macro_); self.update( self.def_map.root, &[(Some(name), PerNs::macros(macro_, Visibility::Public))], 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 { fn module_symbols(&self, module_id: ModuleId) -> Arc; fn library_symbols(&self) -> Arc>; /// The set of "local" (that is, from the current workspace) roots. @@ -129,7 +131,7 @@ fn library_symbols(db: &dyn SymbolsDatabase) -> Arc Arc { - 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>(); query.search(&buf) } @@ -446,14 +444,16 @@ enum SymbolCollectorWorkItem { } struct SymbolCollector<'a> { - db: &'a dyn DefDatabase, + db: &'a dyn SymbolsDatabase, symbols: Vec, work: Vec, container_name_stack: Vec, } +/// 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 { + fn collect(db: &dyn SymbolsDatabase, module_id: ModuleId) -> Vec { 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 { 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> { ::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) { if let Some(file_symbol) = f(self) { self.symbols.push(file_symbol); From 6cf9969546dd32dbb5713e3fa6e01f6247b77d25 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 05:28:22 +0000 Subject: [PATCH 14/24] collect macro_rules! macros into macro declarations --- crates/hir_def/src/item_scope.rs | 2 +- crates/hir_def/src/nameres/collector.rs | 1 + crates/ide_db/src/symbol_index.rs | 11 +---------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index 8b5984bf12..37599371f6 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs @@ -127,7 +127,7 @@ impl ItemScope { } /// Iterate over all legacy textual scoped macros visible at the end of the module - pub fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { self.legacy_macros.iter().map(|(name, def)| (name, *def)) } diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 49d2a7866a..d7a35caf29 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -594,6 +594,7 @@ impl DefCollector<'_> { ) { // Textual scoping self.define_legacy_macro(module_id, name.clone(), macro_); + self.def_map.modules[module_id].scope.declare_macro(macro_); // Module scoping // In Rust, `#[macro_export]` macros are unconditionally visible at the diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 53fa3f0881..b8efa279e1 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -490,8 +490,6 @@ impl<'a> SymbolCollector<'a> { 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), @@ -533,13 +531,6 @@ impl<'a> SymbolCollector<'a> { self.work.push(SymbolCollectorWorkItem::Body { body: const_id.into() }) } - // 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()); } @@ -699,7 +690,7 @@ impl<'a> SymbolCollector<'a> { }) } - pub(crate) fn push_decl_macro(&mut self, macro_def: MacroDef) { + 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())?; From 6e89fb6f736f28fdc090c30946871b2d8ea70cca Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 05:42:46 +0000 Subject: [PATCH 15/24] :broom: --- crates/ide_db/src/symbol_index.rs | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index b8efa279e1..5fcb9416c8 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -436,9 +436,9 @@ fn source_file_to_file_symbols(_source_file: &SourceFile, _file_id: FileId) -> V // todo: delete this. vec![] } -enum SymbolCollectorWorkItem { +enum SymbolCollectorWork { Module { module_id: ModuleId, parent: Option }, - Body { body: DefWithBodyId }, + Body { body_id: DefWithBodyId }, Impl { impl_id: ImplId }, Trait { trait_id: TraitId }, } @@ -446,7 +446,7 @@ enum SymbolCollectorWorkItem { struct SymbolCollector<'a> { db: &'a dyn SymbolsDatabase, symbols: Vec, - work: Vec, + work: Vec, container_name_stack: Vec, } @@ -458,30 +458,30 @@ impl<'a> SymbolCollector<'a> { db, symbols: Default::default(), container_name_stack: Default::default(), - work: vec![SymbolCollectorWorkItem::Module { module_id, parent: None }], + work: vec![SymbolCollectorWork::Module { module_id, parent: None }], }; - while let Some(work_item) = symbol_collector.work.pop() { - symbol_collector.do_work(work_item); + while let Some(work) = symbol_collector.work.pop() { + symbol_collector.do_work(work); } symbol_collector.symbols } - fn do_work(&mut self, work_item: SymbolCollectorWorkItem) { + fn do_work(&mut self, work: SymbolCollectorWork) { self.db.unwind_if_cancelled(); - match work_item { - SymbolCollectorWorkItem::Module { module_id, parent } => { + match work { + SymbolCollectorWork::Module { module_id, parent } => { let parent_name = parent.and_then(|id| self.def_with_body_id_name(id)); self.with_container_name(parent_name, |s| s.collect_from_module(module_id)); } - SymbolCollectorWorkItem::Body { body } => self.collect_from_body(body), - SymbolCollectorWorkItem::Impl { impl_id } => self.collect_from_impl(impl_id), - SymbolCollectorWorkItem::Trait { trait_id } => { + SymbolCollectorWork::Trait { trait_id } => { let trait_name = self.db.trait_data(trait_id).name.as_text(); self.with_container_name(trait_name, |s| s.collect_from_trait(trait_id)); } + SymbolCollectorWork::Body { body_id } => self.collect_from_body(body_id), + SymbolCollectorWork::Impl { impl_id } => self.collect_from_impl(impl_id), } } @@ -495,7 +495,7 @@ impl<'a> SymbolCollector<'a> { ModuleDefId::ModuleId(id) => self.push_module(id), ModuleDefId::FunctionId(id) => { self.push_decl_assoc(id, FileSymbolKind::Function); - self.work.push(SymbolCollectorWorkItem::Body { body: id.into() }); + self.work.push(SymbolCollectorWork::Body { body_id: id.into() }); } ModuleDefId::AdtId(AdtId::StructId(id)) => { self.push_decl(id, FileSymbolKind::Struct) @@ -504,15 +504,15 @@ impl<'a> SymbolCollector<'a> { ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id, FileSymbolKind::Union), ModuleDefId::ConstId(id) => { self.push_decl_assoc(id, FileSymbolKind::Const); - self.work.push(SymbolCollectorWorkItem::Body { body: id.into() }) + self.work.push(SymbolCollectorWork::Body { body_id: id.into() }) } ModuleDefId::StaticId(id) => { self.push_decl(id, FileSymbolKind::Static); - self.work.push(SymbolCollectorWorkItem::Body { body: id.into() }) + self.work.push(SymbolCollectorWork::Body { body_id: id.into() }) } ModuleDefId::TraitId(id) => { self.push_decl(id, FileSymbolKind::Trait); - self.work.push(SymbolCollectorWorkItem::Trait { trait_id: id }) + self.work.push(SymbolCollectorWork::Trait { trait_id: id }) } ModuleDefId::TypeAliasId(id) => { self.push_decl_assoc(id, FileSymbolKind::TypeAlias); @@ -524,11 +524,11 @@ impl<'a> SymbolCollector<'a> { } for impl_id in scope.impls() { - self.work.push(SymbolCollectorWorkItem::Impl { impl_id }); + self.work.push(SymbolCollectorWork::Impl { impl_id }); } for const_id in scope.unnamed_consts() { - self.work.push(SymbolCollectorWorkItem::Body { body: const_id.into() }) + self.work.push(SymbolCollectorWork::Body { body_id: const_id.into() }) } for macro_def_id in scope.macro_declarations() { @@ -542,7 +542,7 @@ impl<'a> SymbolCollector<'a> { // Descend into the blocks and enqueue collection of all modules within. for (_, def_map) in body.blocks(self.db.upcast()) { for (id, _) in def_map.modules() { - self.work.push(SymbolCollectorWorkItem::Module { + self.work.push(SymbolCollectorWork::Module { module_id: def_map.module_id(id), parent: Some(body_id), }); From 176f4da77aedc487b24ea32d69ccf3a3eb069a90 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 07:17:18 +0000 Subject: [PATCH 16/24] simplify work --- crates/hir/src/lib.rs | 1 + crates/ide_db/src/symbol_index.rs | 53 ++++++++++++++----------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index becef49564..a23d77d2cc 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -103,6 +103,7 @@ pub use { hir_def::{ adt::StructKind, attr::{Attr, Attrs, AttrsWithOwner, Documentation}, + data::TraitData, find_path::PrefixKind, import_map, item_scope::ItemScope, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 5fcb9416c8..3ad3f2b5d4 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -436,11 +436,11 @@ fn source_file_to_file_symbols(_source_file: &SourceFile, _file_id: FileId) -> V // todo: delete this. vec![] } -enum SymbolCollectorWork { - Module { module_id: ModuleId, parent: Option }, - Body { body_id: DefWithBodyId }, - Impl { impl_id: ImplId }, - Trait { trait_id: TraitId }, + +/// Represents an outstanding module that the symbol collector must collect symbols from. +struct SymbolCollectorWork { + module_id: ModuleId, + parent: Option, } struct SymbolCollector<'a> { @@ -458,7 +458,9 @@ impl<'a> SymbolCollector<'a> { db, symbols: Default::default(), container_name_stack: Default::default(), - work: vec![SymbolCollectorWork::Module { module_id, parent: None }], + // The initial work is the root module we're collecting, additional work will + // be populated as we traverse the module's definitions. + work: vec![SymbolCollectorWork { module_id, parent: None }], }; while let Some(work) = symbol_collector.work.pop() { @@ -471,18 +473,8 @@ impl<'a> SymbolCollector<'a> { fn do_work(&mut self, work: SymbolCollectorWork) { self.db.unwind_if_cancelled(); - match work { - SymbolCollectorWork::Module { module_id, parent } => { - let parent_name = parent.and_then(|id| self.def_with_body_id_name(id)); - self.with_container_name(parent_name, |s| s.collect_from_module(module_id)); - } - SymbolCollectorWork::Trait { trait_id } => { - let trait_name = self.db.trait_data(trait_id).name.as_text(); - self.with_container_name(trait_name, |s| s.collect_from_trait(trait_id)); - } - SymbolCollectorWork::Body { body_id } => self.collect_from_body(body_id), - SymbolCollectorWork::Impl { impl_id } => self.collect_from_impl(impl_id), - } + let parent_name = work.parent.and_then(|id| self.def_with_body_id_name(id)); + self.with_container_name(parent_name, |s| s.collect_from_module(work.module_id)); } fn collect_from_module(&mut self, module_id: ModuleId) { @@ -495,7 +487,7 @@ impl<'a> SymbolCollector<'a> { ModuleDefId::ModuleId(id) => self.push_module(id), ModuleDefId::FunctionId(id) => { self.push_decl_assoc(id, FileSymbolKind::Function); - self.work.push(SymbolCollectorWork::Body { body_id: id.into() }); + self.collect_from_body(id); } ModuleDefId::AdtId(AdtId::StructId(id)) => { self.push_decl(id, FileSymbolKind::Struct) @@ -504,15 +496,15 @@ impl<'a> SymbolCollector<'a> { ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id, FileSymbolKind::Union), ModuleDefId::ConstId(id) => { self.push_decl_assoc(id, FileSymbolKind::Const); - self.work.push(SymbolCollectorWork::Body { body_id: id.into() }) + self.collect_from_body(id); } ModuleDefId::StaticId(id) => { self.push_decl(id, FileSymbolKind::Static); - self.work.push(SymbolCollectorWork::Body { body_id: id.into() }) + self.collect_from_body(id); } ModuleDefId::TraitId(id) => { self.push_decl(id, FileSymbolKind::Trait); - self.work.push(SymbolCollectorWork::Trait { trait_id: id }) + self.collect_from_trait(id); } ModuleDefId::TypeAliasId(id) => { self.push_decl_assoc(id, FileSymbolKind::TypeAlias); @@ -524,11 +516,11 @@ impl<'a> SymbolCollector<'a> { } for impl_id in scope.impls() { - self.work.push(SymbolCollectorWork::Impl { impl_id }); + self.collect_from_impl(impl_id); } for const_id in scope.unnamed_consts() { - self.work.push(SymbolCollectorWork::Body { body_id: const_id.into() }) + self.collect_from_body(const_id); } for macro_def_id in scope.macro_declarations() { @@ -536,13 +528,14 @@ impl<'a> SymbolCollector<'a> { } } - fn collect_from_body(&mut self, body_id: DefWithBodyId) { + fn collect_from_body(&mut self, body_id: impl Into) { + let body_id = body_id.into(); 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.upcast()) { for (id, _) in def_map.modules() { - self.work.push(SymbolCollectorWork::Module { + self.work.push(SymbolCollectorWork { module_id: def_map.module_id(id), parent: Some(body_id), }); @@ -559,9 +552,11 @@ impl<'a> SymbolCollector<'a> { fn collect_from_trait(&mut self, trait_id: TraitId) { let trait_data = self.db.trait_data(trait_id); - for &(_, assoc_item_id) in &trait_data.items { - self.push_assoc_item(assoc_item_id); - } + self.with_container_name(trait_data.name.as_text(), |s| { + for &(_, assoc_item_id) in &trait_data.items { + s.push_assoc_item(assoc_item_id); + } + }); } fn with_container_name(&mut self, container_name: Option, f: impl FnOnce(&mut Self)) { From 1280887561ec48f628f3920075918b72142de1ad Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 09:36:00 +0000 Subject: [PATCH 17/24] do something with library_symbols --- crates/base_db/src/lib.rs | 2 +- crates/ide/src/status.rs | 15 ++---- crates/ide_db/src/symbol_index.rs | 82 +++++++++++-------------------- 3 files changed, 36 insertions(+), 63 deletions(-) diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index c34a329540..66b3a1ca42 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs @@ -102,7 +102,7 @@ fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc>(); + .collect(); Arc::new(res) } diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs index d11c2c35e4..9f589c1ea1 100644 --- a/crates/ide/src/status.rs +++ b/crates/ide/src/status.rs @@ -11,7 +11,6 @@ use ide_db::{ }; use itertools::Itertools; use profile::{memory_usage, Bytes}; -use rustc_hash::FxHashMap; use std::env; use stdx::format_to; use syntax::{ast, Parse, SyntaxNode}; @@ -149,20 +148,16 @@ impl fmt::Display for LibrarySymbolsStats { } } -impl FromIterator>>> - for LibrarySymbolsStats -{ +impl FromIterator>> for LibrarySymbolsStats { fn from_iter(iter: T) -> LibrarySymbolsStats where - T: IntoIterator>>>, + T: IntoIterator>>, { let mut res = LibrarySymbolsStats::default(); for entry in iter { - let value = entry.value.unwrap(); - for symbols in value.values() { - res.total += symbols.len(); - res.size += symbols.memory_size(); - } + let symbols = entry.value.unwrap(); + res.total += symbols.len(); + res.size += symbols.memory_size(); } res } diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 3ad3f2b5d4..6f9e8bf0ed 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -30,7 +30,7 @@ use std::{ use base_db::{ salsa::{self, ParallelDatabase}, - CrateId, FileId, FileRange, SourceDatabaseExt, SourceRootId, Upcast, + CrateId, FileRange, SourceDatabaseExt, SourceRootId, Upcast, }; use either::Either; use fst::{self, Streamer}; @@ -41,11 +41,8 @@ use hir::{ Semantics, TraitId, }; use rayon::prelude::*; -use rustc_hash::{FxHashMap, FxHashSet}; -use syntax::{ - ast::{self, HasName}, - AstNode, Parse, SmolStr, SourceFile, SyntaxNode, SyntaxNodePtr, -}; +use rustc_hash::FxHashSet; +use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr}; use crate::RootDatabase; @@ -98,7 +95,7 @@ impl Query { #[salsa::query_group(SymbolsDatabaseStorage)] pub trait SymbolsDatabase: HirDatabase + SourceDatabaseExt + Upcast { fn module_symbols(&self, module_id: ModuleId) -> Arc; - fn library_symbols(&self) -> Arc>; + fn library_symbols(&self, source_root_id: SourceRootId) -> Arc; /// The set of "local" (that is, from the current workspace) roots. /// Files in local roots are assumed to change frequently. #[salsa::input] @@ -109,28 +106,23 @@ pub trait SymbolsDatabase: HirDatabase + SourceDatabaseExt + Upcast Arc>; } -fn library_symbols(db: &dyn SymbolsDatabase) -> Arc> { +fn library_symbols(db: &dyn SymbolsDatabase, source_root_id: SourceRootId) -> Arc { let _p = profile::span("library_symbols"); - let roots = db.library_roots(); - let res = roots + // todo: this could be parallelized, once I figure out how to do that... + let symbols = db + .source_root_crates(source_root_id) .iter() - .map(|&root_id| { - let root = db.source_root(root_id); - let files = root - .iter() - .map(|it| (it, SourceDatabaseExt::file_text(db, it))) - .collect::>(); - let symbol_index = SymbolIndex::for_files( - files.into_par_iter().map(|(file, text)| (file, SourceFile::parse(&text))), - ); - (root_id, symbol_index) - }) + .flat_map(|&krate| module_ids_for_crate(db.upcast(), krate)) + .map(|module_id| SymbolCollector::collect(db, module_id)) + .flatten() .collect(); - Arc::new(res) + + Arc::new(SymbolIndex::new(symbols)) } fn module_symbols(db: &dyn SymbolsDatabase, module_id: ModuleId) -> Arc { + let _p = profile::span("module_symbols"); let symbols = SymbolCollector::collect(db, module_id); Arc::new(SymbolIndex::new(symbols)) } @@ -172,11 +164,13 @@ impl Clone for Snap> { pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { let _p = profile::span("world_symbols").detail(|| query.query.clone()); - let tmp1; - let tmp2; - let buf: Vec<&SymbolIndex> = if query.libs { - tmp1 = db.library_symbols(); - tmp1.values().collect() + let snap = Snap(db.snapshot()); + + let indices = if query.libs { + db.library_roots() + .par_iter() + .map_with(snap, |snap, &root| snap.0.library_symbols(root)) + .collect() } else { let mut module_ids = Vec::new(); @@ -187,14 +181,13 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { } } - let snap = Snap(db.snapshot()); - tmp2 = module_ids + module_ids .par_iter() .map_with(snap, |snap, &module_id| snap.0.module_symbols(module_id)) - .collect::>(); - tmp2.iter().map(|it| &**it).collect() + .collect() }; - query.search(&buf) + + query.search(indices) } pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec { @@ -202,16 +195,15 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec = module_ids + let indices: Vec<_> = module_ids .par_iter() .map_with(snap, |snap, &module_id| snap.0.module_symbols(module_id)) .collect(); - let buf = buf.iter().map(|it| &**it).collect::>(); - query.search(&buf) + query.search(indices) } -fn module_ids_for_crate(db: &RootDatabase, krate: CrateId) -> Vec { +fn module_ids_for_crate(db: &dyn DefDatabase, krate: CrateId) -> Vec { let def_map = db.crate_def_map(krate); def_map.modules().map(|(id, _)| def_map.module_id(id)).collect() } @@ -292,15 +284,6 @@ impl SymbolIndex { self.map.as_fst().size() + self.symbols.len() * mem::size_of::() } - pub(crate) fn for_files( - files: impl ParallelIterator)>, - ) -> SymbolIndex { - let symbols = files - .flat_map(|(file_id, file)| source_file_to_file_symbols(&file.tree(), file_id)) - .collect::>(); - SymbolIndex::new(symbols) - } - fn range_to_map_value(start: usize, end: usize) -> u64 { debug_assert![start <= (std::u32::MAX as usize)]; debug_assert![end <= (std::u32::MAX as usize)]; @@ -316,10 +299,10 @@ impl SymbolIndex { } impl Query { - pub(crate) fn search(self, indices: &[&SymbolIndex]) -> Vec { + pub(crate) fn search(self, indices: Vec>) -> Vec { let _p = profile::span("symbol_index::Query::search"); let mut op = fst::map::OpBuilder::new(); - for file_symbols in indices.iter() { + for file_symbols in &indices { let automaton = fst::automaton::Subsequence::new(&self.lowercased); op = op.add(file_symbols.map.search(automaton)) } @@ -432,11 +415,6 @@ impl FileSymbolKind { } } -fn source_file_to_file_symbols(_source_file: &SourceFile, _file_id: FileId) -> Vec { - // todo: delete this. - vec![] -} - /// Represents an outstanding module that the symbol collector must collect symbols from. struct SymbolCollectorWork { module_id: ModuleId, From 97105e1288fbeeea5dc814f0b5dad09deb6dfff1 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 09:52:03 +0000 Subject: [PATCH 18/24] some more cleanups --- crates/ide_db/src/symbol_index.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 6f9e8bf0ed..b1546dd4d0 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -94,12 +94,18 @@ impl Query { #[salsa::query_group(SymbolsDatabaseStorage)] pub trait SymbolsDatabase: HirDatabase + SourceDatabaseExt + Upcast { + /// The symbol index for a given module. These modules should only be in source roots that + /// are inside local_roots. fn module_symbols(&self, module_id: ModuleId) -> Arc; + + /// The symbol index for a given source root within library_roots. fn library_symbols(&self, source_root_id: SourceRootId) -> Arc; + /// The set of "local" (that is, from the current workspace) roots. /// Files in local roots are assumed to change frequently. #[salsa::input] fn local_roots(&self) -> Arc>; + /// The set of roots for crates.io libraries. /// Files in libraries are assumed to never change. #[salsa::input] @@ -114,6 +120,9 @@ fn library_symbols(db: &dyn SymbolsDatabase, source_root_id: SourceRootId) -> Ar .source_root_crates(source_root_id) .iter() .flat_map(|&krate| module_ids_for_crate(db.upcast(), krate)) + // we specifically avoid calling SymbolsDatabase::module_symbols here, even they do the same thing, + // as the index for a library is not going to really ever change, and we do not want to store each + // module's index in salsa. .map(|module_id| SymbolCollector::collect(db, module_id)) .flatten() .collect(); @@ -129,11 +138,23 @@ fn module_symbols(db: &dyn SymbolsDatabase, module_id: ModuleId) -> Arc(DB); +impl Snap> { + fn new(db: &DB) -> Self { + Self(db.snapshot()) + } +} impl Clone for Snap> { fn clone(&self) -> Snap> { Snap(self.0.snapshot()) } } +impl std::ops::Deref for Snap { + type Target = DB; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} // Feature: Workspace Symbol // @@ -164,12 +185,10 @@ impl Clone for Snap> { pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { let _p = profile::span("world_symbols").detail(|| query.query.clone()); - let snap = Snap(db.snapshot()); - let indices = if query.libs { db.library_roots() .par_iter() - .map_with(snap, |snap, &root| snap.0.library_symbols(root)) + .map_with(Snap::new(db), |snap, &root| snap.library_symbols(root)) .collect() } else { let mut module_ids = Vec::new(); @@ -183,7 +202,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { module_ids .par_iter() - .map_with(snap, |snap, &module_id| snap.0.module_symbols(module_id)) + .map_with(Snap::new(db), |snap, &module_id| snap.module_symbols(module_id)) .collect() }; @@ -194,10 +213,9 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec = module_ids .par_iter() - .map_with(snap, |snap, &module_id| snap.0.module_symbols(module_id)) + .map_with(Snap::new(db), |snap, &module_id| snap.module_symbols(module_id)) .collect(); query.search(indices) From f0bfe310a224447fdd143ef3844a3ba1408c7620 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 10:36:22 +0000 Subject: [PATCH 19/24] add a test --- crates/base_db/src/fixture.rs | 4 +- crates/hir/src/lib.rs | 1 - crates/ide_db/src/symbol_index.rs | 64 +++ .../test_symbol_index_collection.txt | 457 ++++++++++++++++++ 4 files changed, 523 insertions(+), 3 deletions(-) create mode 100644 crates/ide_db/src/test_data/test_symbol_index_collection.txt diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 2b091f37a0..3751f44cf4 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs @@ -18,8 +18,8 @@ use crate::{ pub const WORKSPACE: SourceRootId = SourceRootId(0); pub trait WithFixture: Default + SourceDatabaseExt + 'static { - fn with_single_file(text: &str) -> (Self, FileId) { - let fixture = ChangeFixture::parse(text); + fn with_single_file(ra_fixture: &str) -> (Self, FileId) { + let fixture = ChangeFixture::parse(ra_fixture); let mut db = Self::default(); fixture.change.apply(&mut db); assert_eq!(fixture.files.len(), 1); diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index a23d77d2cc..becef49564 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -103,7 +103,6 @@ pub use { hir_def::{ adt::StructKind, attr::{Attr, Attrs, AttrsWithOwner, Documentation}, - data::TraitData, find_path::PrefixKind, import_map, item_scope::ItemScope, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index b1546dd4d0..d264c083d7 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -710,3 +710,67 @@ impl<'a> SymbolCollector<'a> { } } } + +#[cfg(test)] +mod tests { + + use base_db::fixture::WithFixture; + use expect_test::expect_file; + + use super::*; + + #[test] + fn test_symbol_index_collection() { + let (db, _) = RootDatabase::with_many_files( + r#" +//- /main.rs + +macro_rules! macro_rules_macro { + () => {} +}; + +macro Macro { } + +struct Struct; +enum Enum { + A, B +} +union Union {} + +impl Struct { + fn impl_fn() {} +} + +trait Trait { + fn trait_fn(&self); +} + +fn main() { + struct StructInFn; +} + +const CONST: u32 = 1; +static STATIC: &'static str = "2"; +type Alias = Struct; + +mod a_mod { + struct StructInModA; +} + +mod b_mod; + +//- /b_mod.rs +struct StructInModB; + "#, + ); + + let symbols: Vec<_> = module_ids_for_crate(db.upcast(), db.test_crate()) + .into_iter() + .map(|module_id| { + (module_id, SymbolCollector::collect(&db as &dyn SymbolsDatabase, module_id)) + }) + .collect(); + + expect_file!["./test_data/test_symbol_index_collection.txt"].assert_debug_eq(&symbols); + } +} diff --git a/crates/ide_db/src/test_data/test_symbol_index_collection.txt b/crates/ide_db/src/test_data/test_symbol_index_collection.txt new file mode 100644 index 0000000000..33f2f2dc7f --- /dev/null +++ b/crates/ide_db/src/test_data/test_symbol_index_collection.txt @@ -0,0 +1,457 @@ +[ + ( + ModuleId { + krate: CrateId( + 0, + ), + block: None, + local_id: Idx::(0), + }, + [ + FileSymbol { + name: "Struct", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 68..82, + kind: STRUCT, + }, + name_ptr: SyntaxNodePtr { + range: 75..81, + kind: NAME, + }, + }, + kind: Struct, + container_name: None, + }, + FileSymbol { + name: "Enum", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 83..105, + kind: ENUM, + }, + name_ptr: SyntaxNodePtr { + range: 88..92, + kind: NAME, + }, + }, + kind: Enum, + container_name: None, + }, + FileSymbol { + name: "Union", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 106..120, + kind: UNION, + }, + name_ptr: SyntaxNodePtr { + range: 112..117, + kind: NAME, + }, + }, + kind: Union, + container_name: None, + }, + FileSymbol { + name: "Trait", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 159..198, + kind: TRAIT, + }, + name_ptr: SyntaxNodePtr { + range: 165..170, + kind: NAME, + }, + }, + kind: Trait, + container_name: None, + }, + FileSymbol { + name: "trait_fn", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 177..196, + kind: FN, + }, + name_ptr: SyntaxNodePtr { + range: 180..188, + kind: NAME, + }, + }, + kind: Function, + container_name: Some( + "Trait", + ), + }, + FileSymbol { + name: "main", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 200..236, + kind: FN, + }, + name_ptr: SyntaxNodePtr { + range: 203..207, + kind: NAME, + }, + }, + kind: Function, + container_name: None, + }, + FileSymbol { + name: "proc_macro", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 238..270, + kind: FN, + }, + name_ptr: SyntaxNodePtr { + range: 255..265, + kind: NAME, + }, + }, + kind: Function, + container_name: None, + }, + FileSymbol { + name: "CONST", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 272..293, + kind: CONST, + }, + name_ptr: SyntaxNodePtr { + range: 278..283, + kind: NAME, + }, + }, + kind: Const, + container_name: None, + }, + FileSymbol { + name: "STATIC", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 294..328, + kind: STATIC, + }, + name_ptr: SyntaxNodePtr { + range: 301..307, + kind: NAME, + }, + }, + kind: Static, + container_name: None, + }, + FileSymbol { + name: "Alias", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 329..349, + kind: TYPE_ALIAS, + }, + name_ptr: SyntaxNodePtr { + range: 334..339, + kind: NAME, + }, + }, + kind: TypeAlias, + container_name: None, + }, + FileSymbol { + name: "a_mod", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 351..389, + kind: MODULE, + }, + name_ptr: SyntaxNodePtr { + range: 355..360, + kind: NAME, + }, + }, + kind: Module, + container_name: None, + }, + FileSymbol { + name: "b_mod", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 391..401, + kind: MODULE, + }, + name_ptr: SyntaxNodePtr { + range: 395..400, + kind: NAME, + }, + }, + kind: Module, + container_name: None, + }, + FileSymbol { + name: "impl_fn", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 140..155, + kind: FN, + }, + name_ptr: SyntaxNodePtr { + range: 143..150, + kind: NAME, + }, + }, + kind: Function, + container_name: None, + }, + FileSymbol { + name: "macro_rules_macro", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 1..48, + kind: MACRO_RULES, + }, + name_ptr: SyntaxNodePtr { + range: 14..31, + kind: NAME, + }, + }, + kind: Macro, + container_name: None, + }, + FileSymbol { + name: "Macro", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 51..66, + kind: MACRO_DEF, + }, + name_ptr: SyntaxNodePtr { + range: 57..62, + kind: NAME, + }, + }, + kind: Macro, + container_name: None, + }, + FileSymbol { + name: "proc_macro", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 238..270, + kind: FN, + }, + name_ptr: SyntaxNodePtr { + range: 255..265, + kind: NAME, + }, + }, + kind: Macro, + container_name: None, + }, + FileSymbol { + name: "StructInFn", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 216..234, + kind: STRUCT, + }, + name_ptr: SyntaxNodePtr { + range: 223..233, + kind: NAME, + }, + }, + kind: Struct, + container_name: Some( + "main", + ), + }, + ], + ), + ( + ModuleId { + krate: CrateId( + 0, + ), + block: None, + local_id: Idx::(1), + }, + [ + FileSymbol { + name: "StructInModA", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 367..387, + kind: STRUCT, + }, + name_ptr: SyntaxNodePtr { + range: 374..386, + kind: NAME, + }, + }, + kind: Struct, + container_name: None, + }, + ], + ), + ( + ModuleId { + krate: CrateId( + 0, + ), + block: None, + local_id: Idx::(2), + }, + [ + FileSymbol { + name: "StructInModB", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 1, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 0..20, + kind: STRUCT, + }, + name_ptr: SyntaxNodePtr { + range: 7..19, + kind: NAME, + }, + }, + kind: Struct, + container_name: None, + }, + ], + ), +] From 0abf236445325d5aafe655067252235846bd1c3c Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Mon, 29 Nov 2021 10:43:51 +0000 Subject: [PATCH 20/24] test the one thing this pr was trying to accomplish lol... --- crates/ide_db/src/symbol_index.rs | 8 + .../test_symbol_index_collection.txt | 150 +++++++++--------- 2 files changed, 84 insertions(+), 74 deletions(-) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index d264c083d7..7744e1ef45 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -729,6 +729,14 @@ macro_rules! macro_rules_macro { () => {} }; +macro_rules! define_struct { + () => { + struct StructFromMacro; + } +}; + +define_struct!(); + macro Macro { } struct Struct; diff --git a/crates/ide_db/src/test_data/test_symbol_index_collection.txt b/crates/ide_db/src/test_data/test_symbol_index_collection.txt index 33f2f2dc7f..4ec4f142da 100644 --- a/crates/ide_db/src/test_data/test_symbol_index_collection.txt +++ b/crates/ide_db/src/test_data/test_symbol_index_collection.txt @@ -8,6 +8,30 @@ local_id: Idx::(0), }, [ + FileSymbol { + name: "StructFromMacro", + loc: DeclarationLocation { + hir_file_id: HirFileId( + MacroFile( + MacroFile { + macro_call_id: MacroCallId( + 0, + ), + }, + ), + ), + ptr: SyntaxNodePtr { + range: 0..22, + kind: STRUCT, + }, + name_ptr: SyntaxNodePtr { + range: 6..21, + kind: NAME, + }, + }, + kind: Struct, + container_name: None, + }, FileSymbol { name: "Struct", loc: DeclarationLocation { @@ -19,11 +43,11 @@ ), ), ptr: SyntaxNodePtr { - range: 68..82, + range: 170..184, kind: STRUCT, }, name_ptr: SyntaxNodePtr { - range: 75..81, + range: 177..183, kind: NAME, }, }, @@ -41,11 +65,11 @@ ), ), ptr: SyntaxNodePtr { - range: 83..105, + range: 185..207, kind: ENUM, }, name_ptr: SyntaxNodePtr { - range: 88..92, + range: 190..194, kind: NAME, }, }, @@ -63,11 +87,11 @@ ), ), ptr: SyntaxNodePtr { - range: 106..120, + range: 208..222, kind: UNION, }, name_ptr: SyntaxNodePtr { - range: 112..117, + range: 214..219, kind: NAME, }, }, @@ -85,11 +109,11 @@ ), ), ptr: SyntaxNodePtr { - range: 159..198, + range: 261..300, kind: TRAIT, }, name_ptr: SyntaxNodePtr { - range: 165..170, + range: 267..272, kind: NAME, }, }, @@ -107,11 +131,11 @@ ), ), ptr: SyntaxNodePtr { - range: 177..196, + range: 279..298, kind: FN, }, name_ptr: SyntaxNodePtr { - range: 180..188, + range: 282..290, kind: NAME, }, }, @@ -131,33 +155,11 @@ ), ), ptr: SyntaxNodePtr { - range: 200..236, + range: 302..338, kind: FN, }, name_ptr: SyntaxNodePtr { - range: 203..207, - kind: NAME, - }, - }, - kind: Function, - container_name: None, - }, - FileSymbol { - name: "proc_macro", - loc: DeclarationLocation { - hir_file_id: HirFileId( - FileId( - FileId( - 0, - ), - ), - ), - ptr: SyntaxNodePtr { - range: 238..270, - kind: FN, - }, - name_ptr: SyntaxNodePtr { - range: 255..265, + range: 305..309, kind: NAME, }, }, @@ -175,11 +177,11 @@ ), ), ptr: SyntaxNodePtr { - range: 272..293, + range: 340..361, kind: CONST, }, name_ptr: SyntaxNodePtr { - range: 278..283, + range: 346..351, kind: NAME, }, }, @@ -197,11 +199,11 @@ ), ), ptr: SyntaxNodePtr { - range: 294..328, + range: 362..396, kind: STATIC, }, name_ptr: SyntaxNodePtr { - range: 301..307, + range: 369..375, kind: NAME, }, }, @@ -219,11 +221,11 @@ ), ), ptr: SyntaxNodePtr { - range: 329..349, + range: 397..417, kind: TYPE_ALIAS, }, name_ptr: SyntaxNodePtr { - range: 334..339, + range: 402..407, kind: NAME, }, }, @@ -241,11 +243,11 @@ ), ), ptr: SyntaxNodePtr { - range: 351..389, + range: 419..457, kind: MODULE, }, name_ptr: SyntaxNodePtr { - range: 355..360, + range: 423..428, kind: NAME, }, }, @@ -263,11 +265,11 @@ ), ), ptr: SyntaxNodePtr { - range: 391..401, + range: 459..469, kind: MODULE, }, name_ptr: SyntaxNodePtr { - range: 395..400, + range: 463..468, kind: NAME, }, }, @@ -285,11 +287,11 @@ ), ), ptr: SyntaxNodePtr { - range: 140..155, + range: 242..257, kind: FN, }, name_ptr: SyntaxNodePtr { - range: 143..150, + range: 245..252, kind: NAME, }, }, @@ -318,6 +320,28 @@ kind: Macro, container_name: None, }, + FileSymbol { + name: "define_struct", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 51..131, + kind: MACRO_RULES, + }, + name_ptr: SyntaxNodePtr { + range: 64..77, + kind: NAME, + }, + }, + kind: Macro, + container_name: None, + }, FileSymbol { name: "Macro", loc: DeclarationLocation { @@ -329,33 +353,11 @@ ), ), ptr: SyntaxNodePtr { - range: 51..66, + range: 153..168, kind: MACRO_DEF, }, name_ptr: SyntaxNodePtr { - range: 57..62, - kind: NAME, - }, - }, - kind: Macro, - container_name: None, - }, - FileSymbol { - name: "proc_macro", - loc: DeclarationLocation { - hir_file_id: HirFileId( - FileId( - FileId( - 0, - ), - ), - ), - ptr: SyntaxNodePtr { - range: 238..270, - kind: FN, - }, - name_ptr: SyntaxNodePtr { - range: 255..265, + range: 159..164, kind: NAME, }, }, @@ -373,11 +375,11 @@ ), ), ptr: SyntaxNodePtr { - range: 216..234, + range: 318..336, kind: STRUCT, }, name_ptr: SyntaxNodePtr { - range: 223..233, + range: 325..335, kind: NAME, }, }, @@ -408,11 +410,11 @@ ), ), ptr: SyntaxNodePtr { - range: 367..387, + range: 435..455, kind: STRUCT, }, name_ptr: SyntaxNodePtr { - range: 374..386, + range: 442..454, kind: NAME, }, }, From 492b169224fae427294abca7710776e2c3784b27 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Tue, 30 Nov 2021 03:09:38 +0000 Subject: [PATCH 21/24] pr feedbacks --- crates/ide_db/src/symbol_index.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 7744e1ef45..1434aa81c2 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -185,7 +185,7 @@ impl std::ops::Deref for Snap { pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { let _p = profile::span("world_symbols").detail(|| query.query.clone()); - let indices = if query.libs { + let indices: Vec<_> = if query.libs { db.library_roots() .par_iter() .map_with(Snap::new(db), |snap, &root| snap.library_symbols(root)) @@ -206,7 +206,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec { .collect() }; - query.search(indices) + query.search(&indices) } pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec { @@ -218,7 +218,7 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec Vec { @@ -317,10 +317,10 @@ impl SymbolIndex { } impl Query { - pub(crate) fn search(self, indices: Vec>) -> Vec { + pub(crate) fn search(self, indices: &[Arc]) -> Vec { let _p = profile::span("symbol_index::Query::search"); let mut op = fst::map::OpBuilder::new(); - for file_symbols in &indices { + for file_symbols in indices.iter() { let automaton = fst::automaton::Subsequence::new(&self.lowercased); op = op.add(file_symbols.map.search(automaton)) } @@ -443,7 +443,7 @@ struct SymbolCollector<'a> { db: &'a dyn SymbolsDatabase, symbols: Vec, work: Vec, - container_name_stack: Vec, + current_container_name: Option, } /// Given a [`ModuleId`] and a [`SymbolsDatabase`], use the DefMap for the module's crate to collect all symbols that should be @@ -453,7 +453,7 @@ impl<'a> SymbolCollector<'a> { let mut symbol_collector = SymbolCollector { db, symbols: Default::default(), - container_name_stack: Default::default(), + current_container_name: None, // The initial work is the root module we're collecting, additional work will // be populated as we traverse the module's definitions. work: vec![SymbolCollectorWork { module_id, parent: None }], @@ -557,16 +557,16 @@ impl<'a> SymbolCollector<'a> { fn with_container_name(&mut self, container_name: Option, f: impl FnOnce(&mut Self)) { if let Some(container_name) = container_name { - self.container_name_stack.push(container_name); + let prev = self.current_container_name.replace(container_name); f(self); - self.container_name_stack.pop(); + self.current_container_name = prev; } else { f(self); } } fn current_container_name(&self) -> Option { - self.container_name_stack.last().cloned() + self.current_container_name.clone() } fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option { From 54fc98920b1f28b5a9ba42a67fcd2868cc0b614a Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Tue, 30 Nov 2021 03:21:17 +0000 Subject: [PATCH 22/24] consts with inners?? --- crates/ide_db/src/symbol_index.rs | 12 ++++ .../test_symbol_index_collection.txt | 72 ++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 1434aa81c2..52c90a3744 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -765,6 +765,18 @@ mod a_mod { struct StructInModA; } +const _: () = { + struct StructInUnnamedConst; + + () +}; + +const CONST_WITH_INNER: () = { + struct StructInNamedConst; + + () +}; + mod b_mod; //- /b_mod.rs diff --git a/crates/ide_db/src/test_data/test_symbol_index_collection.txt b/crates/ide_db/src/test_data/test_symbol_index_collection.txt index 4ec4f142da..fe6eebc4f0 100644 --- a/crates/ide_db/src/test_data/test_symbol_index_collection.txt +++ b/crates/ide_db/src/test_data/test_symbol_index_collection.txt @@ -254,6 +254,28 @@ kind: Module, container_name: None, }, + FileSymbol { + name: "CONST_WITH_INNER", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 520..592, + kind: CONST, + }, + name_ptr: SyntaxNodePtr { + range: 526..542, + kind: NAME, + }, + }, + kind: Const, + container_name: None, + }, FileSymbol { name: "b_mod", loc: DeclarationLocation { @@ -265,11 +287,11 @@ ), ), ptr: SyntaxNodePtr { - range: 459..469, + range: 594..604, kind: MODULE, }, name_ptr: SyntaxNodePtr { - range: 463..468, + range: 598..603, kind: NAME, }, }, @@ -364,6 +386,52 @@ kind: Macro, container_name: None, }, + FileSymbol { + name: "StructInUnnamedConst", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 479..507, + kind: STRUCT, + }, + name_ptr: SyntaxNodePtr { + range: 486..506, + kind: NAME, + }, + }, + kind: Struct, + container_name: None, + }, + FileSymbol { + name: "StructInNamedConst", + loc: DeclarationLocation { + hir_file_id: HirFileId( + FileId( + FileId( + 0, + ), + ), + ), + ptr: SyntaxNodePtr { + range: 555..581, + kind: STRUCT, + }, + name_ptr: SyntaxNodePtr { + range: 562..580, + kind: NAME, + }, + }, + kind: Struct, + container_name: Some( + "CONST_WITH_INNER", + ), + }, FileSymbol { name: "StructInFn", loc: DeclarationLocation { From b0c7ff39b8277aaf80c93a83200dc732792bac7d Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Tue, 30 Nov 2021 04:50:09 +0000 Subject: [PATCH 23/24] remove one need for semantics --- crates/ide/src/navigation_target.rs | 5 ++--- crates/ide_db/src/symbol_index.rs | 17 +++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs index 76ec99ce9e..7deb6cae38 100644 --- a/crates/ide/src/navigation_target.rs +++ b/crates/ide/src/navigation_target.rs @@ -169,9 +169,8 @@ impl NavigationTarget { impl TryToNav for FileSymbol { fn try_to_nav(&self, db: &RootDatabase) -> Option { - let semantics = Semantics::new(db); - let full_range = self.loc.original_range(&semantics)?; - let name_range = self.loc.original_name_range(&semantics)?; + let full_range = self.loc.original_range(db)?; + let name_range = self.loc.original_name_range(db)?; Some(NavigationTarget { file_id: full_range.file_id, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 52c90a3744..f2629f69a0 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -382,28 +382,25 @@ impl DeclarationLocation { Some(self.ptr.to_node(&root)) } - pub fn original_range(&self, semantics: &Semantics<'_, RootDatabase>) -> Option { - find_original_file_range(semantics, self.hir_file_id, &self.ptr) + pub fn original_range(&self, db: &dyn HirDatabase) -> Option { + find_original_file_range(db, self.hir_file_id, &self.ptr) } - pub fn original_name_range( - &self, - semantics: &Semantics<'_, RootDatabase>, - ) -> Option { - find_original_file_range(semantics, self.hir_file_id, &self.name_ptr) + pub fn original_name_range(&self, db: &dyn HirDatabase) -> Option { + find_original_file_range(db, self.hir_file_id, &self.name_ptr) } } fn find_original_file_range( - semantics: &Semantics<'_, RootDatabase>, + db: &dyn HirDatabase, file_id: HirFileId, ptr: &SyntaxNodePtr, ) -> Option { - let root = semantics.parse_or_expand(file_id)?; + let root = db.parse_or_expand(file_id)?; let node = ptr.to_node(&root); let node = InFile::new(file_id, &node); - Some(node.original_file_range(semantics.db.upcast())) + Some(node.original_file_range(db.upcast())) } #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] From f4bf750016c4c51b0ec1f1b0e6e2fe25578796f3 Mon Sep 17 00:00:00 2001 From: Jake Heinz Date: Tue, 30 Nov 2021 08:24:07 +0000 Subject: [PATCH 24/24] simpler way of grabbing module / trait name --- crates/ide_db/src/symbol_index.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index f2629f69a0..cc2b2bbb7b 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs @@ -37,8 +37,8 @@ use fst::{self, Streamer}; use hir::{ db::{DefDatabase, HirDatabase}, AdtId, AssocContainerId, AssocItemId, AssocItemLoc, DefHasSource, DefWithBodyId, HasSource, - HirFileId, ImplId, InFile, ItemLoc, ItemTreeNode, Lookup, MacroDef, ModuleDefId, ModuleId, - Semantics, TraitId, + HirFileId, ImplId, InFile, ItemLoc, ItemTreeNode, Lookup, MacroDef, Module, ModuleDefId, + ModuleId, Semantics, TraitId, }; use rayon::prelude::*; use rustc_hash::FxHashSet; @@ -472,8 +472,7 @@ impl<'a> SymbolCollector<'a> { fn collect_from_module(&mut self, module_id: ModuleId) { let def_map = module_id.def_map(self.db.upcast()); - let module_data = &def_map[module_id.local_id]; - let scope = &module_data.scope; + let scope = &def_map[module_id.local_id].scope; for module_def_id in scope.declarations() { match module_def_id { @@ -594,20 +593,15 @@ impl<'a> SymbolCollector<'a> { T: ItemTreeNode, ::Source: HasName, { - fn container_name(db: &dyn DefDatabase, container: AssocContainerId) -> Option { + fn container_name(db: &dyn HirDatabase, container: AssocContainerId) -> Option { match container { AssocContainerId::ModuleId(module_id) => { - let def_map = module_id.def_map(db); - let module_data = &def_map[module_id.local_id]; - module_data - .origin - .declaration() - .and_then(|s| s.to_node(db.upcast()).name().map(|n| n.text().into())) + let module = Module::from(module_id); + module.name(db).and_then(|name| name.as_text()) } AssocContainerId::TraitId(trait_id) => { - let loc = trait_id.lookup(db); - let source = loc.source(db); - source.value.name().map(|n| n.text().into()) + let trait_data = db.trait_data(trait_id); + trait_data.name.as_text() } AssocContainerId::ImplId(_) => None, }