forked from libre-chip/fayalite
initial public commit
This commit is contained in:
commit
0b958e7852
56 changed files with 30235 additions and 0 deletions
248
crates/fayalite-proc-macros-impl/src/fold.rs
Normal file
248
crates/fayalite-proc-macros-impl/src/fold.rs
Normal file
|
@ -0,0 +1,248 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
pub(crate) trait DoFold<State: ?Sized + syn::fold::Fold> {
|
||||
fn do_fold(self, state: &mut State) -> Self;
|
||||
}
|
||||
|
||||
impl<T: DoFold<State>, State: ?Sized + syn::fold::Fold> DoFold<State> for Box<T> {
|
||||
fn do_fold(mut self, state: &mut State) -> Self {
|
||||
*self = T::do_fold(*self, state);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DoFold<State>, State: ?Sized + syn::fold::Fold> DoFold<State> for Option<T> {
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
self.map(|v| T::do_fold(v, state))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DoFold<State>, State: ?Sized + syn::fold::Fold> DoFold<State> for Vec<T> {
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
Vec::from_iter(self.into_iter().map(|v| T::do_fold(v, state)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DoFold<State>, P: DoFold<State>, State: ?Sized + syn::fold::Fold> DoFold<State>
|
||||
for Punctuated<T, P>
|
||||
{
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
Punctuated::from_iter(self.into_pairs().map(|v| {
|
||||
let (v, p) = v.into_tuple().do_fold(state);
|
||||
Pair::new(v, p)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_fold_tuple {
|
||||
($($var0:ident: $T0:ident, $($var:ident: $T:ident,)*)?) => {
|
||||
$(impl_fold_tuple!($($var: $T,)*);)?
|
||||
impl_fold_tuple!(@impl $($var0: $T0, $($var: $T,)*)?);
|
||||
};
|
||||
(@impl $($var:ident: $T:ident,)*) => {
|
||||
impl<State: ?Sized + syn::fold::Fold, $($T: DoFold<State>,)*> DoFold<State> for ($($T,)*) {
|
||||
#[allow(clippy::unused_unit)]
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
let _ = state;
|
||||
let ($($var,)*) = self;
|
||||
$(let $var = $var.do_fold(state);)*
|
||||
($($var,)*)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_fold_tuple!(
|
||||
v0: T0,
|
||||
v1: T1,
|
||||
v2: T2,
|
||||
v3: T3,
|
||||
v4: T4,
|
||||
v5: T5,
|
||||
v6: T6,
|
||||
v7: T7,
|
||||
v8: T8,
|
||||
v9: T9,
|
||||
v10: T10,
|
||||
v11: T11,
|
||||
);
|
||||
|
||||
macro_rules! no_op_fold {
|
||||
($ty:ty) => {
|
||||
impl<State: ?Sized + syn::fold::Fold> $crate::fold::DoFold<State> for $ty {
|
||||
fn do_fold(self, _state: &mut State) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use no_op_fold;
|
||||
|
||||
macro_rules! impl_fold {
|
||||
(
|
||||
struct $Struct:ident<$($T:ident,)*> $(where ($($where:tt)*))? {
|
||||
$($field:ident: $field_ty:ty,)*
|
||||
}
|
||||
) => {
|
||||
impl<State: ?Sized + syn::fold::Fold, $($T,)*> $crate::fold::DoFold<State> for $Struct<$($T,)*>
|
||||
where
|
||||
$($T: $crate::fold::DoFold<State>,)*
|
||||
$($where)*
|
||||
{
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
let _ = state;
|
||||
let Self {
|
||||
$($field,)*
|
||||
} = self;
|
||||
Self {
|
||||
$($field: <$field_ty as $crate::fold::DoFold<State>>::do_fold($field, state),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
(
|
||||
struct $Struct:ident<$($T:ident,)*>(
|
||||
$field0_ty:ty $(,)?
|
||||
)
|
||||
$(where ($($where:tt)*))?;
|
||||
) => {
|
||||
impl<State: ?Sized + syn::fold::Fold, $($T,)*> $crate::fold::DoFold<State> for $Struct<$($T,)*>
|
||||
where
|
||||
$($T: $crate::fold::DoFold<State>,)*
|
||||
$($where)*
|
||||
{
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
let _ = state;
|
||||
let Self(
|
||||
v0,
|
||||
) = self;
|
||||
Self(
|
||||
<$field0_ty as $crate::fold::DoFold<State>>::do_fold(v0, state),
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
(
|
||||
enum $Enum:ident<$($T:ident,)*> $(where ($($where:tt)*))? {
|
||||
$($Variant:ident $({
|
||||
$($brace_field:ident: $brace_field_ty:ty,)*
|
||||
})?
|
||||
$((
|
||||
$($paren_field_ty:ty),* $(,)?
|
||||
))?,)*
|
||||
}
|
||||
) => {
|
||||
impl<State: ?Sized + syn::fold::Fold, $($T,)*> $crate::fold::DoFold<State> for $Enum<$($T,)*>
|
||||
where
|
||||
$($T: $crate::fold::DoFold<State>,)*
|
||||
$($where)*
|
||||
{
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
let _ = state;
|
||||
$crate::fold::impl_fold! {
|
||||
@enum_variants self, state => ()
|
||||
$($Variant $({
|
||||
$($brace_field: $brace_field_ty,)*
|
||||
})?
|
||||
$((
|
||||
$($paren_field_ty,)*
|
||||
))?,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
(
|
||||
@enum_variants $self:expr, $state:expr => ($($generated_arms:tt)*)
|
||||
) => {
|
||||
match $self {
|
||||
$($generated_arms)*
|
||||
}
|
||||
};
|
||||
(
|
||||
@enum_variants $self:expr, $state:expr => ($($generated_arms:tt)*)
|
||||
$Variant:ident {
|
||||
$($field:tt: $field_ty:ty,)*
|
||||
},
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
$crate::fold::impl_fold! {
|
||||
@enum_variants $self, $state => (
|
||||
$($generated_arms)*
|
||||
Self::$Variant {
|
||||
$($field,)*
|
||||
} => Self::$Variant {
|
||||
$($field: <$field_ty as $crate::fold::DoFold<State>>::do_fold($field, $state),)*
|
||||
},
|
||||
)
|
||||
$($rest)*
|
||||
}
|
||||
};
|
||||
(
|
||||
@enum_variants $self:expr, $state:expr => ($($generated_arms:tt)*)
|
||||
$Variant:ident(
|
||||
$field0_ty:ty $(,)?
|
||||
),
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
$crate::fold::impl_fold! {
|
||||
@enum_variants $self, $state => (
|
||||
$($generated_arms)*
|
||||
Self::$Variant(v0) => Self::$Variant(
|
||||
<$field0_ty as $crate::fold::DoFold<State>>::do_fold(v0, $state),
|
||||
),
|
||||
)
|
||||
$($rest)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) use impl_fold;
|
||||
use syn::punctuated::{Pair, Punctuated};
|
||||
|
||||
macro_rules! forward_fold {
|
||||
($ty:ty => $fn:ident) => {
|
||||
impl<State: syn::fold::Fold + ?Sized> DoFold<State> for $ty {
|
||||
fn do_fold(self, state: &mut State) -> Self {
|
||||
<State as syn::fold::Fold>::$fn(state, self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
forward_fold!(syn::Attribute => fold_attribute);
|
||||
forward_fold!(syn::AttrStyle => fold_attr_style);
|
||||
forward_fold!(syn::Expr => fold_expr);
|
||||
forward_fold!(syn::ExprArray => fold_expr_array);
|
||||
forward_fold!(syn::ExprCall => fold_expr_call);
|
||||
forward_fold!(syn::ExprIf => fold_expr_if);
|
||||
forward_fold!(syn::ExprMatch => fold_expr_match);
|
||||
forward_fold!(syn::ExprPath => fold_expr_path);
|
||||
forward_fold!(syn::ExprStruct => fold_expr_struct);
|
||||
forward_fold!(syn::ExprTuple => fold_expr_tuple);
|
||||
forward_fold!(syn::Ident => fold_ident);
|
||||
forward_fold!(syn::Member => fold_member);
|
||||
forward_fold!(syn::Path => fold_path);
|
||||
forward_fold!(syn::Type => fold_type);
|
||||
forward_fold!(syn::TypePath => fold_type_path);
|
||||
forward_fold!(syn::WherePredicate => fold_where_predicate);
|
||||
no_op_fold!(syn::parse::Nothing);
|
||||
no_op_fold!(syn::token::Brace);
|
||||
no_op_fold!(syn::token::Bracket);
|
||||
no_op_fold!(syn::token::Paren);
|
||||
no_op_fold!(syn::Token![_]);
|
||||
no_op_fold!(syn::Token![,]);
|
||||
no_op_fold!(syn::Token![;]);
|
||||
no_op_fold!(syn::Token![:]);
|
||||
no_op_fold!(syn::Token![..]);
|
||||
no_op_fold!(syn::Token![.]);
|
||||
no_op_fold!(syn::Token![#]);
|
||||
no_op_fold!(syn::Token![=]);
|
||||
no_op_fold!(syn::Token![=>]);
|
||||
no_op_fold!(syn::Token![|]);
|
||||
no_op_fold!(syn::Token![enum]);
|
||||
no_op_fold!(syn::Token![extern]);
|
||||
no_op_fold!(syn::Token![let]);
|
||||
no_op_fold!(syn::Token![mut]);
|
||||
no_op_fold!(syn::Token![struct]);
|
||||
no_op_fold!(syn::Token![where]);
|
Loading…
Add table
Add a link
Reference in a new issue