253 lines
7.4 KiB
Rust
253 lines
7.4 KiB
Rust
// 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::ExprRepeat => fold_expr_repeat);
|
|
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]);
|