salsa/examples/compiler/implementation.rs

57 lines
2.3 KiB
Rust
Raw Normal View History

2018-09-28 18:26:46 +00:00
use crate::class_table;
2018-10-05 08:54:51 +00:00
use crate::compiler::{CompilerDatabase, Interner};
2018-09-28 15:40:20 +00:00
2018-10-05 08:54:51 +00:00
/// Our "database" will be threaded through our application (though
/// 99% of the application only interacts with it through traits and
/// never knows its real name). It contains all the values for all of
/// our memoized queries and encapsulates **all mutable state that
/// persists longer than a single query execution.**
2018-09-29 10:10:06 +00:00
///
2018-10-05 08:54:51 +00:00
/// Databases can contain whatever you want them to, but salsa
2018-09-29 10:44:08 +00:00
/// requires you to add a `salsa::runtime::Runtime` member. Note
/// though: you should be very careful if adding shared, mutable state
/// to your context (e.g., a shared counter or some such thing). If
/// mutations to that shared state affect the results of your queries,
/// that's going to mess up the incremental results.
2018-09-28 15:40:20 +00:00
#[derive(Default)]
2018-10-05 08:54:51 +00:00
pub struct DatabaseImpl {
runtime: salsa::runtime::Runtime<DatabaseImpl>,
2018-09-29 10:44:08 +00:00
/// An interner is an example of shared mutable state that would
/// be ok: although the interner allocates internally when you
/// intern something new, this never affects any previously
/// interned values, so it's not going to affect query results.
2018-09-28 15:40:20 +00:00
interner: Interner,
}
2018-09-29 10:44:08 +00:00
/// This impl tells salsa where to find the salsa runtime.
2018-10-05 08:54:51 +00:00
impl salsa::Database for DatabaseImpl {
fn salsa_runtime(&self) -> &salsa::runtime::Runtime<DatabaseImpl> {
2018-09-29 10:10:06 +00:00
&self.runtime
}
}
/// Declares the "query storage" for your context. Here, you list out
/// all of the query traits from your application that you wish to
/// provide storage for. This macro will generate the appropriate
/// storage and also generate impls for those traits, so that you
2018-10-05 08:54:51 +00:00
/// `DatabaseImpl` type implements them.
salsa::database_storage! {
pub struct DatabaseImplStorage for DatabaseImpl {
impl class_table::ClassTableDatabase {
2018-09-28 18:26:46 +00:00
fn all_classes() for class_table::AllClasses;
fn all_fields() for class_table::AllFields;
fn fields() for class_table::Fields;
}
2018-09-28 15:40:20 +00:00
}
}
2018-09-29 10:10:06 +00:00
/// In addition to the "query provider" traits, you may have other
/// trait requirements that your application needs -- you can
/// implement those yourself (in this case, an `interner`).
2018-10-05 08:54:51 +00:00
impl CompilerDatabase for DatabaseImpl {
2018-09-28 15:40:20 +00:00
fn interner(&self) -> &Interner {
&self.interner
}
}