#![feature(proc_macro_diagnostic, proc_macro_span)]
extern crate proc_macro;
mod declare_derive;
mod lerp_derive;
mod util;
use fn_widget_macro::FnWidgetMacro;
use proc_macro::TokenStream;
use quote::quote;
use symbol_process::DollarRefsCtx;
use syn::{parse_macro_input, DeriveInput};
mod child_template;
mod fn_widget_macro;
mod pipe_macro;
mod rdl_macro;
pub(crate) mod variable_names;
mod watch_macro;
mod writer_map_macro;
pub(crate) use rdl_macro::*;
use crate::pipe_macro::PipeMacro;
use crate::watch_macro::WatchMacro;
pub(crate) mod declare_obj;
pub(crate) mod symbol_process;
macro_rules! ok {
($e: expr) => {
match $e {
Ok(ok) => ok,
Err(err) => return err.into(),
}
};
}
pub(crate) use ok;
#[proc_macro_derive(SingleChild)]
pub fn single_marco_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let name = input.ident;
quote! {
impl #impl_generics SingleChild for #name #ty_generics #where_clause {}
}
.into()
}
#[proc_macro_derive(Query)]
pub fn query_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let name = input.ident;
quote! {
impl #impl_generics Query for #name #ty_generics #where_clause {
#[inline]
fn query_inside_first(
&self,
type_id: TypeId,
callback: &mut dyn FnMut(&dyn Any) -> bool
)-> bool {
self.query_outside_first(type_id, callback)
}
#[inline]
fn query_outside_first(
&self,
type_id: TypeId,
callback: &mut dyn FnMut(&dyn Any) -> bool
) -> bool{
if type_id == self.type_id() {
callback(self)
} else {
true
}
}
}
}
.into()
}
#[proc_macro_derive(MultiChild)]
pub fn multi_macro_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let name = input.ident;
quote! {
impl #impl_generics MultiChild for #name #ty_generics #where_clause {}
}
.into()
}
#[proc_macro_derive(PairChild)]
pub fn pair_compose_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let name = input.ident;
quote! {
impl #impl_generics PairChild for #name #ty_generics #where_clause {}
}
.into()
}
#[proc_macro_derive(Lerp)]
pub fn lerp_derive(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
lerp_derive::lerp_derive(&mut input)
.unwrap_or_else(|e| e.into_compile_error())
.into()
}
#[proc_macro_derive(Declare, attributes(declare))]
pub fn declare_trait_macro_derive2(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
declare_derive::declare_derive(&mut input)
.unwrap_or_else(|e| e.into_compile_error())
.into()
}
#[proc_macro_derive(Template, attributes(template))]
pub fn child_template_trait_derive(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
child_template::derive_child_template(&mut input)
.unwrap_or_else(|e| e.into_compile_error())
.into()
}
#[proc_macro]
pub fn rdl(input: TokenStream) -> TokenStream {
let mut refs = DollarRefsCtx::top_level();
refs.new_dollar_scope(false);
RdlMacro::gen_code(input.into(), &mut refs)
}
#[proc_macro]
pub fn fn_widget(input: TokenStream) -> TokenStream {
FnWidgetMacro::gen_code(input.into(), &mut DollarRefsCtx::top_level())
}
#[proc_macro]
pub fn ribir_expanded_ಠ_ಠ(input: TokenStream) -> TokenStream { input }
#[proc_macro]
pub fn ctx(input: TokenStream) -> TokenStream {
let tokens = if !input.is_empty() {
quote!(compile_error!("ctx! macro does not accept any argument"))
} else {
quote! { _ctx_ಠ_ಠ }
};
tokens.into()
}
#[proc_macro]
pub fn pipe(input: TokenStream) -> TokenStream {
PipeMacro::gen_code(input.into(), &mut DollarRefsCtx::top_level())
}
#[proc_macro]
pub fn watch(input: TokenStream) -> TokenStream {
WatchMacro::gen_code(input.into(), &mut DollarRefsCtx::top_level())
}
#[proc_macro]
pub fn split_writer(input: TokenStream) -> TokenStream {
writer_map_macro::gen_split_path_writer(input.into(), &mut DollarRefsCtx::top_level())
}
#[proc_macro]
pub fn map_writer(input: TokenStream) -> TokenStream {
writer_map_macro::gen_map_path_writer(input.into(), &mut DollarRefsCtx::top_level())
}
#[proc_macro]
pub fn include_svg(input: TokenStream) -> TokenStream {
let w = parse_macro_input! { input as syn::LitStr };
let mut span = proc_macro::Span::call_site();
while let Some(p) = span.parent() {
span = p;
}
let mut file = span.source_file().path();
file.pop();
file.push(w.value());
let encoded_bytes = ribir_painter::Svg::open(file).and_then(|reader| reader.serialize());
match encoded_bytes {
Ok(data) => quote! {
Svg::deserialize(#data).unwrap()
}
.into(),
Err(err) => {
let err = format!("{err}");
quote! { compile_error!(#err)}.into()
}
}
}