@@ -8,9 +8,12 @@ use crate::svd::{
8
8
use log:: { debug, trace, warn} ;
9
9
use proc_macro2:: { Ident , Punct , Spacing , Span , TokenStream } ;
10
10
use quote:: { quote, ToTokens } ;
11
- use syn:: { parse_str , Token } ;
11
+ use syn:: { punctuated :: Punctuated , Token } ;
12
12
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
+ } ;
14
17
use anyhow:: { anyhow, bail, Context , Result } ;
15
18
16
19
use crate :: generate:: register;
@@ -686,7 +689,7 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
686
689
let span = Span :: call_site ( ) ;
687
690
let mut accessors = TokenStream :: new ( ) ;
688
691
let nb_name = util:: replace_suffix ( & info. name , "" ) ;
689
- let ty = name_to_ty ( & nb_name) ? ;
692
+ let ty = name_to_ty ( & nb_name) ;
690
693
let nb_name_cs = nb_name. to_snake_case_ident ( span) ;
691
694
for ( i, idx) in array_info. indexes ( ) . enumerate ( ) {
692
695
let idx_name =
@@ -717,14 +720,13 @@ fn expand_cluster(cluster: &Cluster, config: &Config) -> Result<Vec<RegisterBloc
717
720
} else if sequential_indexes_from0 && config. const_generic {
718
721
// Include a ZST ArrayProxy giving indexed access to the
719
722
// elements.
720
- cluster_expanded. push ( array_proxy ( info, array_info) ? ) ;
723
+ cluster_expanded. push ( array_proxy ( info, array_info) ) ;
721
724
} else {
722
725
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) ) ;
724
727
725
728
for ( field_num, idx) in array_info. indexes ( ) . enumerate ( ) {
726
729
let nb_name = util:: replace_suffix ( & info. name , & idx) ;
727
-
728
730
let syn_field =
729
731
new_syn_field ( nb_name. to_snake_case_ident ( Span :: call_site ( ) ) , ty. clone ( ) ) ;
730
732
@@ -790,7 +792,7 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
790
792
let span = Span :: call_site ( ) ;
791
793
let mut accessors = TokenStream :: new ( ) ;
792
794
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) ;
794
796
let nb_name_cs = nb_name. to_snake_case_ident ( span) ;
795
797
let info_name = info. fullname ( config. ignore_groups ) ;
796
798
for ( i, idx) in array_info. indexes ( ) . enumerate ( ) {
@@ -822,11 +824,10 @@ fn expand_register(register: &Register, config: &Config) -> Result<Vec<RegisterB
822
824
} else {
823
825
let info_name = info. fullname ( config. ignore_groups ) ;
824
826
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) ;
826
828
827
829
for ( field_num, idx) in array_info. indexes ( ) . enumerate ( ) {
828
830
let nb_name = util:: replace_suffix ( & info_name, & idx) ;
829
-
830
831
let syn_field =
831
832
new_syn_field ( nb_name. to_snake_case_ident ( Span :: call_site ( ) ) , ty. clone ( ) ) ;
832
833
@@ -863,8 +864,7 @@ fn render_ercs(
863
864
if let Some ( dpath) = dpath {
864
865
cpath = derive_cluster ( c, & dpath, path, index) ?;
865
866
}
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) ?) ;
868
868
}
869
869
870
870
// Generate definition for each of the registers.
@@ -876,10 +876,9 @@ fn render_ercs(
876
876
rpath = derive_register ( reg, & dpath, path, index) ?;
877
877
}
878
878
let reg_name = & reg. name ;
879
- let rpath = rpath. unwrap_or_else ( || path. new_register ( reg_name) ) ;
880
879
881
880
let rendered_reg =
882
- register:: render ( reg, & rpath, index, config) . with_context ( || {
881
+ register:: render ( reg, path , rpath, index, config) . with_context ( || {
883
882
let descrip = reg. description . as_deref ( ) . unwrap_or ( "No description" ) ;
884
883
format ! (
885
884
"Error rendering register\n Name: {reg_name}\n Description: {descrip}"
@@ -896,23 +895,57 @@ fn render_ercs(
896
895
fn cluster_block (
897
896
c : & mut Cluster ,
898
897
path : & BlockPath ,
898
+ dpath : Option < BlockPath > ,
899
899
index : & Index ,
900
900
config : & Config ,
901
901
) -> 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 ) ) ) ;
905
904
let mod_name = util:: replace_suffix ( & c. name , "" ) ;
906
905
907
- let reg_block = register_or_cluster_block ( & c. children , Some ( & mod_name) , config) ?;
908
-
909
906
// 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) ;
912
912
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) ) ) ;
914
931
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
+ } ;
916
949
917
950
Ok ( quote ! {
918
951
#[ doc = #description]
@@ -921,8 +954,6 @@ fn cluster_block(
921
954
///Cluster
922
955
#[ doc = #description]
923
956
pub mod #name_snake_case {
924
- #reg_block
925
-
926
957
#mod_items
927
958
}
928
959
} )
@@ -933,15 +964,13 @@ fn register_to_syn_field(register: &Register, ignore_group: bool) -> Result<syn:
933
964
Ok ( match register {
934
965
Register :: Single ( info) => {
935
966
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) ;
938
968
new_syn_field ( info_name. to_snake_case_ident ( Span :: call_site ( ) ) , ty)
939
969
}
940
970
Register :: Array ( info, array_info) => {
941
971
let info_name = info. fullname ( ignore_group) ;
942
972
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) ;
945
974
let array_ty = new_syn_array ( ty, array_info. dim ) ;
946
975
947
976
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:
950
979
}
951
980
952
981
/// 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 {
957
983
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) ,
971
990
description : info. description . as_ref ( ) . unwrap_or ( & info. name ) . into ( ) ,
972
991
offset : info. address_offset ,
973
992
size : 0 ,
974
993
accessors : None ,
975
- } )
994
+ }
976
995
}
977
996
978
997
/// Convert a parsed `Cluster` into its `Field` equivalent
979
998
fn cluster_to_syn_field ( cluster : & Cluster ) -> Result < syn:: Field , syn:: Error > {
980
999
Ok ( match cluster {
981
1000
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 ) ) ;
984
1002
new_syn_field ( info. name . to_snake_case_ident ( Span :: call_site ( ) ) , ty)
985
1003
}
986
1004
Cluster :: Array ( info, array_info) => {
987
1005
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) ) ;
989
1007
let array_ty = new_syn_array ( ty, array_info. dim ) ;
990
1008
991
1009
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 {
1015
1033
len : new_syn_u32 ( len, span) ,
1016
1034
} )
1017
1035
}
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