pub(crate) fn analyze(syn_items: &[syn::DeriveInput]) -> Result<Ir> {
    let mut items = BTreeMap::new();
    for syn_item in syn_items {
        let name = syn_item.ident.to_string();
        let generics = analyze_generics(&syn_item.generics)?;
        let item = match &syn_item.data {
            syn::Data::Struct(s) => Item::Struct(Struct {
                fields: analyze_fields(&s.fields)?,
                generics,
            }),
            syn::Data::Enum(e) => {
                let mut variants = vec![];
                for v in &e.variants {
                    variants.push(Variant {
                        name: v.ident.to_string(),
                        fields: analyze_fields(&v.fields)?,
                    });
                }
                Item::Enum(Enum { variants, generics })
            }
            syn::Data::Union(_) => bail!("Unable to analyze union: {}", syn_item.ident),
        };
        for field in item.fields() {
            if let Type::Abstract(ty) = &field.ty {
                items.insert(ty.clone(), Item::Abstract);
            }
        }
        items.insert(name, item);
    }

    let mut generics = BTreeMap::<_, BTreeSet<String>>::new();
    for item in items.values() {
        for ig in item.generics() {
            generics
                .entry(ig.name.clone())
                .or_default()
                .extend(ig.bounds.clone());
        }
    }

    for item in items.values() {
        validate_fields(&items, item.fields())?
    }

    Ok(Ir { items, generics })
}
/// Analyzes the provided items and produces an IR.
///
/// This is a very, very lightweight semantic analysis phase for Rust code. Our
/// main goal is to determine the type of each field of a struct or enum
/// variant, so we know how to visit it. See [`Type`] for details.
Analyzes the provided items and produces an IR.
This is a very, very lightweight semantic analysis phase for Rust code. Our
main goal is to determine the type of each field of a struct or enum
variant, so we know how to visit it. See [`Type`] for details.
Analyzes the provided items and produces an IR . This is a very very lightweight semantic analysis phase for Rust code . Our main goal is to determine the type of each field of a struct or enum variant so we know how to visit it . See [ ` Type ` ] for details .
pub(crate) fn analyze(syn_items: &[syn::DeriveInput]) -> Result<Ir> {
    let mut items = BTreeMap::new();
    for syn_item in syn_items {
        let name = syn_item.ident.to_string();
        let generics = analyze_generics(&syn_item.generics)?;
        let item = match &syn_item.data {
            syn::Data::Struct(s) => Item::Struct(Struct {
                fields: analyze_fields(&s.fields)?,
                generics,
            }),
            syn::Data::Enum(e) => {
                let mut variants = vec![];
                for v in &e.variants {
                    variants.push(Variant {
                        name: v.ident.to_string(),
                        fields: analyze_fields(&v.fields)?,
                    });
                }
                Item::Enum(Enum { variants, generics })
            }
            syn::Data::Union(_) => bail!("Unable to analyze union: {}", syn_item.ident),
        };
        for field in item.fields() {
            if let Type::Abstract(ty) = &field.ty {
                items.insert(ty.clone(), Item::Abstract);
            }
        }
        items.insert(name, item);
    }
    let mut generics = BTreeMap::<_, BTreeSet<String>>::new();
    for item in items.values() {
        for ig in item.generics() {
            generics
                .entry(ig.name.clone())
                .or_default()
                .extend(ig.bounds.clone());
        }
    }
    for item in items.values() {
        validate_fields(&items, item.fields())?
    }
    Ok(Ir { items, generics })
}
pub ( crate ) fn analyze ( syn_items : & [ syn :: DeriveInput ] ) -> Result < Ir > { let mut items = BTreeMap :: new ( ) ; for syn_item in syn_items { let name = syn_item . ident . to_string ( ) ; let generics = analyze_generics ( & syn_item . generics ) ? ; let item = match & syn_item . data { syn :: Data :: Struct ( s ) => Item :: Struct ( Struct { fields : analyze_fields ( & s . fields ) ? , generics , } ) , syn :: Data :: Enum ( e ) => { let mut variants = vec ! [ ] ; for v in & e . variants { variants . push ( Variant { name : v . ident . to_string ( ) , fields : analyze_fields ( & v . fields ) ? , } ) ; } Item :: Enum ( Enum { variants , generics } ) } syn :: Data :: Union ( _ ) => bail ! ( " " syn_item ident ) , } ; for field in item . fields ( ) { if let Type :: Abstract ( ty ) = & field . ty { items . insert ( ty . clone ( ) , Item :: Abstract ) ; } } items . insert ( name , item ) ; } let mut generics = BTreeMap :: < _ , BTreeSet < String > > :: new ( ) ; for item in items . values ( ) { for ig in item . generics ( ) { generics . entry ( ig . name . clone ( ) ) . or_default ( ) . extend ( ig . bounds . clone ( ) ) ; } } for item in items . values ( ) { validate_fields ( & items , item . fields ( ) ) ? } Ok ( Ir { items , generics } ) }
Analyzes the provided items and produces an IR.
Analyzes the provided items and produces an IR .
syn_items
&[syn::DeriveInput]
syn_items
&[syn::DeriveInput]