Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/base-db/src/lib.rs')
-rw-r--r--crates/base-db/src/lib.rs108
1 files changed, 49 insertions, 59 deletions
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index 5baf4ce6f9..e438505c07 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -36,7 +36,6 @@ pub use query_group;
use rustc_hash::{FxHashSet, FxHasher};
use salsa::{Durability, Setter};
pub use semver::{BuildMetadata, Prerelease, Version, VersionReq};
-use syntax::{Parse, SyntaxError, ast};
use triomphe::Arc;
pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet};
@@ -236,36 +235,6 @@ pub struct SourceRootInput {
pub source_root: Arc<SourceRoot>,
}
-/// Database which stores all significant input facts: source code and project
-/// model. Everything else in rust-analyzer is derived from these queries.
-#[query_group::query_group]
-pub trait RootQueryDb: SourceDatabase + salsa::Database {
- /// Parses the file into the syntax tree.
- #[salsa::invoke(parse)]
- #[salsa::lru(128)]
- fn parse(&self, file_id: EditionedFileId) -> Parse<ast::SourceFile>;
-
- /// Returns the set of errors obtained from parsing the file including validation errors.
- #[salsa::transparent]
- fn parse_errors(&self, file_id: EditionedFileId) -> Option<&[SyntaxError]>;
-
- #[salsa::transparent]
- fn toolchain_channel(&self, krate: Crate) -> Option<ReleaseChannel>;
-
- /// Crates whose root file is in `id`.
- #[salsa::invoke_interned(source_root_crates)]
- fn source_root_crates(&self, id: SourceRootId) -> Arc<[Crate]>;
-
- #[salsa::transparent]
- fn relevant_crates(&self, file_id: FileId) -> Arc<[Crate]>;
-
- /// Returns the crates in topological order.
- ///
- /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
- #[salsa::input]
- fn all_crates(&self) -> Arc<Box<[Crate]>>;
-}
-
#[salsa_macros::db]
pub trait SourceDatabase: salsa::Database {
/// Text of the file.
@@ -353,46 +322,67 @@ impl CrateWorkspaceData {
}
}
-fn toolchain_channel(db: &dyn RootQueryDb, krate: Crate) -> Option<ReleaseChannel> {
+pub fn toolchain_channel(db: &dyn salsa::Database, krate: Crate) -> Option<ReleaseChannel> {
krate.workspace_data(db).toolchain.as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre))
}
-fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse<ast::SourceFile> {
- let _p = tracing::info_span!("parse", ?file_id).entered();
- let (file_id, edition) = file_id.unpack(db.as_dyn_database());
- let text = db.file_text(file_id).text(db);
- ast::SourceFile::parse(text, edition)
+#[salsa::input(singleton, debug)]
+struct AllCrates {
+ crates: std::sync::Arc<[Crate]>,
}
-fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option<&[SyntaxError]> {
- #[salsa_macros::tracked(returns(ref))]
- fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option<Box<[SyntaxError]>> {
- let errors = db.parse(file_id).errors();
- match &*errors {
- [] => None,
- [..] => Some(errors.into()),
- }
- }
- parse_errors(db, file_id).as_ref().map(|it| &**it)
+pub fn set_all_crates_with_durability(
+ db: &mut dyn salsa::Database,
+ crates: impl IntoIterator<Item = Crate>,
+ durability: Durability,
+) {
+ AllCrates::try_get(db)
+ .unwrap_or_else(|| AllCrates::new(db, std::sync::Arc::default()))
+ .set_crates(db)
+ .with_durability(durability)
+ .to(crates.into_iter().collect());
}
-fn source_root_crates(db: &dyn RootQueryDb, id: SourceRootId) -> Arc<[Crate]> {
- let crates = db.all_crates();
- crates
- .iter()
- .copied()
- .filter(|&krate| {
- let root_file = krate.data(db).root_file_id;
- db.file_source_root(root_file).source_root_id(db) == id
- })
- .collect()
+/// Returns the crates in topological order.
+///
+/// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications.
+pub fn all_crates(db: &dyn salsa::Database) -> std::sync::Arc<[Crate]> {
+ AllCrates::try_get(db).map_or(std::sync::Arc::default(), |all_crates| all_crates.crates(db))
+}
+
+// FIXME: VFS rewrite should allow us to get rid of this wrapper
+#[doc(hidden)]
+#[salsa::interned]
+pub struct InternedSourceRootId {
+ pub id: SourceRootId,
+}
+
+/// Crates whose root file is in `id`.
+pub fn source_root_crates(db: &dyn SourceDatabase, id: SourceRootId) -> &[Crate] {
+ #[salsa::tracked(returns(deref))]
+ pub fn source_root_crates<'db>(
+ db: &'db dyn SourceDatabase,
+ id: InternedSourceRootId<'db>,
+ ) -> Box<[Crate]> {
+ let crates = AllCrates::get(db).crates(db);
+ let id = id.id(db);
+ crates
+ .iter()
+ .copied()
+ .filter(|&krate| {
+ let root_file = krate.data(db).root_file_id;
+ db.file_source_root(root_file).source_root_id(db) == id
+ })
+ .collect()
+ }
+ source_root_crates(db, InternedSourceRootId::new(db, id))
}
-fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> {
+pub fn relevant_crates(db: &dyn SourceDatabase, file_id: FileId) -> &[Crate] {
let _p = tracing::info_span!("relevant_crates").entered();
let source_root = db.file_source_root(file_id);
- db.source_root_crates(source_root.source_root_id(db))
+ source_root_crates(db, source_root.source_root_id(db))
}
#[must_use]