Skip to content

Commit 3c19ebf

Browse files
committed
Disassemble SymbolsDatabase
1 parent abf2e3e commit 3c19ebf

File tree

11 files changed

+125
-95
lines changed

11 files changed

+125
-95
lines changed

crates/hir/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ pub mod term_search;
3535

3636
mod display;
3737

38+
#[doc(hidden)]
39+
pub use hir_def::ModuleId;
40+
3841
use std::{
3942
fmt,
4043
mem::discriminant,
@@ -48,8 +51,8 @@ use hir_def::{
4851
AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId,
4952
CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId,
5053
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
51-
LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, SyntheticSyntax,
52-
TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
54+
LocalFieldId, Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId,
55+
TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
5356
expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap},
5457
hir::{
5558
BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat,

crates/ide-db/src/apply_change.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
use base_db::SourceRootId;
44
use profile::Bytes;
55
use rustc_hash::FxHashSet;
6-
use salsa::{Database as _, Durability};
7-
use triomphe::Arc;
6+
use salsa::{Database as _, Durability, Setter as _};
87

9-
use crate::{ChangeWithProcMacros, RootDatabase, symbol_index::SymbolsDatabase};
8+
use crate::{
9+
ChangeWithProcMacros, RootDatabase,
10+
symbol_index::{LibraryRoots, LocalRoots},
11+
};
1012

1113
impl RootDatabase {
1214
pub fn request_cancellation(&mut self) {
@@ -29,8 +31,8 @@ impl RootDatabase {
2931
local_roots.insert(root_id);
3032
}
3133
}
32-
self.set_local_roots_with_durability(Arc::new(local_roots), Durability::MEDIUM);
33-
self.set_library_roots_with_durability(Arc::new(library_roots), Durability::MEDIUM);
34+
LocalRoots::get(self).set_roots(self).to(local_roots);
35+
LibraryRoots::get(self).set_roots(self).to(library_roots);
3436
}
3537
change.apply(self);
3638
}

crates/ide-db/src/items_locator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use hir::{Complete, Crate, ItemInNs, Module, import_map};
1010
use crate::{
1111
RootDatabase,
1212
imports::import_assets::NameToImport,
13-
symbol_index::{self, SymbolsDatabase as _},
13+
symbol_index::{self, SymbolIndex},
1414
};
1515

1616
/// A value to use, when uncertain which limit to pick.
@@ -110,7 +110,7 @@ pub fn items_with_name_in_module<T>(
110110
local_query
111111
}
112112
};
113-
local_query.search(&[db.module_symbols(module)], |local_candidate| {
113+
local_query.search(&[SymbolIndex::module_symbols(db, module)], |local_candidate| {
114114
cb(match local_candidate.def {
115115
hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def),
116116
def => ItemInNs::from(def),

crates/ide-db/src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use hir::{
6464
};
6565
use triomphe::Arc;
6666

67-
use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
67+
use crate::line_index::LineIndex;
6868
pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
6969

7070
pub use ::line_index;
@@ -195,8 +195,12 @@ impl RootDatabase {
195195
db.set_all_crates(Arc::new(Box::new([])));
196196
CrateGraphBuilder::default().set_in_db(&mut db);
197197
db.set_proc_macros_with_durability(Default::default(), Durability::MEDIUM);
198-
db.set_local_roots_with_durability(Default::default(), Durability::MEDIUM);
199-
db.set_library_roots_with_durability(Default::default(), Durability::MEDIUM);
198+
_ = crate::symbol_index::LibraryRoots::builder(Default::default())
199+
.durability(Durability::MEDIUM)
200+
.new(&db);
201+
_ = crate::symbol_index::LocalRoots::builder(Default::default())
202+
.durability(Durability::MEDIUM)
203+
.new(&db);
200204
db.set_expand_proc_attr_macros_with_durability(false, Durability::HIGH);
201205
db.update_base_query_lru_capacities(lru_capacity);
202206
db

crates/ide-db/src/prime_caches.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use salsa::{Cancelled, Database};
1111
use crate::{
1212
FxIndexMap, RootDatabase,
1313
base_db::{Crate, RootQueryDb},
14-
symbol_index::SymbolsDatabase,
14+
symbol_index::SymbolIndex,
1515
};
1616

1717
/// We're indexing many crates.
@@ -107,8 +107,9 @@ pub fn parallel_prime_caches(
107107
Ok::<_, crossbeam_channel::SendError<_>>(())
108108
};
109109
let handle_symbols = |module| {
110-
let cancelled =
111-
Cancelled::catch(AssertUnwindSafe(|| _ = db.module_symbols(module)));
110+
let cancelled = Cancelled::catch(AssertUnwindSafe(|| {
111+
_ = SymbolIndex::module_symbols(&db, module)
112+
}));
112113

113114
match cancelled {
114115
Ok(()) => progress_sender

crates/ide-db/src/symbol_index.rs

Lines changed: 89 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use std::{
2727
ops::ControlFlow,
2828
};
2929

30-
use base_db::{RootQueryDb, SourceDatabase, SourceRootId};
30+
use base_db::{RootQueryDb, SourceRootId};
3131
use fst::{Automaton, Streamer, raw::IndexedValue};
3232
use hir::{
3333
Crate, Module,
@@ -37,7 +37,6 @@ use hir::{
3737
};
3838
use rayon::prelude::*;
3939
use rustc_hash::FxHashSet;
40-
use triomphe::Arc;
4140

4241
use crate::RootDatabase;
4342

@@ -102,63 +101,26 @@ impl Query {
102101
}
103102
}
104103

105-
#[query_group::query_group]
106-
pub trait SymbolsDatabase: HirDatabase + SourceDatabase {
107-
/// The symbol index for a given module. These modules should only be in source roots that
108-
/// are inside local_roots.
109-
// FIXME: Is it worth breaking the encapsulation boundary of `hir`, and make this take a `ModuleId`,
110-
// in order for it to be a non-interned query?
111-
#[salsa::invoke_interned(module_symbols)]
112-
fn module_symbols(&self, module: Module) -> Arc<SymbolIndex>;
113-
114-
/// The symbol index for a given source root within library_roots.
115-
#[salsa::invoke_interned(library_symbols)]
116-
fn library_symbols(&self, source_root_id: SourceRootId) -> Arc<SymbolIndex>;
117-
118-
#[salsa::transparent]
119-
/// The symbol indices of modules that make up a given crate.
120-
fn crate_symbols(&self, krate: Crate) -> Box<[Arc<SymbolIndex>]>;
121-
122-
/// The set of "local" (that is, from the current workspace) roots.
123-
/// Files in local roots are assumed to change frequently.
124-
#[salsa::input]
125-
fn local_roots(&self) -> Arc<FxHashSet<SourceRootId>>;
126-
127-
/// The set of roots for crates.io libraries.
128-
/// Files in libraries are assumed to never change.
129-
#[salsa::input]
130-
fn library_roots(&self) -> Arc<FxHashSet<SourceRootId>>;
131-
}
132-
133-
fn library_symbols(db: &dyn SymbolsDatabase, source_root_id: SourceRootId) -> Arc<SymbolIndex> {
134-
let _p = tracing::info_span!("library_symbols").entered();
135-
136-
// We call this without attaching because this runs in parallel, so we need to attach here.
137-
hir::attach_db(db, || {
138-
let mut symbol_collector = SymbolCollector::new(db);
139-
140-
db.source_root_crates(source_root_id)
141-
.iter()
142-
.flat_map(|&krate| Crate::from(krate).modules(db))
143-
// we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing,
144-
// as the index for a library is not going to really ever change, and we do not want to store each
145-
// the module or crate indices for those in salsa unless we need to.
146-
.for_each(|module| symbol_collector.collect(module));
147-
148-
Arc::new(SymbolIndex::new(symbol_collector.finish()))
149-
})
104+
/// The set of roots for crates.io libraries.
105+
/// Files in libraries are assumed to never change.
106+
#[salsa::input(singleton, debug)]
107+
pub struct LibraryRoots {
108+
#[returns(ref)]
109+
pub roots: FxHashSet<SourceRootId>,
150110
}
151111

152-
fn module_symbols(db: &dyn SymbolsDatabase, module: Module) -> Arc<SymbolIndex> {
153-
let _p = tracing::info_span!("module_symbols").entered();
154-
155-
// We call this without attaching because this runs in parallel, so we need to attach here.
156-
hir::attach_db(db, || Arc::new(SymbolIndex::new(SymbolCollector::new_module(db, module))))
112+
/// The set of "local" (that is, from the current workspace) roots.
113+
/// Files in local roots are assumed to change frequently.
114+
#[salsa::input(singleton, debug)]
115+
pub struct LocalRoots {
116+
#[returns(ref)]
117+
pub roots: FxHashSet<SourceRootId>,
157118
}
158119

159-
pub fn crate_symbols(db: &dyn SymbolsDatabase, krate: Crate) -> Box<[Arc<SymbolIndex>]> {
120+
/// The symbol indices of modules that make up a given crate.
121+
pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex]> {
160122
let _p = tracing::info_span!("crate_symbols").entered();
161-
krate.modules(db).into_iter().map(|module| db.module_symbols(module)).collect()
123+
krate.modules(db).into_iter().map(|module| SymbolIndex::module_symbols(db, module)).collect()
162124
}
163125

164126
// Feature: Workspace Symbol
@@ -190,20 +152,26 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
190152
let _p = tracing::info_span!("world_symbols", query = ?query.query).entered();
191153

192154
let indices: Vec<_> = if query.libs {
193-
db.library_roots()
155+
LibraryRoots::get(db)
156+
.roots(db)
194157
.par_iter()
195-
.map_with(db.clone(), |snap, &root| snap.library_symbols(root))
158+
.for_each_with(db.clone(), |snap, &root| _ = SymbolIndex::library_symbols(snap, root));
159+
LibraryRoots::get(db)
160+
.roots(db)
161+
.iter()
162+
.map(|&root| SymbolIndex::library_symbols(db, root))
196163
.collect()
197164
} else {
198165
let mut crates = Vec::new();
199166

200-
for &root in db.local_roots().iter() {
167+
for &root in LocalRoots::get(db).roots(db).iter() {
201168
crates.extend(db.source_root_crates(root).iter().copied())
202169
}
203-
let indices: Vec<_> = crates
204-
.into_par_iter()
205-
.map_with(db.clone(), |snap, krate| snap.crate_symbols(krate.into()))
206-
.collect();
170+
crates
171+
.par_iter()
172+
.for_each_with(db.clone(), |snap, &krate| _ = crate_symbols(snap, krate.into()));
173+
let indices: Vec<_> =
174+
crates.into_iter().map(|krate| crate_symbols(db, krate.into())).collect();
207175
indices.iter().flat_map(|indices| indices.iter().cloned()).collect()
208176
};
209177

@@ -221,6 +189,62 @@ pub struct SymbolIndex {
221189
map: fst::Map<Vec<u8>>,
222190
}
223191

192+
impl SymbolIndex {
193+
/// The symbol index for a given source root within library_roots.
194+
pub fn library_symbols(db: &dyn HirDatabase, source_root_id: SourceRootId) -> &SymbolIndex {
195+
// FIXME:
196+
#[salsa::interned]
197+
struct InternedSourceRootId {
198+
id: SourceRootId,
199+
}
200+
#[salsa::tracked(returns(ref))]
201+
fn library_symbols(
202+
db: &dyn HirDatabase,
203+
source_root_id: InternedSourceRootId<'_>,
204+
) -> SymbolIndex {
205+
let _p = tracing::info_span!("library_symbols").entered();
206+
207+
// We call this without attaching because this runs in parallel, so we need to attach here.
208+
hir::attach_db(db, || {
209+
let mut symbol_collector = SymbolCollector::new(db);
210+
211+
db.source_root_crates(source_root_id.id(db))
212+
.iter()
213+
.flat_map(|&krate| Crate::from(krate).modules(db))
214+
// we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing,
215+
// as the index for a library is not going to really ever change, and we do not want to store each
216+
// the module or crate indices for those in salsa unless we need to.
217+
.for_each(|module| symbol_collector.collect(module));
218+
219+
SymbolIndex::new(symbol_collector.finish())
220+
})
221+
}
222+
library_symbols(db, InternedSourceRootId::new(db, source_root_id))
223+
}
224+
225+
/// The symbol index for a given module. These modules should only be in source roots that
226+
/// are inside local_roots.
227+
pub fn module_symbols(db: &dyn HirDatabase, module: Module) -> &SymbolIndex {
228+
// FIXME:
229+
#[salsa::interned]
230+
struct InternedModuleId {
231+
id: hir::ModuleId,
232+
}
233+
234+
#[salsa::tracked(returns(ref))]
235+
fn module_symbols(db: &dyn HirDatabase, module: InternedModuleId<'_>) -> SymbolIndex {
236+
let _p = tracing::info_span!("module_symbols").entered();
237+
238+
// We call this without attaching because this runs in parallel, so we need to attach here.
239+
hir::attach_db(db, || {
240+
SymbolIndex::new(SymbolCollector::new_module(db, module.id(db).into()))
241+
})
242+
}
243+
244+
module_symbols(db, InternedModuleId::new(db, hir::ModuleId::from(module)))
245+
}
246+
}
247+
224248
impl fmt::Debug for SymbolIndex {
225249
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226250
f.debug_struct("SymbolIndex").field("n_symbols", &self.symbols.len()).finish()
@@ -309,7 +333,7 @@ impl SymbolIndex {
309333
impl Query {
310334
pub(crate) fn search<'sym, T>(
311335
self,
312-
indices: &'sym [Arc<SymbolIndex>],
336+
indices: &'sym [&SymbolIndex],
313337
cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
314338
) -> Option<T> {
315339
let _p = tracing::info_span!("symbol_index::Query::search").entered();
@@ -344,7 +368,7 @@ impl Query {
344368

345369
fn search_maps<'sym, T>(
346370
&self,
347-
indices: &'sym [Arc<SymbolIndex>],
371+
indices: &'sym [&SymbolIndex],
348372
mut stream: fst::map::Union<'_>,
349373
mut cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
350374
) -> Option<T> {
@@ -397,7 +421,7 @@ impl Query {
397421
mod tests {
398422

399423
use expect_test::expect_file;
400-
use salsa::Durability;
424+
use salsa::Setter;
401425
use test_fixture::{WORKSPACE, WithFixture};
402426

403427
use super::*;
@@ -535,7 +559,7 @@ pub struct Foo;
535559

536560
let mut local_roots = FxHashSet::default();
537561
local_roots.insert(WORKSPACE);
538-
db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
562+
LocalRoots::get(&db).set_roots(&mut db).to(local_roots);
539563

540564
let mut query = Query::new("Foo".to_owned());
541565
let mut symbols = world_symbols(&db, query.clone());

crates/ide-ssr/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ pub use crate::{errors::SsrError, from_comment::ssr_from_comment, matching::Matc
8080

8181
use crate::{errors::bail, matching::MatchFailureReason};
8282
use hir::{FileRange, Semantics};
83-
use ide_db::symbol_index::SymbolsDatabase;
83+
use ide_db::symbol_index::LocalRoots;
8484
use ide_db::text_edit::TextEdit;
8585
use ide_db::{EditionedFileId, FileId, FxHashMap, RootDatabase, base_db::SourceDatabase};
8686
use resolving::ResolvedRule;
@@ -138,8 +138,8 @@ impl<'db> MatchFinder<'db> {
138138

139139
/// Constructs an instance using the start of the first file in `db` as the lookup context.
140140
pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result<MatchFinder<'db>, SsrError> {
141-
if let Some(first_file_id) = db
142-
.local_roots()
141+
if let Some(first_file_id) = LocalRoots::get(db)
142+
.roots(db)
143143
.iter()
144144
.next()
145145
.and_then(|root| db.source_root(*root).source_root(db).iter().next())

crates/ide-ssr/src/search.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use ide_db::{
99
EditionedFileId, FileId, FxHashSet,
1010
defs::Definition,
1111
search::{SearchScope, UsageSearchResult},
12+
symbol_index::LocalRoots,
1213
};
1314
use syntax::{AstNode, SyntaxKind, SyntaxNode, ast};
1415

@@ -156,8 +157,7 @@ impl<'db> MatchFinder<'db> {
156157
if self.restrict_ranges.is_empty() {
157158
// Unrestricted search.
158159
use ide_db::base_db::SourceDatabase;
159-
use ide_db::symbol_index::SymbolsDatabase;
160-
for &root in self.sema.db.local_roots().iter() {
160+
for &root in LocalRoots::get(self.sema.db).roots(self.sema.db).iter() {
161161
let sr = self.sema.db.source_root(root).source_root(self.sema.db);
162162
for file_id in sr.iter() {
163163
callback(file_id);

0 commit comments

Comments
 (0)