From f9b0e252827cbadd0786a22d532441118d00f41f Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sat, 24 Feb 2024 10:20:06 +0300 Subject: [PATCH 1/2] reexport enum --- CHANGELOG.md | 1 + src/generate/register.rs | 125 ++++++++++++++++++--------------------- 2 files changed, 59 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 876c495c..134291e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/). - Add `base-address-shift` config flag - Use `PascalCase` for type idents, fix case changing bugs, add `--ident-format` (`-f`) option flag - Add `enum_read_name` for `read-only` enums, `RWEnum` helper +- Reexport enums inside register again ## [v0.31.5] - 2024-01-04 diff --git a/src/generate/register.rs b/src/generate/register.rs index bd380a25..c006a1ef 100644 --- a/src/generate/register.rs +++ b/src/generate/register.rs @@ -620,8 +620,9 @@ pub fn fields( // Hack for #625 let mut enum_derives = HashSet::new(); + let mut read_enum_derives = HashSet::new(); + let mut write_enum_derives = HashSet::new(); let mut reader_derives = HashSet::new(); - let mut writer_enum_derives = HashSet::new(); let mut writer_derives = HashSet::new(); // TODO enumeratedValues @@ -737,32 +738,31 @@ pub fn fields( // If this field can be read, generate read proxy structure and value structure. if can_read { - // get the type of value structure. It can be generated from either name field - // in enumeratedValues if it's an enumeration, or from field name directly if it's not. + // collect information on items in enumeration to generate it later. + let mut enum_items = TokenStream::new(); + + // if this is an enumeratedValues not derived from base, generate the enum structure + // and implement functions for each value in enumeration. let value_read_ty = if let Some(ev) = rwenum.read_enum() { - let fmt = if rwenum.different_enums() { - "enum_read_name" + let derives; + let fmt; + if rwenum.different_enums() { + derives = &mut read_enum_derives; + fmt = "enum_read_name"; } else { - "enum_name" + derives = &mut enum_derives; + fmt = "enum_name"; }; - ident( + // get the type of value structure. It can be generated from either name field + // in enumeratedValues if it's an enumeration, or from field name directly if it's not. + let value_read_ty = ident( ev.values().name.as_deref().unwrap_or(&name), config, fmt, span, - ) - } else { - // raw_field_value_read_ty - fty.clone() - }; - - // collect information on items in enumeration to generate it later. - let mut enum_items = TokenStream::new(); + ); - if let Some(ev) = rwenum.read_enum() { match ev { - // if this is an enumeratedValues not derived from base, generate the enum structure - // and implement functions for each value in enumeration. EV::New(evs) => { // parse enum variants from enumeratedValues svd record let mut variants = Variant::from_enumerated_values(evs, config)?; @@ -909,24 +909,22 @@ pub fn fields( } } EV::Derived(_, base) => { - // only pub use enum when derived from another register. - // If field is in the same register it emits - // pub use enum from same module which is not expected - if base.register() != fpath.register() { - // use the same enum structure name - if !enum_derives.contains(&value_read_ty) { - let base_path = - base_syn_path(base, &fpath, &value_read_ty, config)?; - mod_items.extend(quote! { - #[doc = #description] - pub use #base_path as #value_read_ty; - }); - enum_derives.insert(value_read_ty.clone()); - } + let base_ident = ident(&base.name, config, fmt, span); + if !derives.contains(&value_read_ty) { + let base_path = base_syn_path(base, &fpath, &base_ident, config)?; + mod_items.extend(quote! { + #[doc = #description] + pub use #base_path as #value_read_ty; + }); } } } - } + derives.insert(value_read_ty.clone()); + value_read_ty + } else { + // raw_field_value_read_ty + fty.clone() + }; // get a brief description for this field // the suffix string from field name is removed in brief description. @@ -1083,29 +1081,28 @@ pub fn fields( // If this field can be written, generate write proxy. Generate write value if it differs from // the read value, or else we reuse read value. if can_write { + let mut proxy_items = TokenStream::new(); + let mut unsafety = unsafety(f.write_constraint.as_ref(), width); + + // if we writes to enumeratedValues, generate its structure if it differs from read structure. let value_write_ty = if let Some(ev) = rwenum.write_enum() { - let fmt = if rwenum.different_enums() { - "enum_write_name" + let derives; + let fmt; + if rwenum.different_enums() { + derives = &mut write_enum_derives; + fmt = "enum_write_name"; } else { - "enum_name" + derives = &mut enum_derives; + fmt = "enum_name"; }; - ident( + let value_write_ty = ident( ev.values().name.as_deref().unwrap_or(&name), config, fmt, span, - ) - } else { - // raw_field_value_write_ty - fty.clone() - }; + ); - let mut proxy_items = TokenStream::new(); - let mut unsafety = unsafety(f.write_constraint.as_ref(), width); - - if let Some(ev) = rwenum.write_enum() { match ev { - // if we writes to enumeratedValues, generate its structure if it differs from read structure. EV::New(evs) => { // parse variants from enumeratedValues svd record let mut variants = Variant::from_enumerated_values(evs, config)?; @@ -1167,24 +1164,23 @@ pub fn fields( } } EV::Derived(_, base) => { - // If field is in the same register it emits pub use structure from same module. - if base.register() != fpath.register() { - // use the same enum structure name - if rwenum.generate_write_enum() - && !writer_enum_derives.contains(&value_write_ty) - { - let base_path = - base_syn_path(base, &fpath, &value_write_ty, config)?; - mod_items.extend(quote! { - #[doc = #description] - pub use #base_path as #value_write_ty; - }); - writer_enum_derives.insert(value_write_ty.clone()); - } + let base_ident = ident(&base.name, config, fmt, span); + + if rwenum.generate_write_enum() && !derives.contains(&value_write_ty) { + let base_path = base_syn_path(base, &fpath, &base_ident, config)?; + mod_items.extend(quote! { + #[doc = #description] + pub use #base_path as #value_write_ty; + }); } } } - } + derives.insert(value_write_ty.clone()); + value_write_ty + } else { + // raw_field_value_write_ty + fty.clone() + }; let mwv = f.modified_write_values.or(rmwv).unwrap_or_default(); @@ -1238,11 +1234,6 @@ pub fn fields( }); } Some(EV::Derived(_, base)) => { - // if base.register == None, derive write from the same module. This is allowed because both - // the generated and source write proxy are in the same module. - // we never reuse writer for writer in different module does not have the same _SPEC strcuture, - // thus we cannot write to current register using re-exported write proxy. - // generate pub use field_1 writer as field_2 writer let base_field = util::replace_suffix(&base.field.name, ""); let base_w = ident(&base_field, config, "field_writer", span); From 4813f560822f4693cd9a956aa60066ecad254a8f Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sun, 25 Feb 2024 14:34:34 +0300 Subject: [PATCH 2/2] always use field names as base for enum names --- src/config.rs | 1 + src/generate/register.rs | 35 ++++++++++++++++++++++++++++++----- src/main.rs | 8 ++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 81e0164b..e53a2e33 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,6 +33,7 @@ pub struct Config { pub reexport_interrupt: bool, pub ident_formats: IdentFormats, pub ident_formats_theme: Option, + pub field_names_for_enums: bool, pub base_address_shift: u64, } diff --git a/src/generate/register.rs b/src/generate/register.rs index c006a1ef..bfbfde92 100644 --- a/src/generate/register.rs +++ b/src/generate/register.rs @@ -756,7 +756,11 @@ pub fn fields( // get the type of value structure. It can be generated from either name field // in enumeratedValues if it's an enumeration, or from field name directly if it's not. let value_read_ty = ident( - ev.values().name.as_deref().unwrap_or(&name), + if config.field_names_for_enums { + &name + } else { + ev.values().name.as_deref().unwrap_or(&name) + }, config, fmt, span, @@ -909,7 +913,16 @@ pub fn fields( } } EV::Derived(_, base) => { - let base_ident = ident(&base.name, config, fmt, span); + let base_ident = if config.field_names_for_enums { + ident( + &util::replace_suffix(&base.field().name, ""), + config, + fmt, + span, + ) + } else { + ident(&base.name, config, fmt, span) + }; if !derives.contains(&value_read_ty) { let base_path = base_syn_path(base, &fpath, &base_ident, config)?; mod_items.extend(quote! { @@ -1096,7 +1109,11 @@ pub fn fields( fmt = "enum_name"; }; let value_write_ty = ident( - ev.values().name.as_deref().unwrap_or(&name), + if config.field_names_for_enums { + &name + } else { + ev.values().name.as_deref().unwrap_or(&name) + }, config, fmt, span, @@ -1164,8 +1181,16 @@ pub fn fields( } } EV::Derived(_, base) => { - let base_ident = ident(&base.name, config, fmt, span); - + let base_ident = if config.field_names_for_enums { + ident( + &util::replace_suffix(&base.field().name, ""), + config, + fmt, + span, + ) + } else { + ident(&base.name, config, fmt, span) + }; if rwenum.generate_write_enum() && !derives.contains(&value_write_ty) { let base_path = base_syn_path(base, &fpath, &base_ident, config)?; mod_items.extend(quote! { diff --git a/src/main.rs b/src/main.rs index 9fd55640..be54cbb3 100755 --- a/src/main.rs +++ b/src/main.rs @@ -172,10 +172,18 @@ Allowed cases are `unchanged` (''), `pascal` ('p'), `constant` ('c') and `snake` .arg( Arg::new("ident_formats_theme") .long("ident-formats-theme") + .alias("ident_formats_theme") .help("A set of `ident_format` settings. `new` or `legacy`") .action(ArgAction::Set) .value_name("THEME"), ) + .arg( + Arg::new("field_names_for_enums") + .long("field-names-for-enums") + .alias("field_names_for_enums") + .action(ArgAction::SetTrue) + .help("Use field name for enumerations even when enumeratedValues has a name"), + ) .arg( Arg::new("max_cluster_size") .long("max-cluster-size")