From 64b879d6a9aa61cf2ebe0154a292aa33e6412745 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 7 Oct 2018 11:32:02 +0300 Subject: add salsa dep, break the world --- crates/ra_analysis/Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index 28d95c581..4481e98d6 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml @@ -15,8 +15,7 @@ fst = "0.3.1" im = "12.0.0" ra_syntax = { path = "../ra_syntax" } ra_editor = { path = "../ra_editor" } -salsa = { path = "../salsa" } -rustc-hash = "1.0" +salsa = "0.4.1" [dev-dependencies] test_utils = { path = "../test_utils" } -- cgit v1.2.3 From 93d77e9b22c38a3587f3b7d5c3c6d517b66f3314 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 7 Oct 2018 11:32:21 +0300 Subject: remove our own copy of salsa salsa-rs/salsa is faster and more type safe --- crates/salsa/Cargo.toml | 8 -- crates/salsa/src/lib.rs | 293 -------------------------------------- crates/salsa/tests/integration.rs | 170 ---------------------- 3 files changed, 471 deletions(-) delete mode 100644 crates/salsa/Cargo.toml delete mode 100644 crates/salsa/src/lib.rs delete mode 100644 crates/salsa/tests/integration.rs (limited to 'crates') diff --git a/crates/salsa/Cargo.toml b/crates/salsa/Cargo.toml deleted file mode 100644 index 9eb83234f..000000000 --- a/crates/salsa/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "salsa" -version = "0.1.0" -authors = ["Aleksey Kladov "] - -[dependencies] -parking_lot = "0.6.3" -im = "12.0.0" diff --git a/crates/salsa/src/lib.rs b/crates/salsa/src/lib.rs deleted file mode 100644 index 35deed374..000000000 --- a/crates/salsa/src/lib.rs +++ /dev/null @@ -1,293 +0,0 @@ -extern crate im; -extern crate parking_lot; - -use std::{ - sync::Arc, - collections::{HashSet, HashMap}, - cell::RefCell, -}; -use parking_lot::Mutex; - -pub type GroundQueryFn = Box (D, OutputFingerprint) + Send + Sync + 'static>; -pub type QueryFn = Box, &D) -> (D, OutputFingerprint) + Send + Sync + 'static>; - -#[derive(Debug)] -pub struct Db { - db: Arc>, - query_config: Arc>, -} - -pub struct QueryConfig { - ground_fn: HashMap>, - query_fn: HashMap>, -} - -impl ::std::fmt::Debug for QueryConfig { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - ::std::fmt::Display::fmt("QueryConfig { ... }", f) - } -} - -#[derive(Debug)] -struct DbState { - ground_data: T, - gen: Gen, - graph: Mutex>)>>, -} - -#[derive(Debug)] -struct QueryRecord { - params: D, - output: D, - output_fingerprint: OutputFingerprint, - deps: Vec<(QueryId, OutputFingerprint)>, -} - -impl DbState { - fn record( - &self, - query_id: QueryId, - params: D, - output: D, - output_fingerprint: OutputFingerprint, - deps: Vec<(QueryId, OutputFingerprint)>, - ) { - let gen = self.gen; - let record = QueryRecord { - params, - output, - output_fingerprint, - deps, - }; - self.graph.lock().insert(query_id, (gen, Arc::new(record))); - } -} - -impl QueryConfig { - pub fn new() -> Self { - QueryConfig { - ground_fn: HashMap::new(), - query_fn: HashMap::new(), - } - } - pub fn with_ground_query( - mut self, - query_type: QueryTypeId, - query_fn: GroundQueryFn - ) -> Self { - let prev = self.ground_fn.insert(query_type, query_fn); - assert!(prev.is_none()); - self - } - pub fn with_query( - mut self, - query_type: QueryTypeId, - query_fn: QueryFn, - ) -> Self { - let prev = self.query_fn.insert(query_type, query_fn); - assert!(prev.is_none()); - self - } -} - -pub struct QueryCtx { - db: Arc>, - query_config: Arc>, - stack: RefCell>>, - executed: RefCell>, -} - -impl QueryCtx -where - D: Clone -{ - fn new(db: &Db) -> QueryCtx { - QueryCtx { - db: Arc::clone(&db.db), - query_config: Arc::clone(&db.query_config), - stack: RefCell::new(vec![Vec::new()]), - executed: RefCell::new(Vec::new()), - } - } - pub fn get( - &self, - query_id: QueryId, - params: D, - ) -> D { - let (res, output_fingerprint) = self.get_inner(query_id, params); - self.record_dep(query_id, output_fingerprint); - res - } - pub fn trace(&self) -> Vec { - ::std::mem::replace(&mut *self.executed.borrow_mut(), Vec::new()) - } - - fn get_inner( - &self, - query_id: QueryId, - params: D, - ) -> (D, OutputFingerprint) { - let (gen, record) = { - let guard = self.db.graph.lock(); - match guard.get(&query_id).map(|it| it.clone()){ - None => { - drop(guard); - return self.force(query_id, params); - }, - Some(it) => it, - } - }; - if gen == self.db.gen { - return (record.output.clone(), record.output_fingerprint) - } - if self.query_config.ground_fn.contains_key(&query_id.0) { - let (invalidated, record) = { - let guard = self.db.graph.lock(); - let (gen, ref record) = guard[&query_id]; - (gen == INVALIDATED, record.clone()) - }; - if invalidated { - return self.force(query_id, params); - } else { - return (record.output.clone(), record.output_fingerprint); - } - } - for (dep_query_id, prev_fingerprint) in record.deps.iter().cloned() { - let dep_params: D = { - let guard = self.db.graph.lock(); - guard[&dep_query_id] - .1 - .params - .clone() - }; - if prev_fingerprint != self.get_inner(dep_query_id, dep_params).1 { - return self.force(query_id, params) - } - } - let gen = self.db.gen; - { - let mut guard = self.db.graph.lock(); - guard[&query_id].0 = gen; - } - (record.output.clone(), record.output_fingerprint) - } - fn force( - &self, - query_id: QueryId, - params: D, - ) -> (D, OutputFingerprint) { - self.executed.borrow_mut().push(query_id.0); - self.stack.borrow_mut().push(Vec::new()); - - let (res, output_fingerprint) = if let Some(f) = self.query_config.ground_fn.get(&query_id.0) { - f(&self.db.ground_data, ¶ms) - } else if let Some(f) = self.query_config.query_fn.get(&query_id.0) { - f(self, ¶ms) - } else { - panic!("unknown query type: {:?}", query_id.0); - }; - - let res: D = res.into(); - - let deps = self.stack.borrow_mut().pop().unwrap(); - self.db.record(query_id, params, res.clone(), output_fingerprint, deps); - (res, output_fingerprint) - } - fn record_dep( - &self, - query_id: QueryId, - output_fingerprint: OutputFingerprint, - ) -> () { - let mut stack = self.stack.borrow_mut(); - let deps = stack.last_mut().unwrap(); - deps.push((query_id, output_fingerprint)) - } -} - -pub struct Invalidations { - types: HashSet, - ids: Vec, -} - -impl Invalidations { - pub fn new() -> Invalidations { - Invalidations { - types: HashSet::new(), - ids: Vec::new(), - } - } - pub fn invalidate( - &mut self, - query_type: QueryTypeId, - params: impl Iterator, - ) { - self.types.insert(query_type); - self.ids.extend(params.map(|it| QueryId(query_type, it))) - } -} - -impl Db -where - D: Clone -{ - pub fn new(query_config: QueryConfig, ground_data: T) -> Db { - Db { - db: Arc::new(DbState { ground_data, gen: Gen(0), graph: Default::default() }), - query_config: Arc::new(query_config), - } - } - pub fn ground_data(&self) -> &T { - &self.db.ground_data - } - pub fn with_ground_data( - &self, - ground_data: T, - invalidations: Invalidations, - ) -> Db { - for id in self.query_config.ground_fn.keys() { - assert!( - invalidations.types.contains(id), - "all ground queries must be invalidated" - ); - } - - let gen = Gen(self.db.gen.0 + 1); - let mut graph = self.db.graph.lock().clone(); - for id in invalidations.ids { - if let Some((gen, _)) = graph.get_mut(&id) { - *gen = INVALIDATED; - } - } - let graph = Mutex::new(graph); - Db { - db: Arc::new(DbState { ground_data, gen, graph }), - query_config: Arc::clone(&self.query_config) - } - } - pub fn query_ctx(&self) -> QueryCtx { - QueryCtx::new(self) - } - pub fn get( - &self, - query_id: QueryId, - params: D, - ) -> (D, Vec) { - let ctx = self.query_ctx(); - let res = ctx.get(query_id, params.into()); - let executed = ::std::mem::replace(&mut *ctx.executed.borrow_mut(), Vec::new()); - (res, executed) - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -struct Gen(u64); -const INVALIDATED: Gen = Gen(!0); -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct InputFingerprint(pub u64); -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct OutputFingerprint(pub u64); -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct QueryTypeId(pub u16); -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct QueryId(pub QueryTypeId, pub InputFingerprint); - diff --git a/crates/salsa/tests/integration.rs b/crates/salsa/tests/integration.rs deleted file mode 100644 index aed9219be..000000000 --- a/crates/salsa/tests/integration.rs +++ /dev/null @@ -1,170 +0,0 @@ -extern crate salsa; -use std::{ - iter::once, - sync::Arc, - collections::hash_map::{HashMap, DefaultHasher}, - any::Any, - hash::{Hash, Hasher}, -}; - -type State = HashMap; -type Data = Arc; -const GET_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(1); -const GET_FILES: salsa::QueryTypeId = salsa::QueryTypeId(2); -const FILE_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(3); -const TOTAL_NEWLINES: salsa::QueryTypeId = salsa::QueryTypeId(4); - -fn mk_ground_query( - state: &State, - params: &Data, - f: fn(&State, &T) -> R, -) -> (Data, salsa::OutputFingerprint) -where - T: 'static, - R: Hash + Send + Sync + 'static, -{ - let params = params.downcast_ref().unwrap(); - let result = f(state, params); - let fingerprint = o_print(&result); - (Arc::new(result), fingerprint) -} - -fn get(db: &salsa::Db, query_type: salsa::QueryTypeId, param: T) -> (Arc, Vec) -where - T: Hash + Send + Sync + 'static, - R: Send + Sync + 'static, -{ - let i_print = i_print(¶m); - let param = Arc::new(param); - let (res, trace) = db.get(salsa::QueryId(query_type, i_print), param); - (res.downcast().unwrap(), trace) -} - -struct QueryCtx<'a>(&'a salsa::QueryCtx); - -impl<'a> QueryCtx<'a> { - fn get_text(&self, id: u32) -> Arc { - let i_print = i_print(&id); - let text = self.0.get(salsa::QueryId(GET_TEXT, i_print), Arc::new(id)); - text.downcast().unwrap() - } - fn get_files(&self) -> Arc> { - let i_print = i_print(&()); - let files = self.0.get(salsa::QueryId(GET_FILES, i_print), Arc::new(())); - let res = files.downcast().unwrap(); - res - } - fn get_n_lines(&self, id: u32) -> usize { - let i_print = i_print(&id); - let n_lines = self.0.get(salsa::QueryId(FILE_NEWLINES, i_print), Arc::new(id)); - *n_lines.downcast().unwrap() - } -} - -fn mk_query( - query_ctx: &salsa::QueryCtx, - params: &Data, - f: fn(QueryCtx, &T) -> R, -) -> (Data, salsa::OutputFingerprint) -where - T: 'static, - R: Hash + Send + Sync + 'static, -{ - let params: &T = params.downcast_ref().unwrap(); - let query_ctx = QueryCtx(query_ctx); - let result = f(query_ctx, params); - let fingerprint = o_print(&result); - (Arc::new(result), fingerprint) -} - -fn mk_queries() -> salsa::QueryConfig { - salsa::QueryConfig::::new() - .with_ground_query(GET_TEXT, Box::new(|state, id| { - mk_ground_query::(state, id, |state, id| state[id].clone()) - })) - .with_ground_query(GET_FILES, Box::new(|state, id| { - mk_ground_query::<(), Vec>(state, id, |state, &()| state.keys().cloned().collect()) - })) - .with_query(FILE_NEWLINES, Box::new(|query_ctx, id| { - mk_query(query_ctx, id, |query_ctx, &id| { - let text = query_ctx.get_text(id); - text.lines().count() - }) - })) - .with_query(TOTAL_NEWLINES, Box::new(|query_ctx, id| { - mk_query(query_ctx, id, |query_ctx, &()| { - let mut total = 0; - for &id in query_ctx.get_files().iter() { - total += query_ctx.get_n_lines(id) - } - total - }) - })) -} - -#[test] -fn test_number_of_lines() { - let mut state = State::new(); - let db = salsa::Db::new(mk_queries(), state.clone()); - let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ()); - assert_eq!(*newlines, 0); - assert_eq!(trace.len(), 2); - let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ()); - assert_eq!(*newlines, 0); - assert_eq!(trace.len(), 0); - - state.insert(1, "hello\nworld".to_string()); - let mut inv = salsa::Invalidations::new(); - inv.invalidate(GET_TEXT, once(i_print(&1u32))); - inv.invalidate(GET_FILES, once(i_print(&()))); - let db = db.with_ground_data(state.clone(), inv); - let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ()); - assert_eq!(*newlines, 2); - assert_eq!(trace.len(), 4); - - state.insert(2, "spam\neggs".to_string()); - let mut inv = salsa::Invalidations::new(); - inv.invalidate(GET_TEXT, once(i_print(&2u32))); - inv.invalidate(GET_FILES, once(i_print(&()))); - let db = db.with_ground_data(state.clone(), inv); - let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ()); - assert_eq!(*newlines, 4); - assert_eq!(trace.len(), 4); - - let mut invs = vec![]; - for i in 0..10 { - let id = i + 10; - invs.push(i_print(&id)); - state.insert(id, "spam".to_string()); - } - let mut inv = salsa::Invalidations::new(); - inv.invalidate(GET_TEXT, invs.into_iter()); - inv.invalidate(GET_FILES, once(i_print(&()))); - let db = db.with_ground_data(state.clone(), inv); - let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ()); - assert_eq!(*newlines, 14); - assert_eq!(trace.len(), 22); - - state.insert(15, String::new()); - let mut inv = salsa::Invalidations::new(); - inv.invalidate(GET_TEXT, once(i_print(&15u32))); - inv.invalidate(GET_FILES, once(i_print(&()))); - let db = db.with_ground_data(state.clone(), inv); - let (newlines, trace) = get::<(), usize>(&db, TOTAL_NEWLINES, ()); - assert_eq!(*newlines, 13); - assert_eq!(trace.len(), 4); -} - -fn o_print(x: &T) -> salsa::OutputFingerprint { - let mut hasher = DefaultHasher::new(); - x.hash(&mut hasher); - let hash = hasher.finish(); - salsa::OutputFingerprint(hash) -} - -fn i_print(x: &T) -> salsa::InputFingerprint { - let mut hasher = DefaultHasher::new(); - x.hash(&mut hasher); - let hash = hasher.finish(); - salsa::InputFingerprint(hash) -} -- cgit v1.2.3 From d8aee31a600a8a8a56ddee0ee2ff1c5d5ba2320b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 7 Oct 2018 13:18:25 +0300 Subject: start salsa migration --- crates/ra_analysis/src/db/mod.rs | 226 ++++++++++++++++++++++++--------- crates/ra_analysis/src/lib.rs | 4 +- crates/ra_analysis/src/roots.rs | 68 ++++++---- crates/ra_analysis/src/symbol_index.rs | 9 ++ crates/ra_editor/src/line_index.rs | 2 +- crates/ra_editor/src/symbols.rs | 2 +- crates/ra_syntax/src/lib.rs | 2 +- 7 files changed, 221 insertions(+), 92 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs index 4eb7d922d..4b3e0fc90 100644 --- a/crates/ra_analysis/src/db/mod.rs +++ b/crates/ra_analysis/src/db/mod.rs @@ -1,85 +1,193 @@ -mod imp; - use std::{ + fmt, sync::Arc, + hash::{Hash, Hasher}, + collections::HashSet, }; -use im; use salsa; -use crate::{FileId, imp::FileResolverImp}; +use ra_syntax::File; +use ra_editor::{LineIndex}; +use crate::{ + symbol_index::SymbolIndex, + FileId, FileResolverImp +}; -#[derive(Debug, Default, Clone)] -pub(crate) struct State { - pub(crate) file_map: im::HashMap>, - pub(crate) file_resolver: FileResolverImp +#[derive(Default)] +pub(crate) struct RootDatabase { + runtime: salsa::runtime::Runtime, } -#[derive(Debug)] -pub(crate) struct Db { - imp: imp::Db, +impl fmt::Debug for RootDatabase { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("RootDatabase { ... }") + } } -#[derive(Clone, Copy)] -pub(crate) struct QueryCtx<'a> { - imp: &'a salsa::QueryCtx, +impl salsa::Database for RootDatabase { + fn salsa_runtime(&self) -> &salsa::runtime::Runtime { + &self.runtime + } } -pub(crate) struct Query(pub(crate) u16, pub(crate) fn(QueryCtx, &T) -> R); - -pub(crate) struct QueryRegistry { - imp: imp::QueryRegistry, +salsa::database_storage! { + pub(crate) struct RootDatabaseStorage for RootDatabase { + impl FilesDatabase { + fn file_text() for FileTextQuery; + fn file_set() for FileSetQuery; + } + impl SyntaxDatabase { + fn file_syntax() for FileSyntaxQuery; + fn file_lines() for FileLinesQuery; + fn file_symbols() for FileSymbolsQuery; + } + } } -impl Default for Db { - fn default() -> Db { - Db::new() +salsa::query_group! { + pub(crate) trait FilesDatabase: salsa::Database { + fn file_text(file_id: FileId) -> Arc { + type FileTextQuery; + storage input; + } + fn file_set(key: ()) -> Arc { + type FileSetQuery; + storage input; + } } } -impl Db { - pub(crate) fn new() -> Db { - let reg = QueryRegistry::new(); - Db { imp: imp::Db::new(reg.imp) } - } - pub(crate) fn state(&self) -> &State { - self.imp.imp.ground_data() - } - pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db { - Db { imp: self.imp.with_changes(new_state, changed_files, resolver_changed) } - } - pub(crate) fn make_query R, R>(&self, f: F) -> R { - let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; - f(ctx) - } - #[allow(unused)] - pub(crate) fn trace_query R, R>(&self, f: F) -> (R, Vec<&'static str>) { - let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; - let res = f(ctx); - let trace = self.imp.extract_trace(ctx.imp); - (res, trace) - } +#[derive(Default, Debug)] +pub(crate) struct FileSet { + pub(crate) files: HashSet, + pub(crate) resolver: FileResolverImp, } -impl<'a> QueryCtx<'a> { - pub(crate) fn get(&self, q: Q, params: Q::Params) -> Arc { - q.get(self, params) +impl PartialEq for FileSet { + fn eq(&self, other: &FileSet) -> bool { + self.files == other.files } } -pub(crate) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc { - imp::file_text(ctx, file_id) +impl Eq for FileSet { } -pub(crate) fn file_set(ctx: QueryCtx) -> Arc<(Vec, FileResolverImp)> { - imp::file_set(ctx) -} -impl QueryRegistry { - fn new() -> QueryRegistry { - let mut reg = QueryRegistry { imp: imp::QueryRegistry::new() }; - crate::queries::register_queries(&mut reg); - crate::module_map::register_queries(&mut reg); - reg +impl Hash for FileSet { + fn hash(&self, hasher: &mut H) { + let mut files = self.files.iter().cloned().collect::>(); + files.sort(); + files.hash(hasher); } - pub(crate) fn add(&mut self, q: Q, name: &'static str) { - self.imp.add(q, name) +} + +salsa::query_group! { + pub(crate) trait SyntaxDatabase: FilesDatabase { + fn file_syntax(file_id: FileId) -> File { + type FileSyntaxQuery; + } + fn file_lines(file_id: FileId) -> Arc { + type FileLinesQuery; + } + fn file_symbols(file_id: FileId) -> Arc { + type FileSymbolsQuery; + } } } + +fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { + let text = db.file_text(file_id); + File::parse(&*text) +} +fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { + let text = db.file_text(file_id); + Arc::new(LineIndex::new(&*text)) +} +fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { + let syntax = db.file_syntax(file_id); + Arc::new(SymbolIndex::for_file(file_id, syntax)) +} + +// mod imp; + +// use std::{ +// sync::Arc, +// }; +// use im; +// use salsa; +// use {FileId, imp::FileResolverImp}; + +// #[derive(Debug, Default, Clone)] +// pub(crate) struct State { +// pub(crate) file_map: im::HashMap>, +// pub(crate) file_resolver: FileResolverImp +// } + +// #[derive(Debug)] +// pub(crate) struct Db { +// imp: imp::Db, +// } + +// #[derive(Clone, Copy)] +// pub(crate) struct QueryCtx<'a> { +// imp: &'a salsa::QueryCtx, +// } + +// pub(crate) struct Query(pub(crate) u16, pub(crate) fn(QueryCtx, &T) -> R); + +// pub(crate) struct QueryRegistry { +// imp: imp::QueryRegistry, +// } + +// impl Default for Db { +// fn default() -> Db { +// Db::new() +// } +// } + +// impl Db { +// pub(crate) fn new() -> Db { +// let reg = QueryRegistry::new(); +// Db { imp: imp::Db::new(reg.imp) } +// } +// pub(crate) fn state(&self) -> &State { +// self.imp.imp.ground_data() +// } +// pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db { +// Db { imp: self.imp.with_changes(new_state, changed_files, resolver_changed) } +// } +// pub(crate) fn make_query R, R>(&self, f: F) -> R { +// let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; +// f(ctx) +// } +// #[allow(unused)] +// pub(crate) fn trace_query R, R>(&self, f: F) -> (R, Vec<&'static str>) { +// let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; +// let res = f(ctx); +// let trace = self.imp.extract_trace(ctx.imp); +// (res, trace) +// } +// } + +// impl<'a> QueryCtx<'a> { +// pub(crate) fn get(&self, q: Q, params: Q::Params) -> Arc { +// q.get(self, params) +// } +// } + +// pub(crate) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc { +// imp::file_text(ctx, file_id) +// } + +// pub(crate) fn file_set(ctx: QueryCtx) -> Arc<(Vec, FileResolverImp)> { +// imp::file_set(ctx) +// } +// impl QueryRegistry { +// fn new() -> QueryRegistry { +// let mut reg = QueryRegistry { imp: imp::QueryRegistry::new() }; +// ::queries::register_queries(&mut reg); +// ::module_map::register_queries(&mut reg); +// reg +// } +// pub(crate) fn add(&mut self, q: Q, name: &'static str) { +// self.imp.add(q, name) +// } +// } diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 86c66236c..4c1ccdeaf 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -14,12 +14,12 @@ extern crate salsa; extern crate rustc_hash; mod symbol_index; -mod module_map; +// mod module_map; mod imp; mod job; mod roots; mod db; -mod queries; +// mod queries; mod descriptors; use std::{ diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 208acc4c2..7a7d1169e 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs @@ -1,11 +1,13 @@ use std::{ + collections::{HashMap, HashSet}, sync::Arc, panic, }; +use parking_lot::RwLock; use once_cell::sync::OnceCell; use rayon::prelude::*; -use rustc_hash::FxHashMap; +use salsa::Database; use ra_editor::LineIndex; use ra_syntax::File; @@ -14,7 +16,7 @@ use crate::{ imp::FileResolverImp, symbol_index::SymbolIndex, descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, - db::Db, + db::{self, FilesDatabase, SyntaxDatabase} }; pub(crate) trait SourceRoot { @@ -25,9 +27,9 @@ pub(crate) trait SourceRoot { fn symbols(&self, acc: &mut Vec>); } -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub(crate) struct WritableSourceRoot { - db: Db, + db: Arc>, } impl WritableSourceRoot { @@ -36,51 +38,61 @@ impl WritableSourceRoot { changes: &mut dyn Iterator)>, file_resolver: Option, ) -> WritableSourceRoot { - let resolver_changed = file_resolver.is_some(); - let mut changed_files = Vec::new(); - let mut new_state = self.db.state().clone(); - + let db = self.db.write(); + let mut changed = HashSet::new(); + let mut removed = HashSet::new(); for (file_id, text) in changes { - changed_files.push(file_id); match text { - Some(text) => { - new_state.file_map.insert(file_id, Arc::new(text)); - }, None => { - new_state.file_map.remove(&file_id); + removed.insert(file_id); + } + Some(text) => { + db.query(db::FileTextQuery) + .set(file_id, Arc::new(text)); + changed.insert(file_id); } } } - if let Some(file_resolver) = file_resolver { - new_state.file_resolver = file_resolver - } - WritableSourceRoot { - db: self.db.with_changes(new_state, &changed_files, resolver_changed) + if let Some(resolver) = file_resolver { + let mut files: HashSet = db.file_set(()) + .files + .clone(); + for file_id in removed { + files.remove(&file_id); + } + files.extend(changed); + db.query(db::FileSetQuery) + .set((), Arc::new(db::FileSet { files, resolver })) } + // TODO: reconcile sasla's API with our needs + // https://github.com/salsa-rs/salsa/issues/12 + self.clone() } } impl SourceRoot for WritableSourceRoot { fn module_tree(&self) -> Arc { - self.db.make_query(crate::module_map::module_tree) + unimplemented!() + //self.db.make_query(::module_map::module_tree) } fn contains(&self, file_id: FileId) -> bool { - self.db.state().file_map.contains_key(&file_id) + self.db.read().file_set(()).files.contains(&file_id) } fn lines(&self, file_id: FileId) -> Arc { - self.db.make_query(|ctx| crate::queries::file_lines(ctx, file_id)) + self.db.read().file_lines(file_id) } fn syntax(&self, file_id: FileId) -> File { - self.db.make_query(|ctx| crate::queries::file_syntax(ctx, file_id)) + self.db.read().file_syntax(file_id) } fn symbols<'a>(&'a self, acc: &mut Vec>) { - self.db.make_query(|ctx| { - let file_set = crate::queries::file_set(ctx); - let syms = file_set.0.iter() - .map(|file_id| crate::queries::file_symbols(ctx, *file_id)); - acc.extend(syms); - }); + let db = self.db.read(); + let symbols = db.file_set(()); + let symbols = symbols + .files + .iter() + .map(|&file_id| db.file_symbols(file_id)); + acc.extend(symbols); } } diff --git a/crates/ra_analysis/src/symbol_index.rs b/crates/ra_analysis/src/symbol_index.rs index e5d83d365..54672fde4 100644 --- a/crates/ra_analysis/src/symbol_index.rs +++ b/crates/ra_analysis/src/symbol_index.rs @@ -17,6 +17,15 @@ pub(crate) struct SymbolIndex { map: fst::Map, } +impl PartialEq for SymbolIndex { + fn eq(&self, other: &SymbolIndex) -> bool { + self.symbols == other.symbols + } +} + +impl Eq for SymbolIndex { +} + impl Hash for SymbolIndex { fn hash(&self, hasher: &mut H) { self.symbols.hash(hasher) diff --git a/crates/ra_editor/src/line_index.rs b/crates/ra_editor/src/line_index.rs index 6ccfdbd83..95d64b8a8 100644 --- a/crates/ra_editor/src/line_index.rs +++ b/crates/ra_editor/src/line_index.rs @@ -1,7 +1,7 @@ use superslice::Ext; use crate::TextUnit; -#[derive(Clone, Debug, Hash)] +#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct LineIndex { newlines: Vec, } diff --git a/crates/ra_editor/src/symbols.rs b/crates/ra_editor/src/symbols.rs index 6211ed547..d9e4b2df7 100644 --- a/crates/ra_editor/src/symbols.rs +++ b/crates/ra_editor/src/symbols.rs @@ -17,7 +17,7 @@ pub struct StructureNode { pub kind: SyntaxKind, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FileSymbol { pub name: SmolStr, pub node_range: TextRange, diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 5bb54aba1..7eba5ee61 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -59,7 +59,7 @@ use crate::{ yellow::{GreenNode}, }; -#[derive(Clone, Debug, Hash)] +#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct File { root: SyntaxNode } -- cgit v1.2.3 From d783371b862c15d6d402d68e8edce4e37d63796c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 8 Oct 2018 13:18:47 +0300 Subject: migrate modue map to salsa --- crates/ra_analysis/src/db/mod.rs | 7 +- crates/ra_analysis/src/descriptors.rs | 10 +- crates/ra_analysis/src/lib.rs | 2 +- crates/ra_analysis/src/module_map.rs | 286 +++++++++++++++++----------------- crates/ra_analysis/src/roots.rs | 32 ++-- 5 files changed, 172 insertions(+), 165 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs index 4b3e0fc90..c54d50252 100644 --- a/crates/ra_analysis/src/db/mod.rs +++ b/crates/ra_analysis/src/db/mod.rs @@ -9,7 +9,8 @@ use ra_syntax::File; use ra_editor::{LineIndex}; use crate::{ symbol_index::SymbolIndex, - FileId, FileResolverImp + module_map::{ModulesDatabase, ModuleTreeQuery, ModuleDescriptorQuery}, + FileId, FileResolverImp, }; #[derive(Default)] @@ -40,6 +41,10 @@ salsa::database_storage! { fn file_lines() for FileLinesQuery; fn file_symbols() for FileSymbolsQuery; } + impl ModulesDatabase { + fn module_tree() for ModuleTreeQuery; + fn module_descriptor() for ModuleDescriptorQuery; + } } } diff --git a/crates/ra_analysis/src/descriptors.rs b/crates/ra_analysis/src/descriptors.rs index f26dac875..8d9f38ca5 100644 --- a/crates/ra_analysis/src/descriptors.rs +++ b/crates/ra_analysis/src/descriptors.rs @@ -12,7 +12,7 @@ use crate::{ imp::FileResolverImp, }; -#[derive(Debug, Hash)] +#[derive(Debug, PartialEq, Eq, Hash)] pub struct ModuleDescriptor { pub submodules: Vec } @@ -43,7 +43,7 @@ pub struct Submodule { pub name: SmolStr, } -#[derive(Hash, Debug)] +#[derive(Debug, PartialEq, Eq, Hash)] pub(crate) struct ModuleTreeDescriptor { nodes: Vec, links: Vec, @@ -52,7 +52,7 @@ pub(crate) struct ModuleTreeDescriptor { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] struct Node(usize); -#[derive(Hash, Debug)] +#[derive(Hash, Debug, PartialEq, Eq)] struct NodeData { file_id: FileId, links: Vec, @@ -61,7 +61,7 @@ struct NodeData { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub(crate) struct Link(usize); -#[derive(Hash, Debug)] +#[derive(Hash, Debug, PartialEq, Eq)] struct LinkData { owner: Node, name: SmolStr, @@ -70,7 +70,7 @@ struct LinkData { } -#[derive(Clone, Debug, Hash)] +#[derive(Clone, Debug, Hash, PartialEq, Eq)] pub enum Problem { UnresolvedModule { candidate: RelativePathBuf, diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 4c1ccdeaf..d49132513 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -14,7 +14,7 @@ extern crate salsa; extern crate rustc_hash; mod symbol_index; -// mod module_map; +mod module_map; mod imp; mod job; mod roots; diff --git a/crates/ra_analysis/src/module_map.rs b/crates/ra_analysis/src/module_map.rs index c77c5cec6..95a770ae7 100644 --- a/crates/ra_analysis/src/module_map.rs +++ b/crates/ra_analysis/src/module_map.rs @@ -1,157 +1,157 @@ use std::sync::Arc; use crate::{ FileId, - db::{ - Query, QueryRegistry, QueryCtx, - file_set - }, - queries::file_syntax, + db::{SyntaxDatabase}, descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, }; -pub(crate) fn register_queries(reg: &mut QueryRegistry) { - reg.add(MODULE_DESCR, "MODULE_DESCR"); - reg.add(MODULE_TREE, "MODULE_TREE"); -} - -pub(crate) fn module_tree(ctx: QueryCtx) -> Arc { - ctx.get(MODULE_TREE, ()) -} - -const MODULE_DESCR: Query = Query(30, |ctx, &file_id| { - let file = file_syntax(ctx, file_id); - ModuleDescriptor::new(file.ast()) -}); - -const MODULE_TREE: Query<(), ModuleTreeDescriptor> = Query(31, |ctx, _| { - let file_set = file_set(ctx); - let mut files = Vec::new(); - for &file_id in file_set.0.iter() { - let module_descr = ctx.get(MODULE_DESCR, file_id); - files.push((file_id, module_descr)); - } - ModuleTreeDescriptor::new(files.iter().map(|(file_id, descr)| (*file_id, &**descr)), &file_set.1) -}); - -#[cfg(test)] -mod tests { - use std::collections::HashMap; - use im; - use relative_path::{RelativePath, RelativePathBuf}; - use crate::{ - db::{Db}, - imp::FileResolverImp, - FileId, FileResolver, - }; - use super::*; - - #[derive(Debug)] - struct FileMap(im::HashMap); - - impl FileResolver for FileMap { - fn file_stem(&self, file_id: FileId) -> String { - self.0[&file_id].file_stem().unwrap().to_string() +salsa::query_group! { + pub(crate) trait ModulesDatabase: SyntaxDatabase { + fn module_tree(key: ()) -> Arc { + type ModuleTreeQuery; } - fn resolve(&self, file_id: FileId, rel: &RelativePath) -> Option { - let path = self.0[&file_id].join(rel).normalize(); - self.0.iter() - .filter_map(|&(id, ref p)| Some(id).filter(|_| p == &path)) - .next() + fn module_descriptor(file_id: FileId) -> Arc { + type ModuleDescriptorQuery; } } +} - struct Fixture { - next_file_id: u32, - fm: im::HashMap, - db: Db, - } - - impl Fixture { - fn new() -> Fixture { - Fixture { - next_file_id: 1, - fm: im::HashMap::new(), - db: Db::new(), - } - } - fn add_file(&mut self, path: &str, text: &str) -> FileId { - assert!(path.starts_with("/")); - let file_id = FileId(self.next_file_id); - self.next_file_id += 1; - self.fm.insert(file_id, RelativePathBuf::from(&path[1..])); - let mut new_state = self.db.state().clone(); - new_state.file_map.insert(file_id, Arc::new(text.to_string())); - new_state.file_resolver = FileResolverImp::new( - Arc::new(FileMap(self.fm.clone())) - ); - self.db = self.db.with_changes(new_state, &[file_id], true); - file_id - } - fn remove_file(&mut self, file_id: FileId) { - self.fm.remove(&file_id); - let mut new_state = self.db.state().clone(); - new_state.file_map.remove(&file_id); - new_state.file_resolver = FileResolverImp::new( - Arc::new(FileMap(self.fm.clone())) - ); - self.db = self.db.with_changes(new_state, &[file_id], true); - } - fn change_file(&mut self, file_id: FileId, new_text: &str) { - let mut new_state = self.db.state().clone(); - new_state.file_map.insert(file_id, Arc::new(new_text.to_string())); - self.db = self.db.with_changes(new_state, &[file_id], false); - } - fn check_parent_modules( - &self, - file_id: FileId, - expected: &[FileId], - queries: &[(&'static str, u64)] - ) { - let (tree, events) = self.db.trace_query(|ctx| module_tree(ctx)); - let actual = tree.parent_modules(file_id) - .into_iter() - .map(|link| link.owner(&tree)) - .collect::>(); - assert_eq!(actual.as_slice(), expected); - let mut counts = HashMap::new(); - events.into_iter() - .for_each(|event| *counts.entry(event).or_insert(0) += 1); - for &(query_id, expected_count) in queries.iter() { - let actual_count = *counts.get(&query_id).unwrap_or(&0); - assert_eq!( - actual_count, - expected_count, - "counts for {} differ", - query_id, - ) - } - - } - } - - #[test] - fn test_parent_module() { - let mut f = Fixture::new(); - let foo = f.add_file("/foo.rs", ""); - f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); - - let lib = f.add_file("/lib.rs", "mod foo;"); - f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); - f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 0)]); - - f.change_file(lib, ""); - f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); - - f.change_file(lib, "mod foo;"); - f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); - - f.change_file(lib, "mod bar;"); - f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); - f.change_file(lib, "mod foo;"); - f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); +fn module_descriptor(db: &impl ModulesDatabase, file_id: FileId) -> Arc { + let file = db.file_syntax(file_id); + Arc::new(ModuleDescriptor::new(file.ast())) +} - f.remove_file(lib); - f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 0)]); +fn module_tree(db: &impl ModulesDatabase, (): ()) -> Arc { + let file_set = db.file_set(()); + let mut files = Vec::new(); + for &file_id in file_set.files.iter() { + let module_descr = db.module_descriptor(file_id); + files.push((file_id, module_descr)); } + let res = ModuleTreeDescriptor::new(files.iter().map(|(file_id, descr)| (*file_id, &**descr)), &file_set.resolver); + Arc::new(res) } + +// #[cfg(test)] +// mod tests { +// use std::collections::HashMap; +// use im; +// use relative_path::{RelativePath, RelativePathBuf}; +// use { +// db::{Db}, +// imp::FileResolverImp, +// FileId, FileResolver, +// }; +// use super::*; + +// #[derive(Debug)] +// struct FileMap(im::HashMap); + +// impl FileResolver for FileMap { +// fn file_stem(&self, file_id: FileId) -> String { +// self.0[&file_id].file_stem().unwrap().to_string() +// } +// fn resolve(&self, file_id: FileId, rel: &RelativePath) -> Option { +// let path = self.0[&file_id].join(rel).normalize(); +// self.0.iter() +// .filter_map(|&(id, ref p)| Some(id).filter(|_| p == &path)) +// .next() +// } +// } + +// struct Fixture { +// next_file_id: u32, +// fm: im::HashMap, +// db: Db, +// } + +// impl Fixture { +// fn new() -> Fixture { +// Fixture { +// next_file_id: 1, +// fm: im::HashMap::new(), +// db: Db::new(), +// } +// } +// fn add_file(&mut self, path: &str, text: &str) -> FileId { +// assert!(path.starts_with("/")); +// let file_id = FileId(self.next_file_id); +// self.next_file_id += 1; +// self.fm.insert(file_id, RelativePathBuf::from(&path[1..])); +// let mut new_state = self.db.state().clone(); +// new_state.file_map.insert(file_id, Arc::new(text.to_string())); +// new_state.file_resolver = FileResolverImp::new( +// Arc::new(FileMap(self.fm.clone())) +// ); +// self.db = self.db.with_changes(new_state, &[file_id], true); +// file_id +// } +// fn remove_file(&mut self, file_id: FileId) { +// self.fm.remove(&file_id); +// let mut new_state = self.db.state().clone(); +// new_state.file_map.remove(&file_id); +// new_state.file_resolver = FileResolverImp::new( +// Arc::new(FileMap(self.fm.clone())) +// ); +// self.db = self.db.with_changes(new_state, &[file_id], true); +// } +// fn change_file(&mut self, file_id: FileId, new_text: &str) { +// let mut new_state = self.db.state().clone(); +// new_state.file_map.insert(file_id, Arc::new(new_text.to_string())); +// self.db = self.db.with_changes(new_state, &[file_id], false); +// } +// fn check_parent_modules( +// &self, +// file_id: FileId, +// expected: &[FileId], +// queries: &[(&'static str, u64)] +// ) { +// let (tree, events) = self.db.trace_query(|ctx| module_tree(ctx)); +// let actual = tree.parent_modules(file_id) +// .into_iter() +// .map(|link| link.owner(&tree)) +// .collect::>(); +// assert_eq!(actual.as_slice(), expected); +// let mut counts = HashMap::new(); +// events.into_iter() +// .for_each(|event| *counts.entry(event).or_insert(0) += 1); +// for &(query_id, expected_count) in queries.iter() { +// let actual_count = *counts.get(&query_id).unwrap_or(&0); +// assert_eq!( +// actual_count, +// expected_count, +// "counts for {} differ", +// query_id, +// ) +// } + +// } +// } + +// #[test] +// fn test_parent_module() { +// let mut f = Fixture::new(); +// let foo = f.add_file("/foo.rs", ""); +// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); + +// let lib = f.add_file("/lib.rs", "mod foo;"); +// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); +// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 0)]); + +// f.change_file(lib, ""); +// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); + +// f.change_file(lib, "mod foo;"); +// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); + +// f.change_file(lib, "mod bar;"); +// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); + +// f.change_file(lib, "mod foo;"); +// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); + +// f.remove_file(lib); +// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 0)]); +// } +// } diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 7a7d1169e..908f49b0a 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs @@ -16,7 +16,8 @@ use crate::{ imp::FileResolverImp, symbol_index::SymbolIndex, descriptors::{ModuleDescriptor, ModuleTreeDescriptor}, - db::{self, FilesDatabase, SyntaxDatabase} + db::{self, FilesDatabase, SyntaxDatabase}, + module_map::ModulesDatabase, }; pub(crate) trait SourceRoot { @@ -53,17 +54,17 @@ impl WritableSourceRoot { } } } - if let Some(resolver) = file_resolver { - let mut files: HashSet = db.file_set(()) - .files - .clone(); - for file_id in removed { - files.remove(&file_id); - } - files.extend(changed); - db.query(db::FileSetQuery) - .set((), Arc::new(db::FileSet { files, resolver })) + let file_set = db.file_set(()); + let mut files: HashSet = file_set + .files + .clone(); + for file_id in removed { + files.remove(&file_id); } + files.extend(changed); + let resolver = file_resolver.unwrap_or_else(|| file_set.resolver.clone()); + db.query(db::FileSetQuery) + .set((), Arc::new(db::FileSet { files, resolver })); // TODO: reconcile sasla's API with our needs // https://github.com/salsa-rs/salsa/issues/12 self.clone() @@ -72,12 +73,13 @@ impl WritableSourceRoot { impl SourceRoot for WritableSourceRoot { fn module_tree(&self) -> Arc { - unimplemented!() - //self.db.make_query(::module_map::module_tree) + self.db.read().module_tree(()) } - fn contains(&self, file_id: FileId) -> bool { - self.db.read().file_set(()).files.contains(&file_id) + let db = self.db.read(); + let files = &db.file_set(()).files; + eprintln!("files = {:?}", files); + files.contains(&file_id) } fn lines(&self, file_id: FileId) -> Arc { self.db.read().file_lines(file_id) -- cgit v1.2.3 From 062019590d70279d82fef3a60a2caf9490f8b97b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 21:25:54 +0300 Subject: Switch to the master of salsa --- crates/ra_analysis/Cargo.toml | 3 ++- crates/ra_analysis/src/db/mod.rs | 4 ++-- crates/ra_analysis/src/roots.rs | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index 4481e98d6..233f34e34 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml @@ -15,7 +15,8 @@ fst = "0.3.1" im = "12.0.0" ra_syntax = { path = "../ra_syntax" } ra_editor = { path = "../ra_editor" } -salsa = "0.4.1" +salsa = { git = "https://github.com/salsa-rs/salsa", rev = "20c9fbf" } +rustc-hash = "1.0" [dev-dependencies] test_utils = { path = "../test_utils" } diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs index c54d50252..c84bfa7a8 100644 --- a/crates/ra_analysis/src/db/mod.rs +++ b/crates/ra_analysis/src/db/mod.rs @@ -2,9 +2,9 @@ use std::{ fmt, sync::Arc, hash::{Hash, Hasher}, - collections::HashSet, }; use salsa; +use rustc_hash::FxHashSet; use ra_syntax::File; use ra_editor::{LineIndex}; use crate::{ @@ -63,7 +63,7 @@ salsa::query_group! { #[derive(Default, Debug)] pub(crate) struct FileSet { - pub(crate) files: HashSet, + pub(crate) files: FxHashSet, pub(crate) resolver: FileResolverImp, } diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 908f49b0a..692a07ccd 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs @@ -1,5 +1,4 @@ use std::{ - collections::{HashMap, HashSet}, sync::Arc, panic, }; @@ -8,6 +7,7 @@ use parking_lot::RwLock; use once_cell::sync::OnceCell; use rayon::prelude::*; use salsa::Database; +use rustc_hash::{FxHashMap, FxHashSet}; use ra_editor::LineIndex; use ra_syntax::File; @@ -40,8 +40,8 @@ impl WritableSourceRoot { file_resolver: Option, ) -> WritableSourceRoot { let db = self.db.write(); - let mut changed = HashSet::new(); - let mut removed = HashSet::new(); + let mut changed = FxHashSet::default(); + let mut removed = FxHashSet::default(); for (file_id, text) in changes { match text { None => { @@ -55,7 +55,7 @@ impl WritableSourceRoot { } } let file_set = db.file_set(()); - let mut files: HashSet = file_set + let mut files: FxHashSet = file_set .files .clone(); for file_id in removed { -- cgit v1.2.3 From 7503c5528f20f7404bac6f70bcf2120edb54dc52 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 21:54:12 +0300 Subject: fix tests --- crates/ra_analysis/src/db/mod.rs | 11 +---------- crates/ra_analysis/src/imp.rs | 19 +++++++++++++++++++ crates/ra_analysis/src/roots.rs | 1 - crates/ra_analysis/tests/tests.rs | 2 +- 4 files changed, 21 insertions(+), 12 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs index c84bfa7a8..081510daa 100644 --- a/crates/ra_analysis/src/db/mod.rs +++ b/crates/ra_analysis/src/db/mod.rs @@ -61,21 +61,12 @@ salsa::query_group! { } } -#[derive(Default, Debug)] +#[derive(Default, Debug, PartialEq, Eq)] pub(crate) struct FileSet { pub(crate) files: FxHashSet, pub(crate) resolver: FileResolverImp, } -impl PartialEq for FileSet { - fn eq(&self, other: &FileSet) -> bool { - self.files == other.files - } -} - -impl Eq for FileSet { -} - impl Hash for FileSet { fn hash(&self, hasher: &mut H) { let mut files = self.files.iter().cloned().collect::>(); diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 26f5e175b..6e6c022d9 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -3,6 +3,7 @@ use std::{ Arc, atomic::{AtomicBool, Ordering::SeqCst}, }, + hash::{Hash, Hasher}, fmt, collections::VecDeque, iter, @@ -29,6 +30,21 @@ pub(crate) struct FileResolverImp { inner: Arc } +impl PartialEq for FileResolverImp { + fn eq(&self, other: &FileResolverImp) -> bool { + self.inner() == other.inner() + } +} + +impl Eq for FileResolverImp { +} + +impl Hash for FileResolverImp { + fn hash(&self, hasher: &mut H) { + self.inner().hash(hasher); + } +} + impl FileResolverImp { pub(crate) fn new(inner: Arc) -> FileResolverImp { FileResolverImp { inner } @@ -39,6 +55,9 @@ impl FileResolverImp { pub(crate) fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option { self.inner.resolve(file_id, path) } + fn inner(&self) -> *const FileResolver { + &*self.inner + } } impl Default for FileResolverImp { diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 692a07ccd..766548c70 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs @@ -78,7 +78,6 @@ impl SourceRoot for WritableSourceRoot { fn contains(&self, file_id: FileId) -> bool { let db = self.db.read(); let files = &db.file_set(()).files; - eprintln!("files = {:?}", files); files.contains(&file_id) } fn lines(&self, file_id: FileId) -> Arc { diff --git a/crates/ra_analysis/tests/tests.rs b/crates/ra_analysis/tests/tests.rs index 755640fb4..2d3679fa9 100644 --- a/crates/ra_analysis/tests/tests.rs +++ b/crates/ra_analysis/tests/tests.rs @@ -238,4 +238,4 @@ fn bar() { assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]); assert_eq!(desc.ret_type, None); assert_eq!(param, Some(1)); -} \ No newline at end of file +} -- cgit v1.2.3 From ee69fddf02b2c8d4b73f9412831f5fcc4fa931a1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 21:56:01 +0300 Subject: Drop dead code --- crates/ra_analysis/src/db.rs | 103 +++++++++++++++++++ crates/ra_analysis/src/db/imp.rs | 153 ---------------------------- crates/ra_analysis/src/db/mod.rs | 189 ----------------------------------- crates/ra_analysis/src/module_map.rs | 123 ----------------------- crates/ra_analysis/src/queries.rs | 39 -------- 5 files changed, 103 insertions(+), 504 deletions(-) create mode 100644 crates/ra_analysis/src/db.rs delete mode 100644 crates/ra_analysis/src/db/imp.rs delete mode 100644 crates/ra_analysis/src/db/mod.rs delete mode 100644 crates/ra_analysis/src/queries.rs (limited to 'crates') diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs new file mode 100644 index 000000000..0773edcc1 --- /dev/null +++ b/crates/ra_analysis/src/db.rs @@ -0,0 +1,103 @@ +use std::{ + fmt, + sync::Arc, + hash::{Hash, Hasher}, +}; +use salsa; +use rustc_hash::FxHashSet; +use ra_syntax::File; +use ra_editor::{LineIndex}; +use crate::{ + symbol_index::SymbolIndex, + module_map::{ModulesDatabase, ModuleTreeQuery, ModuleDescriptorQuery}, + FileId, FileResolverImp, +}; + +#[derive(Default)] +pub(crate) struct RootDatabase { + runtime: salsa::runtime::Runtime, +} + +impl fmt::Debug for RootDatabase { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str("RootDatabase { ... }") + } +} + +impl salsa::Database for RootDatabase { + fn salsa_runtime(&self) -> &salsa::runtime::Runtime { + &self.runtime + } +} + +salsa::database_storage! { + pub(crate) struct RootDatabaseStorage for RootDatabase { + impl FilesDatabase { + fn file_text() for FileTextQuery; + fn file_set() for FileSetQuery; + } + impl SyntaxDatabase { + fn file_syntax() for FileSyntaxQuery; + fn file_lines() for FileLinesQuery; + fn file_symbols() for FileSymbolsQuery; + } + impl ModulesDatabase { + fn module_tree() for ModuleTreeQuery; + fn module_descriptor() for ModuleDescriptorQuery; + } + } +} + +salsa::query_group! { + pub(crate) trait FilesDatabase: salsa::Database { + fn file_text(file_id: FileId) -> Arc { + type FileTextQuery; + storage input; + } + fn file_set(key: ()) -> Arc { + type FileSetQuery; + storage input; + } + } +} + +#[derive(Default, Debug, PartialEq, Eq)] +pub(crate) struct FileSet { + pub(crate) files: FxHashSet, + pub(crate) resolver: FileResolverImp, +} + +impl Hash for FileSet { + fn hash(&self, hasher: &mut H) { + let mut files = self.files.iter().cloned().collect::>(); + files.sort(); + files.hash(hasher); + } +} + +salsa::query_group! { + pub(crate) trait SyntaxDatabase: FilesDatabase { + fn file_syntax(file_id: FileId) -> File { + type FileSyntaxQuery; + } + fn file_lines(file_id: FileId) -> Arc { + type FileLinesQuery; + } + fn file_symbols(file_id: FileId) -> Arc { + type FileSymbolsQuery; + } + } +} + +fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { + let text = db.file_text(file_id); + File::parse(&*text) +} +fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { + let text = db.file_text(file_id); + Arc::new(LineIndex::new(&*text)) +} +fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { + let syntax = db.file_syntax(file_id); + Arc::new(SymbolIndex::for_file(file_id, syntax)) +} diff --git a/crates/ra_analysis/src/db/imp.rs b/crates/ra_analysis/src/db/imp.rs deleted file mode 100644 index 7669b6184..000000000 --- a/crates/ra_analysis/src/db/imp.rs +++ /dev/null @@ -1,153 +0,0 @@ -use std::{ - sync::Arc, - any::Any, - hash::{Hash, Hasher}, - collections::hash_map::{DefaultHasher}, - iter, -}; -use rustc_hash::FxHashMap; -use salsa; -use crate::{FileId, imp::FileResolverImp}; -use super::{State, Query, QueryCtx}; - -pub(super) type Data = Arc; - -#[derive(Debug)] -pub(super) struct Db { - names: Arc>, - pub(super) imp: salsa::Db, -} - -impl Db { - pub(super) fn new(mut reg: QueryRegistry) -> Db { - let config = reg.config.take().unwrap(); - Db { - names: Arc::new(reg.names), - imp: salsa::Db::new(config, State::default()) - } - } - pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db { - let names = self.names.clone(); - let mut invalidations = salsa::Invalidations::new(); - invalidations.invalidate(FILE_TEXT, changed_files.iter().map(hash).map(salsa::InputFingerprint)); - if resolver_changed { - invalidations.invalidate(FILE_SET, iter::once(salsa::InputFingerprint(hash(&())))); - } else { - invalidations.invalidate(FILE_SET, iter::empty()); - } - let imp = self.imp.with_ground_data( - new_state, - invalidations, - ); - Db { names, imp } - } - pub(super) fn extract_trace(&self, ctx: &salsa::QueryCtx) -> Vec<&'static str> { - ctx.trace().into_iter().map(|it| self.names[&it]).collect() - } -} - -pub(crate) trait EvalQuery { - type Params; - type Output; - fn query_type(&self) -> salsa::QueryTypeId; - fn f(&self) -> salsa::QueryFn; - fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc; -} - -impl EvalQuery for Query -where - T: Hash + Send + Sync + 'static, - R: Hash + Send + Sync + 'static, -{ - type Params = T; - type Output = R; - fn query_type(&self) -> salsa::QueryTypeId { - salsa::QueryTypeId(self.0) - } - fn f(&self) -> salsa::QueryFn { - let f = self.1; - Box::new(move |ctx, data| { - let ctx = QueryCtx { imp: ctx }; - let data: &T = data.downcast_ref().unwrap(); - let res = f(ctx, data); - let h = hash(&res); - (Arc::new(res), salsa::OutputFingerprint(h)) - }) - } - fn get(&self, ctx: &QueryCtx, params: Self::Params) -> Arc { - let query_id = salsa::QueryId( - self.query_type(), - salsa::InputFingerprint(hash(¶ms)), - ); - let res = ctx.imp.get(query_id, Arc::new(params)); - res.downcast().unwrap() - } -} - -pub(super) struct QueryRegistry { - config: Option>, - names: FxHashMap, -} - -impl QueryRegistry { - pub(super) fn new() -> QueryRegistry { - let mut config = salsa::QueryConfig::::new(); - config = config.with_ground_query( - FILE_TEXT, Box::new(|state, params| { - let file_id: &FileId = params.downcast_ref().unwrap(); - let res = state.file_map[file_id].clone(); - let fingerprint = salsa::OutputFingerprint(hash(&res)); - (res, fingerprint) - }) - ); - config = config.with_ground_query( - FILE_SET, Box::new(|state, _params| { - let file_ids: Vec = state.file_map.keys().cloned().collect(); - let hash = hash(&file_ids); - let file_resolver = state.file_resolver.clone(); - let res = (file_ids, file_resolver); - let fingerprint = salsa::OutputFingerprint(hash); - (Arc::new(res), fingerprint) - }) - ); - let mut names = FxHashMap::default(); - names.insert(FILE_TEXT, "FILE_TEXT"); - names.insert(FILE_SET, "FILE_SET"); - QueryRegistry { config: Some(config), names } - } - pub(super) fn add(&mut self, q: Q, name: &'static str) { - let id = q.query_type(); - let prev = self.names.insert(id, name); - assert!(prev.is_none(), "duplicate query: {:?}", id); - let config = self.config.take().unwrap(); - let config = config.with_query(id, q.f()); - self.config= Some(config); - } -} - -fn hash(x: &T) -> u64 { - let mut hasher = DefaultHasher::new(); - x.hash(&mut hasher); - hasher.finish() -} - -const FILE_TEXT: salsa::QueryTypeId = salsa::QueryTypeId(0); -pub(super) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc { - let query_id = salsa::QueryId( - FILE_TEXT, - salsa::InputFingerprint(hash(&file_id)), - ); - let res = ctx.imp.get(query_id, Arc::new(file_id)); - res.downcast().unwrap() -} - -const FILE_SET: salsa::QueryTypeId = salsa::QueryTypeId(1); -pub(super) fn file_set(ctx: QueryCtx) -> Arc<(Vec, FileResolverImp)> { - let query_id = salsa::QueryId( - FILE_SET, - salsa::InputFingerprint(hash(&())), - ); - let res = ctx.imp.get(query_id, Arc::new(())); - res.downcast().unwrap() -} - diff --git a/crates/ra_analysis/src/db/mod.rs b/crates/ra_analysis/src/db/mod.rs deleted file mode 100644 index 081510daa..000000000 --- a/crates/ra_analysis/src/db/mod.rs +++ /dev/null @@ -1,189 +0,0 @@ -use std::{ - fmt, - sync::Arc, - hash::{Hash, Hasher}, -}; -use salsa; -use rustc_hash::FxHashSet; -use ra_syntax::File; -use ra_editor::{LineIndex}; -use crate::{ - symbol_index::SymbolIndex, - module_map::{ModulesDatabase, ModuleTreeQuery, ModuleDescriptorQuery}, - FileId, FileResolverImp, -}; - -#[derive(Default)] -pub(crate) struct RootDatabase { - runtime: salsa::runtime::Runtime, -} - -impl fmt::Debug for RootDatabase { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write_str("RootDatabase { ... }") - } -} - -impl salsa::Database for RootDatabase { - fn salsa_runtime(&self) -> &salsa::runtime::Runtime { - &self.runtime - } -} - -salsa::database_storage! { - pub(crate) struct RootDatabaseStorage for RootDatabase { - impl FilesDatabase { - fn file_text() for FileTextQuery; - fn file_set() for FileSetQuery; - } - impl SyntaxDatabase { - fn file_syntax() for FileSyntaxQuery; - fn file_lines() for FileLinesQuery; - fn file_symbols() for FileSymbolsQuery; - } - impl ModulesDatabase { - fn module_tree() for ModuleTreeQuery; - fn module_descriptor() for ModuleDescriptorQuery; - } - } -} - -salsa::query_group! { - pub(crate) trait FilesDatabase: salsa::Database { - fn file_text(file_id: FileId) -> Arc { - type FileTextQuery; - storage input; - } - fn file_set(key: ()) -> Arc { - type FileSetQuery; - storage input; - } - } -} - -#[derive(Default, Debug, PartialEq, Eq)] -pub(crate) struct FileSet { - pub(crate) files: FxHashSet, - pub(crate) resolver: FileResolverImp, -} - -impl Hash for FileSet { - fn hash(&self, hasher: &mut H) { - let mut files = self.files.iter().cloned().collect::>(); - files.sort(); - files.hash(hasher); - } -} - -salsa::query_group! { - pub(crate) trait SyntaxDatabase: FilesDatabase { - fn file_syntax(file_id: FileId) -> File { - type FileSyntaxQuery; - } - fn file_lines(file_id: FileId) -> Arc { - type FileLinesQuery; - } - fn file_symbols(file_id: FileId) -> Arc { - type FileSymbolsQuery; - } - } -} - -fn file_syntax(db: &impl SyntaxDatabase, file_id: FileId) -> File { - let text = db.file_text(file_id); - File::parse(&*text) -} -fn file_lines(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { - let text = db.file_text(file_id); - Arc::new(LineIndex::new(&*text)) -} -fn file_symbols(db: &impl SyntaxDatabase, file_id: FileId) -> Arc { - let syntax = db.file_syntax(file_id); - Arc::new(SymbolIndex::for_file(file_id, syntax)) -} - -// mod imp; - -// use std::{ -// sync::Arc, -// }; -// use im; -// use salsa; -// use {FileId, imp::FileResolverImp}; - -// #[derive(Debug, Default, Clone)] -// pub(crate) struct State { -// pub(crate) file_map: im::HashMap>, -// pub(crate) file_resolver: FileResolverImp -// } - -// #[derive(Debug)] -// pub(crate) struct Db { -// imp: imp::Db, -// } - -// #[derive(Clone, Copy)] -// pub(crate) struct QueryCtx<'a> { -// imp: &'a salsa::QueryCtx, -// } - -// pub(crate) struct Query(pub(crate) u16, pub(crate) fn(QueryCtx, &T) -> R); - -// pub(crate) struct QueryRegistry { -// imp: imp::QueryRegistry, -// } - -// impl Default for Db { -// fn default() -> Db { -// Db::new() -// } -// } - -// impl Db { -// pub(crate) fn new() -> Db { -// let reg = QueryRegistry::new(); -// Db { imp: imp::Db::new(reg.imp) } -// } -// pub(crate) fn state(&self) -> &State { -// self.imp.imp.ground_data() -// } -// pub(crate) fn with_changes(&self, new_state: State, changed_files: &[FileId], resolver_changed: bool) -> Db { -// Db { imp: self.imp.with_changes(new_state, changed_files, resolver_changed) } -// } -// pub(crate) fn make_query R, R>(&self, f: F) -> R { -// let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; -// f(ctx) -// } -// #[allow(unused)] -// pub(crate) fn trace_query R, R>(&self, f: F) -> (R, Vec<&'static str>) { -// let ctx = QueryCtx { imp: &self.imp.imp.query_ctx() }; -// let res = f(ctx); -// let trace = self.imp.extract_trace(ctx.imp); -// (res, trace) -// } -// } - -// impl<'a> QueryCtx<'a> { -// pub(crate) fn get(&self, q: Q, params: Q::Params) -> Arc { -// q.get(self, params) -// } -// } - -// pub(crate) fn file_text(ctx: QueryCtx, file_id: FileId) -> Arc { -// imp::file_text(ctx, file_id) -// } - -// pub(crate) fn file_set(ctx: QueryCtx) -> Arc<(Vec, FileResolverImp)> { -// imp::file_set(ctx) -// } -// impl QueryRegistry { -// fn new() -> QueryRegistry { -// let mut reg = QueryRegistry { imp: imp::QueryRegistry::new() }; -// ::queries::register_queries(&mut reg); -// ::module_map::register_queries(&mut reg); -// reg -// } -// pub(crate) fn add(&mut self, q: Q, name: &'static str) { -// self.imp.add(q, name) -// } -// } diff --git a/crates/ra_analysis/src/module_map.rs b/crates/ra_analysis/src/module_map.rs index 95a770ae7..c1799e3d4 100644 --- a/crates/ra_analysis/src/module_map.rs +++ b/crates/ra_analysis/src/module_map.rs @@ -32,126 +32,3 @@ fn module_tree(db: &impl ModulesDatabase, (): ()) -> Arc { let res = ModuleTreeDescriptor::new(files.iter().map(|(file_id, descr)| (*file_id, &**descr)), &file_set.resolver); Arc::new(res) } - -// #[cfg(test)] -// mod tests { -// use std::collections::HashMap; -// use im; -// use relative_path::{RelativePath, RelativePathBuf}; -// use { -// db::{Db}, -// imp::FileResolverImp, -// FileId, FileResolver, -// }; -// use super::*; - -// #[derive(Debug)] -// struct FileMap(im::HashMap); - -// impl FileResolver for FileMap { -// fn file_stem(&self, file_id: FileId) -> String { -// self.0[&file_id].file_stem().unwrap().to_string() -// } -// fn resolve(&self, file_id: FileId, rel: &RelativePath) -> Option { -// let path = self.0[&file_id].join(rel).normalize(); -// self.0.iter() -// .filter_map(|&(id, ref p)| Some(id).filter(|_| p == &path)) -// .next() -// } -// } - -// struct Fixture { -// next_file_id: u32, -// fm: im::HashMap, -// db: Db, -// } - -// impl Fixture { -// fn new() -> Fixture { -// Fixture { -// next_file_id: 1, -// fm: im::HashMap::new(), -// db: Db::new(), -// } -// } -// fn add_file(&mut self, path: &str, text: &str) -> FileId { -// assert!(path.starts_with("/")); -// let file_id = FileId(self.next_file_id); -// self.next_file_id += 1; -// self.fm.insert(file_id, RelativePathBuf::from(&path[1..])); -// let mut new_state = self.db.state().clone(); -// new_state.file_map.insert(file_id, Arc::new(text.to_string())); -// new_state.file_resolver = FileResolverImp::new( -// Arc::new(FileMap(self.fm.clone())) -// ); -// self.db = self.db.with_changes(new_state, &[file_id], true); -// file_id -// } -// fn remove_file(&mut self, file_id: FileId) { -// self.fm.remove(&file_id); -// let mut new_state = self.db.state().clone(); -// new_state.file_map.remove(&file_id); -// new_state.file_resolver = FileResolverImp::new( -// Arc::new(FileMap(self.fm.clone())) -// ); -// self.db = self.db.with_changes(new_state, &[file_id], true); -// } -// fn change_file(&mut self, file_id: FileId, new_text: &str) { -// let mut new_state = self.db.state().clone(); -// new_state.file_map.insert(file_id, Arc::new(new_text.to_string())); -// self.db = self.db.with_changes(new_state, &[file_id], false); -// } -// fn check_parent_modules( -// &self, -// file_id: FileId, -// expected: &[FileId], -// queries: &[(&'static str, u64)] -// ) { -// let (tree, events) = self.db.trace_query(|ctx| module_tree(ctx)); -// let actual = tree.parent_modules(file_id) -// .into_iter() -// .map(|link| link.owner(&tree)) -// .collect::>(); -// assert_eq!(actual.as_slice(), expected); -// let mut counts = HashMap::new(); -// events.into_iter() -// .for_each(|event| *counts.entry(event).or_insert(0) += 1); -// for &(query_id, expected_count) in queries.iter() { -// let actual_count = *counts.get(&query_id).unwrap_or(&0); -// assert_eq!( -// actual_count, -// expected_count, -// "counts for {} differ", -// query_id, -// ) -// } - -// } -// } - -// #[test] -// fn test_parent_module() { -// let mut f = Fixture::new(); -// let foo = f.add_file("/foo.rs", ""); -// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); - -// let lib = f.add_file("/lib.rs", "mod foo;"); -// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); -// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 0)]); - -// f.change_file(lib, ""); -// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); - -// f.change_file(lib, "mod foo;"); -// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); - -// f.change_file(lib, "mod bar;"); -// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 1)]); - -// f.change_file(lib, "mod foo;"); -// f.check_parent_modules(foo, &[lib], &[("MODULE_DESCR", 1)]); - -// f.remove_file(lib); -// f.check_parent_modules(foo, &[], &[("MODULE_DESCR", 0)]); -// } -// } diff --git a/crates/ra_analysis/src/queries.rs b/crates/ra_analysis/src/queries.rs deleted file mode 100644 index 613bf1e61..000000000 --- a/crates/ra_analysis/src/queries.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::sync::Arc; -use ra_syntax::File; -use ra_editor::LineIndex; -use crate::{ - FileId, - db::{Query, QueryCtx, QueryRegistry}, - symbol_index::SymbolIndex, -}; - -pub(crate) use crate::db::{file_text, file_set}; - -pub(crate) fn file_syntax(ctx: QueryCtx, file_id: FileId) -> File { - (&*ctx.get(FILE_SYNTAX, file_id)).clone() -} -pub(crate) fn file_lines(ctx: QueryCtx, file_id: FileId) -> Arc { - ctx.get(FILE_LINES, file_id) -} -pub(crate) fn file_symbols(ctx: QueryCtx, file_id: FileId) -> Arc { - ctx.get(FILE_SYMBOLS, file_id) -} - -const FILE_SYNTAX: Query = Query(16, |ctx, file_id: &FileId| { - let text = file_text(ctx, *file_id); - File::parse(&*text) -}); -const FILE_LINES: Query = Query(17, |ctx, file_id: &FileId| { - let text = file_text(ctx, *file_id); - LineIndex::new(&*text) -}); -const FILE_SYMBOLS: Query = Query(18, |ctx, file_id: &FileId| { - let syntax = file_syntax(ctx, *file_id); - SymbolIndex::for_file(*file_id, syntax) -}); - -pub(crate) fn register_queries(reg: &mut QueryRegistry) { - reg.add(FILE_SYNTAX, "FILE_SYNTAX"); - reg.add(FILE_LINES, "FILE_LINES"); - reg.add(FILE_SYMBOLS, "FILE_SYMBOLS"); -} -- cgit v1.2.3 From 8c88900fa9ecc71fdd58254d3f29b66912a56bd4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 22:01:50 +0300 Subject: remove resolver from world --- crates/ra_analysis/src/imp.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 6e6c022d9..fb711491b 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -99,7 +99,6 @@ impl AnalysisHostImpl { } pub fn set_file_resolver(&mut self, resolver: FileResolverImp) { let data = self.data_mut(); - data.file_resolver = resolver.clone(); data.root = Arc::new(data.root.apply_changes(&mut iter::empty(), Some(resolver))); } pub fn set_crate_graph(&mut self, graph: CrateGraph) { @@ -405,7 +404,6 @@ impl AnalysisImpl { #[derive(Default, Clone, Debug)] struct WorldData { - file_resolver: FileResolverImp, crate_graph: CrateGraph, root: Arc, libs: Vec>, -- cgit v1.2.3 From 76c51fae77d5dc2d7791132ecc78e444118e48de Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 22:05:21 +0300 Subject: Tweak writable root API --- crates/ra_analysis/src/imp.rs | 12 ++++++------ crates/ra_analysis/src/roots.rs | 7 ++----- 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index fb711491b..0cf6db40d 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -94,12 +94,12 @@ impl AnalysisHostImpl { } } pub fn change_files(&mut self, changes: &mut dyn Iterator)>) { - let data = self.data_mut(); - data.root = Arc::new(data.root.apply_changes(changes, None)); + self.data_mut() + .root.apply_changes(changes, None); } pub fn set_file_resolver(&mut self, resolver: FileResolverImp) { - let data = self.data_mut(); - data.root = Arc::new(data.root.apply_changes(&mut iter::empty(), Some(resolver))); + self.data_mut() + .root.apply_changes(&mut iter::empty(), Some(resolver)); } pub fn set_crate_graph(&mut self, graph: CrateGraph) { let mut visited = FxHashSet::default(); @@ -141,7 +141,7 @@ impl Clone for AnalysisImpl { impl AnalysisImpl { fn root(&self, file_id: FileId) -> &SourceRoot { if self.data.root.contains(file_id) { - return &*self.data.root; + return &self.data.root; } &**self.data.libs.iter().find(|it| it.contains(file_id)).unwrap() } @@ -405,7 +405,7 @@ impl AnalysisImpl { #[derive(Default, Clone, Debug)] struct WorldData { crate_graph: CrateGraph, - root: Arc, + root: WritableSourceRoot, libs: Vec>, } diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 766548c70..42833af36 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs @@ -35,10 +35,10 @@ pub(crate) struct WritableSourceRoot { impl WritableSourceRoot { pub fn apply_changes( - &self, + &mut self, changes: &mut dyn Iterator)>, file_resolver: Option, - ) -> WritableSourceRoot { + ) { let db = self.db.write(); let mut changed = FxHashSet::default(); let mut removed = FxHashSet::default(); @@ -65,9 +65,6 @@ impl WritableSourceRoot { let resolver = file_resolver.unwrap_or_else(|| file_set.resolver.clone()); db.query(db::FileSetQuery) .set((), Arc::new(db::FileSet { files, resolver })); - // TODO: reconcile sasla's API with our needs - // https://github.com/salsa-rs/salsa/issues/12 - self.clone() } } -- cgit v1.2.3 From bbcd998433075aba66ef0677bcdd821ca5fc926e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 22:29:24 +0300 Subject: make analysis sync --- crates/ra_analysis/src/db.rs | 14 ++++++++++++++ crates/ra_analysis/src/imp.rs | 12 ++++++------ crates/ra_analysis/src/lib.rs | 6 ++++++ crates/ra_analysis/src/roots.rs | 24 +++++++++++------------- 4 files changed, 37 insertions(+), 19 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs index 0773edcc1..c69577233 100644 --- a/crates/ra_analysis/src/db.rs +++ b/crates/ra_analysis/src/db.rs @@ -30,6 +30,20 @@ impl salsa::Database for RootDatabase { } } +impl salsa::ParallelDatabase for RootDatabase { + fn fork(&self) -> Self { + RootDatabase { + runtime: self.runtime.fork(), + } + } +} + +impl Clone for RootDatabase { + fn clone(&self) -> RootDatabase { + salsa::ParallelDatabase::fork(self) + } +} + salsa::database_storage! { pub(crate) struct RootDatabaseStorage for RootDatabase { impl FilesDatabase { diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 0cf6db40d..d07d797d5 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -78,13 +78,13 @@ impl Default for FileResolverImp { #[derive(Debug)] pub(crate) struct AnalysisHostImpl { - data: Arc + data: WorldData } impl AnalysisHostImpl { pub fn new() -> AnalysisHostImpl { AnalysisHostImpl { - data: Arc::new(WorldData::default()), + data: WorldData::default(), } } pub fn analysis(&self) -> AnalysisImpl { @@ -114,18 +114,18 @@ impl AnalysisHostImpl { self.data_mut().libs.push(Arc::new(root)); } fn data_mut(&mut self) -> &mut WorldData { - Arc::make_mut(&mut self.data) + &mut self.data } } pub(crate) struct AnalysisImpl { needs_reindex: AtomicBool, - data: Arc, + data: WorldData, } impl fmt::Debug for AnalysisImpl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - (&*self.data).fmt(f) + self.data.fmt(f) } } @@ -133,7 +133,7 @@ impl Clone for AnalysisImpl { fn clone(&self) -> AnalysisImpl { AnalysisImpl { needs_reindex: AtomicBool::new(self.needs_reindex.load(SeqCst)), - data: Arc::clone(&self.data), + data: self.data.clone(), } } } diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index d49132513..c76e4f4fe 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -258,3 +258,9 @@ impl LibraryData { LibraryData { root } } } + +#[test] +fn analysis_is_send() { + fn is_send() {} + is_send::(); +} diff --git a/crates/ra_analysis/src/roots.rs b/crates/ra_analysis/src/roots.rs index 42833af36..76bcecd38 100644 --- a/crates/ra_analysis/src/roots.rs +++ b/crates/ra_analysis/src/roots.rs @@ -2,7 +2,6 @@ use std::{ sync::Arc, panic, }; -use parking_lot::RwLock; use once_cell::sync::OnceCell; use rayon::prelude::*; @@ -30,7 +29,7 @@ pub(crate) trait SourceRoot { #[derive(Default, Debug, Clone)] pub(crate) struct WritableSourceRoot { - db: Arc>, + db: db::RootDatabase, } impl WritableSourceRoot { @@ -39,7 +38,6 @@ impl WritableSourceRoot { changes: &mut dyn Iterator)>, file_resolver: Option, ) { - let db = self.db.write(); let mut changed = FxHashSet::default(); let mut removed = FxHashSet::default(); for (file_id, text) in changes { @@ -48,13 +46,13 @@ impl WritableSourceRoot { removed.insert(file_id); } Some(text) => { - db.query(db::FileTextQuery) + self.db.query(db::FileTextQuery) .set(file_id, Arc::new(text)); changed.insert(file_id); } } } - let file_set = db.file_set(()); + let file_set = self.db.file_set(()); let mut files: FxHashSet = file_set .files .clone(); @@ -63,28 +61,28 @@ impl WritableSourceRoot { } files.extend(changed); let resolver = file_resolver.unwrap_or_else(|| file_set.resolver.clone()); - db.query(db::FileSetQuery) + self.db.query(db::FileSetQuery) .set((), Arc::new(db::FileSet { files, resolver })); } } impl SourceRoot for WritableSourceRoot { fn module_tree(&self) -> Arc { - self.db.read().module_tree(()) + self.db.module_tree(()) } fn contains(&self, file_id: FileId) -> bool { - let db = self.db.read(); - let files = &db.file_set(()).files; - files.contains(&file_id) + self.db.file_set(()) + .files + .contains(&file_id) } fn lines(&self, file_id: FileId) -> Arc { - self.db.read().file_lines(file_id) + self.db.file_lines(file_id) } fn syntax(&self, file_id: FileId) -> File { - self.db.read().file_syntax(file_id) + self.db.file_syntax(file_id) } fn symbols<'a>(&'a self, acc: &mut Vec>) { - let db = self.db.read(); + let db = &self.db; let symbols = db.file_set(()); let symbols = symbols .files -- cgit v1.2.3 From 85ff328d31f4ccdbb797a3040f967963bfaa5fff Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 22:36:08 +0300 Subject: remove clones --- crates/ra_analysis/src/lib.rs | 2 +- crates/ra_lsp_server/src/main_loop/handlers.rs | 4 ++-- crates/ra_lsp_server/src/main_loop/mod.rs | 4 ++-- crates/ra_lsp_server/src/server_world.rs | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index c76e4f4fe..543a8f6da 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -162,7 +162,7 @@ impl Query { } } -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct Analysis { imp: AnalysisImpl } diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 1fe78f3d0..5acb39b60 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs @@ -478,7 +478,7 @@ pub fn handle_code_action( } pub fn publish_diagnostics( - world: ServerWorld, + world: &ServerWorld, file_id: FileId, ) -> Result { let uri = world.file_id_to_uri(file_id)?; @@ -497,7 +497,7 @@ pub fn publish_diagnostics( } pub fn publish_decorations( - world: ServerWorld, + world: &ServerWorld, file_id: FileId, ) -> Result { let uri = world.file_id_to_uri(file_id)?; diff --git a/crates/ra_lsp_server/src/main_loop/mod.rs b/crates/ra_lsp_server/src/main_loop/mod.rs index 773501efe..cf2477cb5 100644 --- a/crates/ra_lsp_server/src/main_loop/mod.rs +++ b/crates/ra_lsp_server/src/main_loop/mod.rs @@ -391,7 +391,7 @@ fn update_file_notifications_on_threadpool( ) { pool.spawn(move || { for file_id in subscriptions { - match handlers::publish_diagnostics(world.clone(), file_id) { + match handlers::publish_diagnostics(&world, file_id) { Err(e) => { error!("failed to compute diagnostics: {:?}", e) } @@ -400,7 +400,7 @@ fn update_file_notifications_on_threadpool( sender.send(Task::Notify(not)); } } - match handlers::publish_decorations(world.clone(), file_id) { + match handlers::publish_decorations(&world, file_id) { Err(e) => { error!("failed to compute decorations: {:?}", e) } diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index c931afa02..9b3013ae8 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs @@ -23,7 +23,6 @@ pub struct ServerWorldState { pub mem_map: FxHashMap>, } -#[derive(Clone)] pub struct ServerWorld { pub workspaces: Arc>, pub analysis: Analysis, -- cgit v1.2.3 From fc31ddd303e05b658cc46f44b6c7043a653cfa2c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 22:59:18 +0300 Subject: Simplify --- crates/ra_analysis/src/imp.rs | 12 ------------ crates/ra_analysis/src/lib.rs | 1 - 2 files changed, 13 deletions(-) (limited to 'crates') diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index d07d797d5..5efcaeca0 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs @@ -1,7 +1,6 @@ use std::{ sync::{ Arc, - atomic::{AtomicBool, Ordering::SeqCst}, }, hash::{Hash, Hasher}, fmt, @@ -89,7 +88,6 @@ impl AnalysisHostImpl { } pub fn analysis(&self) -> AnalysisImpl { AnalysisImpl { - needs_reindex: AtomicBool::new(false), data: self.data.clone(), } } @@ -119,7 +117,6 @@ impl AnalysisHostImpl { } pub(crate) struct AnalysisImpl { - needs_reindex: AtomicBool, data: WorldData, } @@ -129,15 +126,6 @@ impl fmt::Debug for AnalysisImpl { } } -impl Clone for AnalysisImpl { - fn clone(&self) -> AnalysisImpl { - AnalysisImpl { - needs_reindex: AtomicBool::new(self.needs_reindex.load(SeqCst)), - data: self.data.clone(), - } - } -} - impl AnalysisImpl { fn root(&self, file_id: FileId) -> &SourceRoot { if self.data.root.contains(file_id) { diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index 543a8f6da..d8b355a81 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -19,7 +19,6 @@ mod imp; mod job; mod roots; mod db; -// mod queries; mod descriptors; use std::{ -- cgit v1.2.3 From f30a7deff17d7a69e1e9876d96d00392cd8f6fd1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 15 Oct 2018 23:57:46 +0300 Subject: switch to salsa release --- crates/ra_analysis/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/ra_analysis/Cargo.toml b/crates/ra_analysis/Cargo.toml index 233f34e34..17b04182f 100644 --- a/crates/ra_analysis/Cargo.toml +++ b/crates/ra_analysis/Cargo.toml @@ -15,7 +15,7 @@ fst = "0.3.1" im = "12.0.0" ra_syntax = { path = "../ra_syntax" } ra_editor = { path = "../ra_editor" } -salsa = { git = "https://github.com/salsa-rs/salsa", rev = "20c9fbf" } +salsa = "0.5.0" rustc-hash = "1.0" [dev-dependencies] -- cgit v1.2.3