From 9b4267f7c1ac41df82897056cebe7f2f619c8a14 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 28 Sep 2018 14:26:46 -0400 Subject: [PATCH] add a boilerplate reducing macro --- examples/hello_world/implementation.rs | 45 +++++------------------ src/lib.rs | 49 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 36 deletions(-) diff --git a/examples/hello_world/implementation.rs b/examples/hello_world/implementation.rs index a6790419..b42dd9b4 100644 --- a/examples/hello_world/implementation.rs +++ b/examples/hello_world/implementation.rs @@ -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>, } -// 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: >::Storage, - AllFields: >::Storage, - Fields: >::Storage, -} - -impl ClassTableQueryContext for QueryContextImpl { - fn all_classes(&self) -> QueryTable<'_, Self, class_table::AllClasses> { - QueryTable::new( - self, - &self.storage.AllClasses, - DynDescriptor::from_key::, - ) - } - - fn all_fields(&self) -> QueryTable<'_, Self, class_table::AllFields> { - QueryTable::new( - self, - &self.storage.AllFields, - DynDescriptor::from_key::, - ) - } - - fn fields(&self) -> QueryTable<'_, Self, class_table::Fields> { - QueryTable::new( - self, - &self.storage.Fields, - DynDescriptor::from_key::, - ) +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; + } } } diff --git a/src/lib.rs b/src/lib.rs index ee98faeb..c2f1729a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, + >, + ) + } + )* + } + )* + }; +}