From ed20a857f485a471369cd99b843af19a4d875ad0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:25:38 +0200 Subject: Rename ra_db -> base_db --- crates/ra_db/src/lib.rs | 167 ------------------------------------------------ 1 file changed, 167 deletions(-) delete mode 100644 crates/ra_db/src/lib.rs (limited to 'crates/ra_db/src/lib.rs') diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs deleted file mode 100644 index 73ac243d6..000000000 --- a/crates/ra_db/src/lib.rs +++ /dev/null @@ -1,167 +0,0 @@ -//! ra_db defines basic database traits. The concrete DB is defined by ra_ide. -mod cancellation; -mod input; -pub mod fixture; - -use std::{panic, sync::Arc}; - -use rustc_hash::FxHashSet; -use syntax::{ast, Parse, SourceFile, TextRange, TextSize}; - -pub use crate::{ - cancellation::Canceled, - input::{ - CrateData, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, FileId, ProcMacroId, - SourceRoot, SourceRootId, - }, -}; -pub use salsa; -pub use vfs::{file_set::FileSet, VfsPath}; - -#[macro_export] -macro_rules! impl_intern_key { - ($name:ident) => { - impl $crate::salsa::InternKey for $name { - fn from_intern_id(v: $crate::salsa::InternId) -> Self { - $name(v) - } - fn as_intern_id(&self) -> $crate::salsa::InternId { - self.0 - } - } - }; -} - -pub trait Upcast { - fn upcast(&self) -> &T; -} - -pub trait CheckCanceled { - /// Aborts current query if there are pending changes. - /// - /// rust-analyzer needs to be able to answer semantic questions about the - /// code while the code is being modified. A common problem is that a - /// long-running query is being calculated when a new change arrives. - /// - /// We can't just apply the change immediately: this will cause the pending - /// query to see inconsistent state (it will observe an absence of - /// repeatable read). So what we do is we **cancel** all pending queries - /// before applying the change. - /// - /// We implement cancellation by panicking with a special value and catching - /// it on the API boundary. Salsa explicitly supports this use-case. - fn check_canceled(&self); - - fn catch_canceled(&self, f: F) -> Result - where - Self: Sized + panic::RefUnwindSafe, - F: FnOnce(&Self) -> T + panic::UnwindSafe, - { - panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::() { - Ok(canceled) => *canceled, - Err(payload) => panic::resume_unwind(payload), - }) - } -} - -impl CheckCanceled for T { - fn check_canceled(&self) { - if self.salsa_runtime().is_current_revision_canceled() { - Canceled::throw() - } - } -} - -#[derive(Clone, Copy, Debug)] -pub struct FilePosition { - pub file_id: FileId, - pub offset: TextSize, -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct FileRange { - pub file_id: FileId, - pub range: TextRange, -} - -pub const DEFAULT_LRU_CAP: usize = 128; - -pub trait FileLoader { - /// Text of the file. - fn file_text(&self, file_id: FileId) -> Arc; - /// Note that we intentionally accept a `&str` and not a `&Path` here. This - /// method exists to handle `#[path = "/some/path.rs"] mod foo;` and such, - /// so the input is guaranteed to be utf-8 string. One might be tempted to - /// introduce some kind of "utf-8 path with / separators", but that's a bad idea. Behold - /// `#[path = "C://no/way"]` - fn resolve_path(&self, anchor: FileId, path: &str) -> Option; - fn relevant_crates(&self, file_id: FileId) -> Arc>; -} - -/// Database which stores all significant input facts: source code and project -/// model. Everything else in rust-analyzer is derived from these queries. -#[salsa::query_group(SourceDatabaseStorage)] -pub trait SourceDatabase: CheckCanceled + FileLoader + std::fmt::Debug { - // Parses the file into the syntax tree. - #[salsa::invoke(parse_query)] - fn parse(&self, file_id: FileId) -> Parse; - - /// The crate graph. - #[salsa::input] - fn crate_graph(&self) -> Arc; -} - -fn parse_query(db: &dyn SourceDatabase, file_id: FileId) -> Parse { - let _p = profile::span("parse_query").detail(|| format!("{:?}", file_id)); - let text = db.file_text(file_id); - SourceFile::parse(&*text) -} - -/// We don't want to give HIR knowledge of source roots, hence we extract these -/// methods into a separate DB. -#[salsa::query_group(SourceDatabaseExtStorage)] -pub trait SourceDatabaseExt: SourceDatabase { - #[salsa::input] - fn file_text(&self, file_id: FileId) -> Arc; - /// Path to a file, relative to the root of its source root. - /// Source root of the file. - #[salsa::input] - fn file_source_root(&self, file_id: FileId) -> SourceRootId; - /// Contents of the source root. - #[salsa::input] - fn source_root(&self, id: SourceRootId) -> Arc; - - fn source_root_crates(&self, id: SourceRootId) -> Arc>; -} - -fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc> { - let graph = db.crate_graph(); - let res = graph - .iter() - .filter(|&krate| { - let root_file = graph[krate].root_file_id; - db.file_source_root(root_file) == id - }) - .collect::>(); - Arc::new(res) -} - -/// Silly workaround for cyclic deps between the traits -pub struct FileLoaderDelegate(pub T); - -impl FileLoader for FileLoaderDelegate<&'_ T> { - fn file_text(&self, file_id: FileId) -> Arc { - SourceDatabaseExt::file_text(self.0, file_id) - } - fn resolve_path(&self, anchor: FileId, path: &str) -> Option { - // FIXME: this *somehow* should be platform agnostic... - let source_root = self.0.file_source_root(anchor); - let source_root = self.0.source_root(source_root); - source_root.file_set.resolve_path(anchor, path) - } - - fn relevant_crates(&self, file_id: FileId) -> Arc> { - let source_root = self.0.file_source_root(file_id); - self.0.source_root_crates(source_root) - } -} -- cgit v1.2.3