summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-01 16:56:35 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-02 09:18:33 +0100
commit37ac5d966ebaf97ac79c507028cd5b742b510b89 (patch)
tree249d43ff0f8d880cb5d00c236993f8ff0c1f10d8 /macros
parentf547c97072881069417acd3b79b08fb7ecf40ba2 (diff)
More dynamic content representation
Diffstat (limited to 'macros')
-rw-r--r--macros/src/lib.rs50
1 files changed, 39 insertions, 11 deletions
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index 62e27a09..5c367604 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -12,7 +12,7 @@ use syn::{Error, Ident, Result};
#[proc_macro_attribute]
pub fn node(stream: TokenStream, item: TokenStream) -> TokenStream {
let impl_block = syn::parse_macro_input!(item as syn::ItemImpl);
- expand(TokenStream2::from(stream), impl_block)
+ expand(stream.into(), impl_block)
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
@@ -51,14 +51,35 @@ fn expand(stream: TokenStream2, mut impl_block: syn::ItemImpl) -> Result<TokenSt
}
}
- let construct =
- construct.ok_or_else(|| Error::new(impl_block.span(), "missing constructor"))?;
+ let construct = construct.unwrap_or_else(|| {
+ parse_quote! {
+ fn construct(
+ _: &mut model::Vm,
+ _: &mut model::Args,
+ ) -> crate::diag::SourceResult<model::Content> {
+ unimplemented!()
+ }
+ }
+ });
let set = generate_set(&properties, set);
- let showable = match stream.to_string().as_str() {
- "" => false,
- "showable" => true,
- _ => return Err(Error::new(stream.span(), "unrecognized argument")),
+
+ let items: syn::punctuated::Punctuated<Ident, syn::Token![,]> =
+ parse_quote! { #stream };
+
+ let checks = items.iter().map(|cap| {
+ quote! {
+ if id == TypeId::of::<dyn #cap>() {
+ return Some(unsafe { crate::util::fat::vtable(self as &dyn #cap) });
+ }
+ }
+ });
+
+ let vtable = quote! {
+ fn vtable(&self, id: TypeId) -> Option<*const ()> {
+ #(#checks)*
+ None
+ }
};
// Put everything into a module with a hopefully unique type to isolate
@@ -75,9 +96,13 @@ fn expand(stream: TokenStream2, mut impl_block: syn::ItemImpl) -> Result<TokenSt
#impl_block
impl<#params> model::Node for #self_ty {
- const SHOWABLE: bool = #showable;
#construct
#set
+ #vtable
+
+ fn id(&self) -> model::NodeId {
+ model::NodeId::of::<Self>()
+ }
}
#(#key_modules)*
@@ -331,7 +356,7 @@ fn generate_set(
) -> syn::ImplItemMethod {
let user = user.map(|method| {
let block = &method.block;
- quote! { (|| -> SourceResult<()> { #block; Ok(()) } )()?; }
+ quote! { (|| -> crate::diag::SourceResult<()> { #block; Ok(()) } )()?; }
});
let mut shorthands = vec![];
@@ -367,8 +392,11 @@ fn generate_set(
});
parse_quote! {
- fn set(args: &mut Args, constructor: bool) -> SourceResult<StyleMap> {
- let mut styles = StyleMap::new();
+ fn set(
+ args: &mut model::Args,
+ constructor: bool,
+ ) -> crate::diag::SourceResult<model::StyleMap> {
+ let mut styles = model::StyleMap::new();
#user
#(#bindings)*
#(#sets)*