add a boilerplate reducing macro

This commit is contained in:
Niko Matsakis 2018-09-28 14:26:46 -04:00
parent 302a89fea5
commit 9b4267f7c1
2 changed files with 58 additions and 36 deletions

View file

@ -1,6 +1,7 @@
use crate::class_table::{self, ClassTableQueryContext};
use crate::class_table;
use crate::compiler::{CompilerQueryContext, Interner};
use salsa::dyn_descriptor::DynDescriptor;
use salsa::query_context_storage;
use salsa::BaseQueryContext;
use salsa::Query;
use salsa::QueryTable;
@ -14,41 +15,13 @@ pub struct QueryContextImpl {
execution_stack: RefCell<Vec<DynDescriptor>>,
}
// The intention is that plus the impl of `ClassTableQueryContext`
// below will eventually be generated by a macro, so that you just
// have to name the queries.
#[allow(non_snake_case)]
#[derive(Default)]
struct QueryContextImplStorage {
AllClasses: <class_table::AllClasses as Query<QueryContextImpl>>::Storage,
AllFields: <class_table::AllFields as Query<QueryContextImpl>>::Storage,
Fields: <class_table::Fields as Query<QueryContextImpl>>::Storage,
}
impl ClassTableQueryContext for QueryContextImpl {
fn all_classes(&self) -> QueryTable<'_, Self, class_table::AllClasses> {
QueryTable::new(
self,
&self.storage.AllClasses,
DynDescriptor::from_key::<Self, class_table::AllClasses>,
)
}
fn all_fields(&self) -> QueryTable<'_, Self, class_table::AllFields> {
QueryTable::new(
self,
&self.storage.AllFields,
DynDescriptor::from_key::<Self, class_table::AllFields>,
)
}
fn fields(&self) -> QueryTable<'_, Self, class_table::Fields> {
QueryTable::new(
self,
&self.storage.Fields,
DynDescriptor::from_key::<Self, class_table::Fields>,
)
query_context_storage! {
struct QueryContextImplStorage for storage in QueryContextImpl {
impl class_table::ClassTableQueryContext {
fn all_classes() for class_table::AllClasses;
fn all_fields() for class_table::AllFields;
fn fields() for class_table::Fields;
}
}
}

View file

@ -190,3 +190,52 @@ macro_rules! query_definition {
}
}
}
#[macro_export]
macro_rules! query_context_storage {
(
$(#[$attr:meta])*
$v:vis struct $Storage:ident for $storage_field:ident in $QueryContext:ty {
$(
impl $TraitName:path {
$(
fn $query_method:ident() for $QueryType:path;
)*
}
)*
}
) => {
#[allow(non_snake_case)]
#[derive(Default)]
$(#[$attr])*
$v struct $Storage {
$(
$(
$query_method: <$QueryType as $crate::Query<$QueryContext>>::Storage,
)*
)*
}
$(
impl $TraitName for $QueryContext {
$(
fn $query_method(
&self,
) -> $crate::QueryTable<'_, Self, $QueryType> {
QueryTable::new(
self,
&self.$storage_field.$query_method,
// FIXME: we should not hardcode the descriptor like this.
// Have to think of the best fix.
$crate::dyn_descriptor::DynDescriptor::from_key::<
Self,
$QueryType,
>,
)
}
)*
}
)*
};
}