abi_stable_derive_lib/
datastructure.rs

1use crate::*;
2
3use std::fmt::Write;
4use std::{cmp, hash};
5
6use arrayvec::ArrayString;
7
8use syn::{
9    self, Attribute, Data, DeriveInput, Field as SynField, Fields as SynFields, Generics, Ident,
10    Type, Visibility,
11};
12
13use quote::ToTokens;
14
15use proc_macro2::{Span, TokenStream};
16
17mod field_map;
18
19pub(crate) use self::field_map::FieldMap;
20
21//////////////////////////////////////////////////////////////////////////////
22
23#[derive(Clone, Debug, PartialEq, Hash)]
24pub(crate) struct DataStructure<'a> {
25    pub(crate) vis: &'a Visibility,
26    pub(crate) name: &'a Ident,
27    pub(crate) generics: &'a Generics,
28    pub(crate) lifetime_count: usize,
29    pub(crate) field_count: usize,
30    pub(crate) pub_field_count: usize,
31    // pub(crate) fn_ptr_count:usize,
32
33    // pub(crate) fn_info: FnInfo<'a>,
34
35    pub(crate) attrs: &'a [Attribute],
36
37    pub(crate) data_variant: DataVariant,
38    pub(crate) enum_: Option<Enum<'a>>,
39    pub(crate) variants: Vec<Struct<'a>>,
40}
41
42#[derive(Clone, Debug)]
43pub(crate) struct Enum<'a> {
44    pub(crate) name: &'a Ident,
45    pub(crate) path: TokenStream,
46}
47
48impl<'a> cmp::PartialEq for Enum<'a> {
49    fn eq(&self, other: &Self) -> bool {
50        self.name == other.name
51    }
52}
53
54impl<'a> hash::Hash for Enum<'a> {
55    fn hash<H>(&self, hasher: &mut H)
56    where
57        H: hash::Hasher,
58    {
59        self.name.hash(hasher);
60    }
61}
62
63impl<'a> DataStructure<'a> {
64    pub(crate) fn new(
65        ast: &'a mut DeriveInput, 
66        _arenas: &'a Arenas,
67    ) -> Self {
68        let name = &ast.ident;
69        let enum_ = match ast.data {
70            Data::Enum(_) => Some(Enum {
71                name,
72                path: quote! { #name:: },
73            }),
74            _ => None,
75        };
76
77        let data_variant: DataVariant;
78
79        // let mut ty_visitor = TypeVisitor::new(arenas, ctokens, &ast.generics);
80
81        let mut variants = Vec::new();
82
83
84        match &mut ast.data {
85            Data::Enum(enum_) => {
86                let override_vis=Some(&ast.vis);
87
88                for (variant,var) in (&mut enum_.variants).into_iter().enumerate() {
89                    variants.push(Struct::new(
90                        StructParams{
91                            discriminant:var.discriminant
92                                .as_ref()
93                                .map(|(_,v)| v ),
94                            variant:variant,
95                            attrs:&var.attrs,
96                            name:&var.ident,
97                            override_vis:override_vis,
98                        },
99                        &mut var.fields,
100                        // &mut ty_visitor,
101                    ));
102                }
103                data_variant = DataVariant::Enum;
104            }
105            Data::Struct(struct_) => {
106                let override_vis=None;
107
108                variants.push(Struct::new(
109                    StructParams{
110                        discriminant:None,
111                        variant:0,
112                        attrs:&[],
113                        name:name,
114                        override_vis:override_vis,
115                    },
116                    &mut struct_.fields,
117                    // &mut ty_visitor,
118                ));
119                data_variant = DataVariant::Struct;
120            }
121
122            Data::Union(union_) => {
123                let override_vis=None;
124
125                let fields = Some(&union_.fields.named);
126                let sk = StructKind::Braced;
127                let vari = Struct::with_fields(
128                    StructParams{
129                        discriminant:None,
130                        variant:0,
131                        attrs:&[], 
132                        name:name, 
133                        override_vis:override_vis,
134                    },
135                    sk, 
136                    fields,
137                    // &mut ty_visitor
138                );
139                variants.push(vari);
140                data_variant = DataVariant::Union;
141            }
142        }
143
144        let mut field_count=0;
145        let mut pub_field_count=0;
146        // let mut fn_ptr_count=0;
147
148        for vari in &variants {
149            field_count+=vari.fields.len();
150            pub_field_count+=vari.pub_field_count;
151            // fn_ptr_count+=vari.fn_ptr_count;
152        }
153
154        Self {
155            vis: &ast.vis,
156            name,
157            // fn_info: ty_visitor.into_fn_info(),
158            attrs: &ast.attrs,
159            generics: &ast.generics,
160            lifetime_count:ast.generics.lifetimes().count(),
161            data_variant,
162            enum_,
163            variants,
164            field_count,
165            pub_field_count,
166            // fn_ptr_count,
167        }
168    }
169
170    pub(crate) fn has_public_fields(&self)->bool{
171        self.pub_field_count!=0
172    }
173}
174
175//////////////////////////////////////////////////////////////////////////////
176
177/// Whether the struct is tupled or not.
178#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
179pub(crate) enum StructKind {
180    /// structs declared using the `struct Name( ... ) syntax.
181    Tuple,
182    /// structs declared using the `struct Name{ ... }` or `struct name;` syntaxes
183    Braced,
184}
185
186#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
187pub(crate) enum DataVariant {
188    Struct,
189    Enum,
190    Union,
191}
192
193
194#[derive(Copy,Clone, Debug, PartialEq, Hash)]
195pub(crate) struct FieldIndex {
196    pub(crate) variant:usize,
197    pub(crate) pos:usize,
198}
199
200//////////////////////////////////////////////////////////////////////////////
201
202
203#[derive(Copy,Clone)]
204pub(crate) struct StructParams<'a>{
205    pub(crate) discriminant:Option<&'a syn::Expr>,
206    pub(crate) variant:usize,
207    pub(crate) attrs: &'a [Attribute],
208    pub(crate) name: &'a Ident,
209    pub(crate) override_vis:Option<&'a Visibility>,
210}
211
212
213#[derive(Clone, Debug, PartialEq, Hash)]
214pub(crate) struct Struct<'a> {
215    pub(crate) attrs: &'a [Attribute],
216    pub(crate) name: &'a Ident,
217    pub(crate) kind: StructKind,
218    pub(crate) fields: Vec<Field<'a>>,
219    pub(crate) pub_field_count:usize,
220    // pub(crate) fn_ptr_count:usize,
221    pub(crate) discriminant:Option<&'a syn::Expr>,
222    _priv: (),
223}
224
225impl<'a> Struct<'a> {
226    pub(crate) fn new(
227        p:StructParams<'a>,
228        fields: &'a SynFields,
229        // tv: &mut TypeVisitor<'a>,
230    ) -> Self {
231        let kind = match *fields {
232            SynFields::Named { .. } => StructKind::Braced,
233            SynFields::Unnamed { .. } => StructKind::Tuple,
234            SynFields::Unit { .. } => StructKind::Braced,
235        };
236        let fields = match fields {
237            SynFields::Named(f) => Some(&f.named),
238            SynFields::Unnamed(f) => Some(&f.unnamed),
239            SynFields::Unit => None,
240        };
241
242        Self::with_fields(p, kind, fields)
243        // Self::with_fields(p, kind, fields, tv)
244    }
245
246    pub(crate) fn with_fields<I>(
247        p:StructParams<'a>,
248        kind: StructKind,
249        fields: Option<I>,
250        // tv: &mut TypeVisitor<'a>,
251    ) -> Self
252    where
253        I: IntoIterator<Item = &'a SynField>,
254    {
255        let fields=match fields {
256            Some(x) => Field::from_iter(p, x),
257            // Some(x) => Field::from_iter(p, x, tv),
258            None => Vec::new(),
259        };
260
261        let mut pub_field_count=0usize;
262        // let mut fn_ptr_count=0usize;
263
264        for field in &fields {
265            if field.is_public() {
266                pub_field_count+=1;
267            }
268            // fn_ptr_count+=field.functions.len();
269        }
270
271        Self {
272            discriminant:p.discriminant,
273            attrs:p.attrs,
274            name:p.name,
275            kind,
276            pub_field_count,
277            // fn_ptr_count,
278            fields,
279            _priv: (),
280        }
281    }
282
283    }
284
285//////////////////////////////////////////////////////////////////////////////
286
287/// Represent a struct field
288///
289#[derive(Clone, Debug, PartialEq, Hash)]
290pub(crate) struct Field<'a> {
291    pub(crate) index:FieldIndex,
292    pub(crate) attrs: &'a [Attribute],
293    pub(crate) vis: &'a Visibility,
294    // pub(crate) referenced_lifetimes: Vec<LifetimeIndex>,
295    /// identifier for the field,which is either an index(in a tuple struct) or a name.
296    pub(crate) ident: FieldIdent<'a>,
297    pub(crate) ty: &'a Type,
298    // /// Whether the type of this field is just a function pointer.
299    // pub(crate) is_function:bool,
300    // /// The type used to get the AbiInfo of the field.
301    // /// This has all parameter and return types of function pointers removed.
302    // /// Extracted into the `functions` field of this struct.
303    // pub(crate) mutated_ty: Type,
304    // /// The function pointers from this field.
305    // pub(crate) functions:Vec<Function<'a>>,
306}
307
308impl<'a> Field<'a> {
309    pub(crate) fn new(
310        index: FieldIndex,
311        field: &'a SynField,
312        span: Span,
313        override_vis:Option<&'a Visibility>,
314        // tv: &mut TypeVisitor<'a>,
315    ) -> Self {
316        let ident = match field.ident.as_ref() {
317            Some(ident) => FieldIdent::Named(ident),
318            None => FieldIdent::new_index(index.pos, span),
319        };
320
321        // let mut mutated_ty=field.ty.clone();
322
323        // let visit_info = tv.visit_field(&mut mutated_ty);
324
325        // let is_function=match field.ty {
326        //     Type::BareFn{..}=>true,
327        //     _=>false,
328        // };
329
330        Self {
331            index,
332            attrs: &field.attrs,
333            vis: override_vis.unwrap_or(&field.vis),
334            // referenced_lifetimes: visit_info.referenced_lifetimes,
335            ident,
336            ty: &field.ty,
337            // is_function,
338            // mutated_ty,
339            // functions: visit_info.functions,
340        }
341    }
342
343    pub(crate) fn is_public(&self)->bool{
344        match self.vis {
345            Visibility::Public{..}=>true,
346            _=>false,
347        }
348    }
349
350
351    pub(crate) fn ident(&self)->&Ident{
352        match &self.ident {
353            FieldIdent::Index(_,ident)=>ident,
354            FieldIdent::Named(ident)=>ident,
355        }
356    }
357
358    pub(crate) fn from_iter<I>(
359        p:StructParams<'a>,
360        fields: I, 
361        // tv: &mut TypeVisitor<'a>
362    ) -> Vec<Self>
363    where
364        I: IntoIterator<Item = &'a SynField>,
365    {
366        fields
367            .into_iter()
368            .enumerate()
369            .map(|(pos, f)|{ 
370                let fi=FieldIndex{variant:p.variant,pos};
371                // Field::new(fi, f, p.name.span(),p.override_vis, tv)
372                Field::new(fi, f, p.name.span(),p.override_vis)
373            })
374            .collect()
375    }
376}
377
378//////////////////////////////////////////////////////////////////////////////
379
380#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
381pub(crate) enum FieldIdent<'a> {
382    Index(usize, Ident),
383    Named(&'a Ident),
384}
385
386impl<'a> ToTokens for FieldIdent<'a> {
387    fn to_tokens(&self, tokens: &mut TokenStream) {
388        match *self {
389            FieldIdent::Index(ind, ..) => syn::Index::from(ind).to_tokens(tokens),
390            FieldIdent::Named(name) => name.to_tokens(tokens),
391        }
392    }
393}
394
395impl<'a> FieldIdent<'a> {
396    fn new_index(index: usize, span: Span) -> Self {
397        let mut buff = ArrayString::<[u8; 16]>::new();
398        let _ = write!(buff, "field_{}", index);
399        FieldIdent::Index(index, Ident::new(&buff, span))
400    }
401}
402