1 //! This crate defines the core datastructure representing IDE state -- `RootDatabase`.
3 //! It is mainly a `HirDatabase` for semantic analysis, plus a `SymbolsDatabase`, for fuzzy search.
12 pub mod items_locator;
13 pub mod source_change;
17 pub mod path_transform;
21 pub mod active_parameter;
23 use std::{fmt, mem::ManuallyDrop, sync::Arc};
26 salsa::{self, Durability},
27 AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast,
29 use hir::db::{AstDatabase, DefDatabase, HirDatabase};
30 use rustc_hash::FxHashSet;
32 use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
34 /// `base_db` is normally also needed in places where `ide_db` is used, so this re-export is for convenience.
37 pub type FxIndexSet<T> = indexmap::IndexSet<T, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
38 pub type FxIndexMap<K, V> =
39 indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
42 base_db::SourceDatabaseStorage,
43 base_db::SourceDatabaseExtStorage,
44 LineIndexDatabaseStorage,
45 symbol_index::SymbolsDatabaseStorage,
46 hir::db::InternDatabaseStorage,
47 hir::db::AstDatabaseStorage,
48 hir::db::DefDatabaseStorage,
49 hir::db::HirDatabaseStorage
51 pub struct RootDatabase {
52 // We use `ManuallyDrop` here because every codegen unit that contains a
53 // `&RootDatabase -> &dyn OtherDatabase` cast will instantiate its drop glue in the vtable,
54 // which duplicates `Weak::drop` and `Arc::drop` tens of thousands of times, which makes
55 // compile times of all `ide_*` and downstream crates suffer greatly.
56 storage: ManuallyDrop<salsa::Storage<RootDatabase>>,
59 impl Drop for RootDatabase {
62 ManuallyDrop::drop(&mut self.storage);
67 impl fmt::Debug for RootDatabase {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 f.debug_struct("RootDatabase").finish()
73 impl Upcast<dyn AstDatabase> for RootDatabase {
74 fn upcast(&self) -> &(dyn AstDatabase + 'static) {
79 impl Upcast<dyn DefDatabase> for RootDatabase {
80 fn upcast(&self) -> &(dyn DefDatabase + 'static) {
85 impl Upcast<dyn HirDatabase> for RootDatabase {
86 fn upcast(&self) -> &(dyn HirDatabase + 'static) {
91 impl FileLoader for RootDatabase {
92 fn file_text(&self, file_id: FileId) -> Arc<String> {
93 FileLoaderDelegate(self).file_text(file_id)
95 fn resolve_path(&self, path: AnchoredPath) -> Option<FileId> {
96 FileLoaderDelegate(self).resolve_path(path)
98 fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
99 FileLoaderDelegate(self).relevant_crates(file_id)
103 impl salsa::Database for RootDatabase {}
105 impl Default for RootDatabase {
106 fn default() -> RootDatabase {
107 RootDatabase::new(None)
112 pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
113 let mut db = RootDatabase { storage: ManuallyDrop::new(salsa::Storage::default()) };
114 db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
115 db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
116 db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
117 db.set_enable_proc_attr_macros(Default::default());
118 db.update_lru_capacity(lru_capacity);
122 pub fn update_lru_capacity(&mut self, lru_capacity: Option<usize>) {
123 let lru_capacity = lru_capacity.unwrap_or(base_db::DEFAULT_LRU_CAP);
124 base_db::ParseQuery.in_db_mut(self).set_lru_capacity(lru_capacity);
125 hir::db::ParseMacroExpansionQuery.in_db_mut(self).set_lru_capacity(lru_capacity);
126 hir::db::MacroExpandQuery.in_db_mut(self).set_lru_capacity(lru_capacity);
130 impl salsa::ParallelDatabase for RootDatabase {
131 fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
132 salsa::Snapshot::new(RootDatabase { storage: ManuallyDrop::new(self.storage.snapshot()) })
136 #[salsa::query_group(LineIndexDatabaseStorage)]
137 pub trait LineIndexDatabase: base_db::SourceDatabase {
138 fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
141 fn line_index(db: &dyn LineIndexDatabase, file_id: FileId) -> Arc<LineIndex> {
142 let text = db.file_text(file_id);
143 Arc::new(LineIndex::new(&*text))
146 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
147 pub enum SymbolKind {