2019-09-30 03:58:53 -05:00
|
|
|
//! FIXME: write short doc here
|
|
|
|
|
2019-09-20 12:38:16 -05:00
|
|
|
use std::sync::Arc;
|
2019-01-08 13:33:36 -06:00
|
|
|
|
2019-01-17 05:11:00 -06:00
|
|
|
use ra_db::{
|
2019-06-26 01:12:46 -05:00
|
|
|
salsa::{self, Database, Durability},
|
2019-11-03 16:14:17 -06:00
|
|
|
Canceled, CheckCanceled, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath,
|
|
|
|
SourceDatabase, SourceDatabaseExt, SourceRootId,
|
2019-01-17 05:11:00 -06:00
|
|
|
};
|
2019-09-08 01:48:45 -05:00
|
|
|
use rustc_hash::FxHashMap;
|
2019-01-08 13:33:36 -06:00
|
|
|
|
2019-07-04 15:05:17 -05:00
|
|
|
use crate::{
|
|
|
|
symbol_index::{self, SymbolsDatabase},
|
2019-08-22 06:44:16 -05:00
|
|
|
FeatureFlags, LineIndex,
|
2019-07-04 15:05:17 -05:00
|
|
|
};
|
2019-01-08 13:33:36 -06:00
|
|
|
|
2019-01-25 06:16:50 -06:00
|
|
|
#[salsa::database(
|
2019-01-26 02:20:30 -06:00
|
|
|
ra_db::SourceDatabaseStorage,
|
2019-10-14 08:20:55 -05:00
|
|
|
ra_db::SourceDatabaseExtStorage,
|
2019-01-25 14:27:16 -06:00
|
|
|
LineIndexDatabaseStorage,
|
|
|
|
symbol_index::SymbolsDatabaseStorage,
|
2019-06-26 13:50:42 -05:00
|
|
|
hir::db::InternDatabaseStorage,
|
2019-06-01 13:17:57 -05:00
|
|
|
hir::db::AstDatabaseStorage,
|
2019-11-23 05:44:43 -06:00
|
|
|
hir::db::DefDatabaseStorage,
|
2019-06-01 13:17:57 -05:00
|
|
|
hir::db::HirDatabaseStorage
|
2019-01-25 06:16:50 -06:00
|
|
|
)]
|
2019-01-08 13:33:36 -06:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub(crate) struct RootDatabase {
|
|
|
|
runtime: salsa::Runtime<RootDatabase>,
|
2019-08-22 06:44:16 -05:00
|
|
|
pub(crate) feature_flags: Arc<FeatureFlags>,
|
2019-09-08 01:48:45 -05:00
|
|
|
pub(crate) debug_data: Arc<DebugData>,
|
2019-09-20 12:38:16 -05:00
|
|
|
pub(crate) last_gc: crate::wasm_shims::Instant,
|
|
|
|
pub(crate) last_gc_check: crate::wasm_shims::Instant,
|
2019-01-08 13:33:36 -06:00
|
|
|
}
|
|
|
|
|
2019-10-14 08:20:55 -05:00
|
|
|
impl FileLoader for RootDatabase {
|
|
|
|
fn file_text(&self, file_id: FileId) -> Arc<String> {
|
|
|
|
FileLoaderDelegate(self).file_text(file_id)
|
|
|
|
}
|
|
|
|
fn resolve_relative_path(
|
|
|
|
&self,
|
|
|
|
anchor: FileId,
|
|
|
|
relative_path: &RelativePath,
|
|
|
|
) -> Option<FileId> {
|
|
|
|
FileLoaderDelegate(self).resolve_relative_path(anchor, relative_path)
|
|
|
|
}
|
|
|
|
fn relevant_crates(&self, file_id: FileId) -> Arc<Vec<CrateId>> {
|
|
|
|
FileLoaderDelegate(self).relevant_crates(file_id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-08 01:48:45 -05:00
|
|
|
impl hir::debug::HirDebugHelper for RootDatabase {
|
|
|
|
fn crate_name(&self, krate: CrateId) -> Option<String> {
|
|
|
|
self.debug_data.crate_names.get(&krate).cloned()
|
|
|
|
}
|
|
|
|
fn file_path(&self, file_id: FileId) -> Option<String> {
|
|
|
|
let source_root_id = self.file_source_root(file_id);
|
|
|
|
let source_root_path = self.debug_data.root_paths.get(&source_root_id)?;
|
|
|
|
let file_path = self.file_relative_path(file_id);
|
2019-10-15 09:44:26 -05:00
|
|
|
Some(format!("{}/{}", source_root_path, file_path))
|
2019-09-08 01:48:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-08 13:33:36 -06:00
|
|
|
impl salsa::Database for RootDatabase {
|
|
|
|
fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
|
|
|
|
&self.runtime
|
|
|
|
}
|
2019-11-26 02:29:20 -06:00
|
|
|
fn salsa_runtime_mut(&mut self) -> &mut salsa::Runtime<Self> {
|
|
|
|
&mut self.runtime
|
|
|
|
}
|
2019-01-10 03:20:32 -06:00
|
|
|
fn on_propagated_panic(&self) -> ! {
|
|
|
|
Canceled::throw()
|
|
|
|
}
|
cancel salsa's validation
This small fix should improve rust-analyzer resopnsivness for
real-time operations like onEnter handling.
Turns out, salsa's validation can take hundreds of milliseconds, and,
in case no changes were made, it won't be triggering any queries.
Because we check for cancellation in queries, that means that
validation is not cancellable!
What this PR does is injecting check_canceled checks into validation,
by using salsa's event API, which wasn't meant to be used like this,
but, hey, it works!
Here's the onEnter handling before and after this change:
https://youtu.be/7-ffPzgvH7o
2019-05-30 01:51:25 -05:00
|
|
|
fn salsa_event(&self, event: impl Fn() -> salsa::Event<RootDatabase>) {
|
2019-06-12 10:05:02 -05:00
|
|
|
match event().kind {
|
|
|
|
salsa::EventKind::DidValidateMemoizedValue { .. }
|
|
|
|
| salsa::EventKind::WillExecute { .. } => {
|
|
|
|
self.check_canceled();
|
|
|
|
}
|
|
|
|
_ => (),
|
cancel salsa's validation
This small fix should improve rust-analyzer resopnsivness for
real-time operations like onEnter handling.
Turns out, salsa's validation can take hundreds of milliseconds, and,
in case no changes were made, it won't be triggering any queries.
Because we check for cancellation in queries, that means that
validation is not cancellable!
What this PR does is injecting check_canceled checks into validation,
by using salsa's event API, which wasn't meant to be used like this,
but, hey, it works!
Here's the onEnter handling before and after this change:
https://youtu.be/7-ffPzgvH7o
2019-05-30 01:51:25 -05:00
|
|
|
}
|
|
|
|
}
|
2019-01-08 13:33:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for RootDatabase {
|
|
|
|
fn default() -> RootDatabase {
|
2019-08-22 06:44:16 -05:00
|
|
|
RootDatabase::new(None, FeatureFlags::default())
|
2019-06-07 12:49:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RootDatabase {
|
2019-08-22 06:44:16 -05:00
|
|
|
pub fn new(lru_capacity: Option<usize>, feature_flags: FeatureFlags) -> RootDatabase {
|
2019-01-08 13:33:36 -06:00
|
|
|
let mut db = RootDatabase {
|
|
|
|
runtime: salsa::Runtime::default(),
|
2019-09-20 12:38:16 -05:00
|
|
|
last_gc: crate::wasm_shims::Instant::now(),
|
|
|
|
last_gc_check: crate::wasm_shims::Instant::now(),
|
2019-08-22 06:44:16 -05:00
|
|
|
feature_flags: Arc::new(feature_flags),
|
2019-09-08 01:48:45 -05:00
|
|
|
debug_data: Default::default(),
|
2019-01-08 13:33:36 -06:00
|
|
|
};
|
2019-06-26 01:12:46 -05:00
|
|
|
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
|
|
|
|
db.set_local_roots_with_durability(Default::default(), Durability::HIGH);
|
|
|
|
db.set_library_roots_with_durability(Default::default(), Durability::HIGH);
|
2019-06-07 12:49:29 -05:00
|
|
|
let lru_capacity = lru_capacity.unwrap_or(ra_db::DEFAULT_LRU_CAP);
|
|
|
|
db.query_mut(ra_db::ParseQuery).set_lru_capacity(lru_capacity);
|
|
|
|
db.query_mut(hir::db::ParseMacroQuery).set_lru_capacity(lru_capacity);
|
2019-06-30 07:03:23 -05:00
|
|
|
db.query_mut(hir::db::MacroExpandQuery).set_lru_capacity(lru_capacity);
|
2019-01-08 13:33:36 -06:00
|
|
|
db
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl salsa::ParallelDatabase for RootDatabase {
|
|
|
|
fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
|
|
|
|
salsa::Snapshot::new(RootDatabase {
|
|
|
|
runtime: self.runtime.snapshot(self),
|
2019-07-04 12:26:44 -05:00
|
|
|
last_gc: self.last_gc,
|
|
|
|
last_gc_check: self.last_gc_check,
|
2019-08-22 06:44:16 -05:00
|
|
|
feature_flags: Arc::clone(&self.feature_flags),
|
2019-09-08 01:48:45 -05:00
|
|
|
debug_data: Arc::clone(&self.debug_data),
|
2019-01-08 13:33:36 -06:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-25 14:27:16 -06:00
|
|
|
#[salsa::query_group(LineIndexDatabaseStorage)]
|
2019-01-26 02:20:30 -06:00
|
|
|
pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
|
2019-01-17 05:11:00 -06:00
|
|
|
fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
|
2019-01-08 13:33:36 -06:00
|
|
|
}
|
|
|
|
|
2019-10-11 14:56:17 -05:00
|
|
|
fn line_index(db: &impl LineIndexDatabase, file_id: FileId) -> Arc<LineIndex> {
|
2019-01-08 13:33:36 -06:00
|
|
|
let text = db.file_text(file_id);
|
|
|
|
Arc::new(LineIndex::new(&*text))
|
|
|
|
}
|
2019-09-08 01:48:45 -05:00
|
|
|
|
|
|
|
#[derive(Debug, Default, Clone)]
|
|
|
|
pub(crate) struct DebugData {
|
|
|
|
pub(crate) root_paths: FxHashMap<SourceRootId, String>,
|
|
|
|
pub(crate) crate_names: FxHashMap<CrateId, String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DebugData {
|
|
|
|
pub(crate) fn merge(&mut self, other: DebugData) {
|
|
|
|
self.root_paths.extend(other.root_paths.into_iter());
|
|
|
|
self.crate_names.extend(other.crate_names.into_iter());
|
|
|
|
}
|
|
|
|
}
|