@@ -8,9 +8,12 @@ use crate::svd::{
88use log:: { debug, trace, warn} ;
99use proc_macro2:: { Ident , Punct , Spacing , Span , TokenStream } ;
1010use quote:: { quote, ToTokens } ;
11- use syn:: { parse_str , Token } ;
11+ use syn:: { punctuated :: Punctuated , Token } ;
1212
13- use crate :: util:: { self , unsuffixed, Config , FullName , ToSanitizedCase , BITS_PER_BYTE } ;
13+ use crate :: util:: {
14+ self , array_proxy_type, name_to_ty, name_to_wrapped_ty, new_syn_u32, path_segment, type_path,
15+ unsuffixed, Config , FullName , ToSanitizedCase , BITS_PER_BYTE ,
16+ } ;
1417use anyhow:: { anyhow, bail, Context , Result } ;
1518
1619use crate :: generate:: register;
@@ -686,7 +689,7 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
686689 let span = Span :: call_site ( ) ;
687690 let mut accessors = TokenStream :: new ( ) ;
688691 let nb_name = util:: replace_suffix ( & info. name , "" ) ;
689- let ty = name_to_ty ( & nb_name) ? ;
692+ let ty = name_to_ty ( & nb_name) ;
690693 let nb_name_cs = nb_name. to_snake_case_ident ( span) ;
691694 for ( i, idx) in array_info. indexes ( ) . enumerate ( ) {
692695 let idx_name =
@@ -717,14 +720,13 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
717720 } else if sequential_indexes_from0 && config. const_generic {
718721 // Include a ZST ArrayProxy giving indexed access to the
719722 // elements.
720- cluster_expanded. push ( array_proxy ( info, array_info) ? ) ;
723+ cluster_expanded. push ( array_proxy ( info, array_info) ) ;
721724 } else {
722725 let ty_name = util:: replace_suffix ( & info. name , "" ) ;
723- let ty = name_to_ty ( & ty_name) ? ;
726+ let ty = syn :: Type :: Path ( name_to_ty ( & ty_name) ) ;
724727
725728 for ( field_num, idx) in array_info. indexes ( ) . enumerate ( ) {
726729 let nb_name = util:: replace_suffix ( & info. name , & idx) ;
727-
728730 let syn_field =
729731 new_syn_field ( nb_name. to_snake_case_ident ( Span :: call_site ( ) ) , ty. clone ( ) ) ;
730732
@@ -790,7 +792,7 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
790792 let span = Span :: call_site ( ) ;
791793 let mut accessors = TokenStream :: new ( ) ;
792794 let nb_name = util:: replace_suffix ( & info. fullname ( config. ignore_groups ) , "" ) ;
793- let ty = name_to_wrapped_ty ( & nb_name) ? ;
795+ let ty = name_to_wrapped_ty ( & nb_name) ;
794796 let nb_name_cs = nb_name. to_snake_case_ident ( span) ;
795797 let info_name = info. fullname ( config. ignore_groups ) ;
796798 for ( i, idx) in array_info. indexes ( ) . enumerate ( ) {
@@ -822,11 +824,10 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
822824 } else {
823825 let info_name = info. fullname ( config. ignore_groups ) ;
824826 let ty_name = util:: replace_suffix ( & info_name, "" ) ;
825- let ty = name_to_wrapped_ty ( & ty_name) ? ;
827+ let ty = name_to_wrapped_ty ( & ty_name) ;
826828
827829 for ( field_num, idx) in array_info. indexes ( ) . enumerate ( ) {
828830 let nb_name = util:: replace_suffix ( & info_name, & idx) ;
829-
830831 let syn_field =
831832 new_syn_field ( nb_name. to_snake_case_ident ( Span :: call_site ( ) ) , ty. clone ( ) ) ;
832833
@@ -863,8 +864,7 @@ fn render_ercs(
863864 if let Some ( dpath) = dpath {
864865 cpath = derive_cluster ( c, & dpath, path, index) ?;
865866 }
866- let cpath = cpath. unwrap_or_else ( || path. new_cluster ( & c. name ) ) ;
867- mod_items. extend ( cluster_block ( c, & cpath, index, config) ?) ;
867+ mod_items. extend ( cluster_block ( c, path, cpath, index, config) ?) ;
868868 }
869869
870870 // Generate definition for each of the registers.
@@ -876,10 +876,9 @@ fn render_ercs(
876876 rpath = derive_register ( reg, & dpath, path, index) ?;
877877 }
878878 let reg_name = & reg. name ;
879- let rpath = rpath. unwrap_or_else ( || path. new_register ( reg_name) ) ;
880879
881880 let rendered_reg =
882- register:: render ( reg, & rpath, index, config) . with_context ( || {
881+ register:: render ( reg, path , rpath, index, config) . with_context ( || {
883882 let descrip = reg. description . as_deref ( ) . unwrap_or ( "No description" ) ;
884883 format ! (
885884 "Error rendering register\n Name: {reg_name}\n Description: {descrip}"
@@ -896,23 +895,57 @@ fn render_ercs(
896895fn cluster_block (
897896 c : & mut Cluster ,
898897 path : & BlockPath ,
898+ dpath : Option < BlockPath > ,
899899 index : & Index ,
900900 config : & Config ,
901901) -> Result < TokenStream > {
902- let mod_items = render_ercs ( & mut c. children , path, index, config) ?;
903-
904- // Generate the register block.
902+ let description =
903+ util:: escape_brackets ( & util:: respace ( c. description . as_ref ( ) . unwrap_or ( & c. name ) ) ) ;
905904 let mod_name = util:: replace_suffix ( & c. name , "" ) ;
906905
907- let reg_block = register_or_cluster_block ( & c. children , Some ( & mod_name) , config) ?;
908-
909906 // name_snake_case needs to take into account array type.
910- let description =
911- util:: escape_brackets ( & util:: respace ( c. description . as_ref ( ) . unwrap_or ( & c. name ) ) ) ;
907+ let span = Span :: call_site ( ) ;
908+ let name_snake_case = mod_name. to_snake_case_ident ( span) ;
909+ let name_constant_case = mod_name. to_constant_case_ident ( span) ;
910+
911+ let struct_path = name_to_ty ( & mod_name) ;
912912
913- let name_snake_case = mod_name. to_snake_case_ident ( Span :: call_site ( ) ) ;
913+ let mod_items = if let Some ( dpath) = dpath {
914+ let dparent = util:: parent ( & dpath) ;
915+ let mut derived = if & dparent == path {
916+ let mut segments = Punctuated :: new ( ) ;
917+ segments. push ( path_segment ( Ident :: new ( "super" , span) ) ) ;
918+ type_path ( segments)
919+ } else {
920+ util:: block_path_to_ty ( & dparent, span)
921+ } ;
922+ let dname = util:: replace_suffix ( & index. clusters . get ( & dpath) . unwrap ( ) . name , "" ) ;
923+ derived
924+ . path
925+ . segments
926+ . push ( path_segment ( dname. to_snake_case_ident ( span) ) ) ;
927+ derived
928+ . path
929+ . segments
930+ . push ( path_segment ( dname. to_constant_case_ident ( span) ) ) ;
914931
915- let struct_path = name_to_ty ( & mod_name) ?;
932+ quote ! {
933+ #[ doc = #description]
934+ pub use #derived as #name_constant_case;
935+ }
936+ } else {
937+ let cpath = path. new_cluster ( & c. name ) ;
938+ let mod_items = render_ercs ( & mut c. children , & cpath, index, config) ?;
939+
940+ // Generate the register block.
941+ let reg_block = register_or_cluster_block ( & c. children , Some ( & mod_name) , config) ?;
942+
943+ quote ! {
944+ #reg_block
945+
946+ #mod_items
947+ }
948+ } ;
916949
917950 Ok ( quote ! {
918951 #[ doc = #description]
@@ -921,8 +954,6 @@ fn cluster_block(
921954 ///Cluster
922955 #[ doc = #description]
923956 pub mod #name_snake_case {
924- #reg_block
925-
926957 #mod_items
927958 }
928959 } )
@@ -933,15 +964,13 @@ fn register_to_syn_field(register: &Register, ignore_group: bool) -> Result<syn:
933964 Ok ( match register {
934965 Register :: Single ( info) => {
935966 let info_name = info. fullname ( ignore_group) ;
936- let ty = name_to_wrapped_ty ( & info_name)
937- . with_context ( || format ! ( "Error converting register name {info_name}" ) ) ?;
967+ let ty = name_to_wrapped_ty ( & info_name) ;
938968 new_syn_field ( info_name. to_snake_case_ident ( Span :: call_site ( ) ) , ty)
939969 }
940970 Register :: Array ( info, array_info) => {
941971 let info_name = info. fullname ( ignore_group) ;
942972 let nb_name = util:: replace_suffix ( & info_name, "" ) ;
943- let ty = name_to_wrapped_ty ( & nb_name)
944- . with_context ( || format ! ( "Error converting register name {nb_name}" ) ) ?;
973+ let ty = name_to_wrapped_ty ( & nb_name) ;
945974 let array_ty = new_syn_array ( ty, array_info. dim ) ;
946975
947976 new_syn_field ( nb_name. to_snake_case_ident ( Span :: call_site ( ) ) , array_ty)
@@ -950,42 +979,31 @@ fn register_to_syn_field(register: &Register, ignore_group: bool) -> Result<syn:
950979}
951980
952981/// Return an syn::Type for an ArrayProxy.
953- fn array_proxy (
954- info : & ClusterInfo ,
955- array_info : & DimElement ,
956- ) -> Result < RegisterBlockField , syn:: Error > {
982+ fn array_proxy ( info : & ClusterInfo , array_info : & DimElement ) -> RegisterBlockField {
957983 let ty_name = util:: replace_suffix ( & info. name , "" ) ;
958- let tys = name_to_ty_str ( & ty_name) ;
959-
960- let ap_path = parse_str :: < syn:: TypePath > ( & format ! (
961- "crate::ArrayProxy<{tys}, {}, {}>" ,
962- array_info. dim,
963- util:: hex( array_info. dim_increment as u64 ) . into_token_stream( ) ,
964- ) ) ?;
965-
966- Ok ( RegisterBlockField {
967- syn_field : new_syn_field (
968- ty_name. to_snake_case_ident ( Span :: call_site ( ) ) ,
969- ap_path. into ( ) ,
970- ) ,
984+ let ty = name_to_ty ( & ty_name) ;
985+
986+ let ap_path = array_proxy_type ( ty, array_info) ;
987+
988+ RegisterBlockField {
989+ syn_field : new_syn_field ( ty_name. to_snake_case_ident ( Span :: call_site ( ) ) , ap_path) ,
971990 description : info. description . as_ref ( ) . unwrap_or ( & info. name ) . into ( ) ,
972991 offset : info. address_offset ,
973992 size : 0 ,
974993 accessors : None ,
975- } )
994+ }
976995}
977996
978997/// Convert a parsed `Cluster` into its `Field` equivalent
979998fn cluster_to_syn_field ( cluster : & Cluster ) -> Result < syn:: Field , syn:: Error > {
980999 Ok ( match cluster {
9811000 Cluster :: Single ( info) => {
982- let ty_name = util:: replace_suffix ( & info. name , "" ) ;
983- let ty = name_to_ty ( & ty_name) ?;
1001+ let ty = syn:: Type :: Path ( name_to_ty ( & info. name ) ) ;
9841002 new_syn_field ( info. name . to_snake_case_ident ( Span :: call_site ( ) ) , ty)
9851003 }
9861004 Cluster :: Array ( info, array_info) => {
9871005 let ty_name = util:: replace_suffix ( & info. name , "" ) ;
988- let ty = name_to_ty ( & ty_name) ? ;
1006+ let ty = syn :: Type :: Path ( name_to_ty ( & ty_name) ) ;
9891007 let array_ty = new_syn_array ( ty, array_info. dim ) ;
9901008
9911009 new_syn_field ( ty_name. to_snake_case_ident ( Span :: call_site ( ) ) , array_ty)
@@ -1015,39 +1033,3 @@ fn new_syn_array(ty: syn::Type, len: u32) -> syn::Type {
10151033 len : new_syn_u32 ( len, span) ,
10161034 } )
10171035}
1018-
1019- fn new_syn_u32 ( len : u32 , span : Span ) -> syn:: Expr {
1020- syn:: Expr :: Lit ( syn:: ExprLit {
1021- attrs : Vec :: new ( ) ,
1022- lit : syn:: Lit :: Int ( syn:: LitInt :: new ( & len. to_string ( ) , span) ) ,
1023- } )
1024- }
1025-
1026- fn name_to_ty_str ( name : & str ) -> String {
1027- format ! (
1028- "{}::{}" ,
1029- name. to_sanitized_snake_case( ) ,
1030- name. to_sanitized_constant_case( )
1031- )
1032- }
1033-
1034- fn name_to_ty ( name : & str ) -> Result < syn:: Type , syn:: Error > {
1035- let ident = name_to_ty_str ( name) ;
1036- parse_str :: < syn:: TypePath > ( & ident) . map ( syn:: Type :: Path )
1037- }
1038-
1039- fn name_to_wrapped_ty_str ( name : & str ) -> String {
1040- format ! (
1041- "crate::Reg<{}::{}_SPEC>" ,
1042- & name. to_sanitized_snake_case( ) ,
1043- & name. to_sanitized_constant_case( ) ,
1044- )
1045- }
1046-
1047- fn name_to_wrapped_ty ( name : & str ) -> Result < syn:: Type > {
1048- let ident = name_to_wrapped_ty_str ( name) ;
1049- parse_str :: < syn:: TypePath > ( & ident)
1050- . map ( syn:: Type :: Path )
1051- . map_err ( anyhow:: Error :: from)
1052- . with_context ( || format ! ( "Determining syn::TypePath from ident \" {ident}\" failed" ) )
1053- }
0 commit comments