From 56de2edf24527230599fd054c2a717b418e128b1 Mon Sep 17 00:00:00 2001 From: schilkp Date: Tue, 7 May 2024 10:18:09 +0200 Subject: [PATCH] rust-rewrite: Removed "split-into-modules" option for rs-structs output. --- .../src/builtin/rs/structs/enums.rs | 4 +- .../src/builtin/rs/structs/layouts.rs | 60 ++++----- .../src/builtin/rs/structs/mod.rs | 24 +--- .../src/builtin/rs/structs/registers.rs | 118 +++++------------- .../tests/generator_rs_structs/mod.rs | 9 -- .../generator_rs_structs/test_proj/Cargo.toml | 2 +- .../generator_rs_structs/test_proj/src/lib.rs | 12 -- 7 files changed, 59 insertions(+), 170 deletions(-) diff --git a/reginald_codegen/src/builtin/rs/structs/enums.rs b/reginald_codegen/src/builtin/rs/structs/enums.rs index 6a864d8..c32bec8 100644 --- a/reginald_codegen/src/builtin/rs/structs/enums.rs +++ b/reginald_codegen/src/builtin/rs/structs/enums.rs @@ -28,11 +28,11 @@ pub(super) fn generate_enum(out: &mut dyn Write, inp: &Input, e: &Enum) -> Resul } /// Generate conversion impls. -pub(super) fn generate_enum_impls(out: &mut dyn Write, inp: &Input, e: &Enum, in_module: bool) -> Result<(), Error> { +pub(super) fn generate_enum_impls(out: &mut dyn Write, inp: &Input, e: &Enum) -> Result<(), Error> { // Smallest uint type that can be used to represent the enum's content: let enum_name = rs_pascalcase(&e.name); let width_bytes = e.min_width_bytes(); - let trait_prefix = trait_prefix(inp, in_module); + let trait_prefix = trait_prefix(inp); match enum_impl(e) { FromBytesImpl::FromBytes => { diff --git a/reginald_codegen/src/builtin/rs/structs/layouts.rs b/reginald_codegen/src/builtin/rs/structs/layouts.rs index c744c00..8d05a3b 100644 --- a/reginald_codegen/src/builtin/rs/structs/layouts.rs +++ b/reginald_codegen/src/builtin/rs/structs/layouts.rs @@ -18,11 +18,11 @@ use reginald_utils::remove_wrapping_parens; use super::{rs_pascalcase, rs_snakecase}; // Generate content for a layout struct -pub fn generate_layout(out: &mut dyn Write, inp: &Input, layout: &Layout, in_module: bool) -> Result<(), Error> { +pub fn generate_layout(out: &mut dyn Write, inp: &Input, layout: &Layout) -> Result<(), Error> { let mut out = HeaderWriter::new(out); // Layout struct: - generate_layout_struct(&mut out, inp, layout, None, in_module)?; + generate_layout_struct(&mut out, inp, layout, None)?; out.push_section_with_header(&["\n", "// Layout-specific enums and sub-layouts:", "\n"]); @@ -31,20 +31,20 @@ pub fn generate_layout(out: &mut dyn Write, inp: &Input, layout: &Layout, in_mod } for local_layout in layout.nested_local_layouts() { - generate_layout_struct(&mut out, inp, local_layout, None, in_module)?; + generate_layout_struct(&mut out, inp, local_layout, None)?; } out.pop_section(); out.push_section_with_header(&["\n", "// Conversion functions:", "\n"]); - generate_layout_impls(&mut out, inp, layout, in_module)?; + generate_layout_impls(&mut out, inp, layout)?; for e in layout.nested_local_enums() { - enums::generate_enum_impls(&mut out, inp, e, in_module)?; + enums::generate_enum_impls(&mut out, inp, e)?; } for layout in layout.nested_local_layouts() { - generate_layout_impls(&mut out, inp, layout, in_module)?; + generate_layout_impls(&mut out, inp, layout)?; } out.pop_section(); @@ -59,7 +59,6 @@ pub fn generate_layout_struct( inp: &Input, layout: &Layout, for_register: Option<&Register>, - in_module: bool, ) -> Result<(), Error> { // Struct doc comment: writeln!(out)?; @@ -93,7 +92,7 @@ pub fn generate_layout_struct( writeln!(out, "pub struct {} {{", rs_pascalcase(&layout.name))?; for field in layout.fields_with_content() { - let field_type = register_layout_member_type(inp, field, in_module)?; + let field_type = register_layout_member_type(field)?; let field_name = rs_snakecase(&field.name); generate_doc_comment(out, &field.docs, " ")?; writeln!(out, " pub {field_name}: {field_type},")?; @@ -105,34 +104,29 @@ pub fn generate_layout_struct( } /// Type of a field inside a register struct. -pub fn register_layout_member_type(inp: &Input, field: &LayoutField, in_module: bool) -> Result { +pub fn register_layout_member_type(field: &LayoutField) -> Result { match &field.accepts { FieldType::UInt => rs_fitting_unsigned_type(mask_width(field.mask)), FieldType::Bool => Ok("bool".to_string()), - FieldType::Enum(e) => Ok(prefix_with_super(inp, &rs_pascalcase(&e.name), e.is_local, in_module)), - FieldType::Layout(l) => Ok(prefix_with_super(inp, &rs_pascalcase(&l.name), l.is_local, in_module)), + FieldType::Enum(e) => Ok(rs_pascalcase(&e.name)), + FieldType::Layout(l) => Ok(rs_pascalcase(&l.name)), FieldType::Fixed(_) => panic!("Fixed layout field has no type"), } } -pub fn generate_layout_impls(out: &mut dyn Write, inp: &Input, layout: &Layout, in_module: bool) -> Result<(), Error> { - generate_layout_impl_to_bytes(inp, out, layout, in_module)?; - generate_layout_impl_from_bytes(inp, out, layout, in_module)?; +pub fn generate_layout_impls(out: &mut dyn Write, inp: &Input, layout: &Layout) -> Result<(), Error> { + generate_layout_impl_to_bytes(inp, out, layout)?; + generate_layout_impl_from_bytes(inp, out, layout)?; if inp.opts.generate_uint_conversion { - generate_layout_impl_uint_conv(inp, out, layout, in_module)?; + generate_layout_impl_uint_conv(inp, out, layout)?; } Ok(()) } -pub fn generate_layout_impl_to_bytes( - inp: &Input, - out: &mut dyn Write, - layout: &Layout, - in_module: bool, -) -> Result<(), Error> { +pub fn generate_layout_impl_to_bytes(inp: &Input, out: &mut dyn Write, layout: &Layout) -> Result<(), Error> { let struct_name = rs_pascalcase(&layout.name); let width_bytes = layout.width_bytes(); - let trait_prefix = trait_prefix(inp, in_module); + let trait_prefix = trait_prefix(inp); let mut out = IndentWriter::new(out, " "); @@ -285,15 +279,10 @@ pub fn generate_layout_impl_to_bytes( Ok(()) } -fn generate_layout_impl_from_bytes( - inp: &Input, - out: &mut dyn Write, - layout: &Layout, - in_module: bool, -) -> Result<(), Error> { +fn generate_layout_impl_from_bytes(inp: &Input, out: &mut dyn Write, layout: &Layout) -> Result<(), Error> { let struct_name = rs_pascalcase(&layout.name); let width_bytes = layout.width_bytes(); - let trait_prefix = trait_prefix(inp, in_module); + let trait_prefix = trait_prefix(inp); let mut out = IndentWriter::new(out, " "); @@ -411,7 +400,7 @@ fn generate_layout_impl_from_bytes( writeln!(out, " {field_name}: {numeric_value} != 0,")?; } FieldType::Enum(e) => { - let enum_name = prefix_with_super(inp, &rs_pascalcase(&e.name), e.is_local, in_module); + let enum_name = rs_pascalcase(&e.name); let array_name = rs_snakecase(&field.name); match enum_impl(e) { @@ -431,7 +420,7 @@ fn generate_layout_impl_from_bytes( } } FieldType::Layout(l) => { - let layout_name = prefix_with_super(inp, &rs_pascalcase(&l.name), l.is_local, in_module); + let layout_name = rs_pascalcase(&l.name); let array_name = rs_snakecase(&field.name); if l.can_always_unpack() { writeln!(out, " {field_name}: {layout_name}::from_le_bytes(&{array_name}),")?; @@ -458,14 +447,9 @@ fn generate_layout_impl_from_bytes( Ok(()) } -fn generate_layout_impl_uint_conv( - inp: &Input, - out: &mut dyn Write, - layout: &Layout, - in_module: bool, -) -> Result<(), Error> { +fn generate_layout_impl_uint_conv(inp: &Input, out: &mut dyn Write, layout: &Layout) -> Result<(), Error> { let struct_name = rs_pascalcase(&layout.name); - let trait_prefix = trait_prefix(inp, in_module); + let trait_prefix = trait_prefix(inp); let (uint_type, uint_width_bytes) = match layout.width_bytes() { 1 => ("u8", 1), diff --git a/reginald_codegen/src/builtin/rs/structs/mod.rs b/reginald_codegen/src/builtin/rs/structs/mod.rs index 84af8fa..46183be 100644 --- a/reginald_codegen/src/builtin/rs/structs/mod.rs +++ b/reginald_codegen/src/builtin/rs/structs/mod.rs @@ -33,13 +33,6 @@ pub struct GeneratorOpts { #[cfg_attr(feature = "cli", arg(verbatim_doc_comment))] pub address_type: Option, - /// Split registers and register blocks into seperate modules. - #[cfg_attr(feature = "cli", arg(long))] - #[cfg_attr(feature = "cli", arg(action = clap::ArgAction::Set))] - #[cfg_attr(feature = "cli", arg(default_value = "true"))] - #[cfg_attr(feature = "cli", arg(verbatim_doc_comment))] - pub split_into_modules: bool, - /// Trait to derive on all register structs. /// /// May be given multiple times. @@ -138,7 +131,7 @@ pub fn generate(out: &mut dyn Write, map: &RegisterMap, opts: &GeneratorOpts) -> out.push_section_with_header(&["\n", &rs_header_comment("Shared Enums"), "\n"]); for shared_enum in inp.map.shared_enums() { enums::generate_enum(&mut out, &inp, shared_enum)?; - enums::generate_enum_impls(&mut out, &inp, shared_enum, false)?; + enums::generate_enum_impls(&mut out, &inp, shared_enum)?; } out.pop_section(); @@ -147,7 +140,7 @@ pub fn generate(out: &mut dyn Write, map: &RegisterMap, opts: &GeneratorOpts) -> for layout in inp.map.shared_layouts() { writeln!(&mut out)?; writeln!(&mut out, "{}", &rs_header_comment(&format!("`{}` Shared Layout", layout.name)))?; - layouts::generate_layout(&mut out, &inp, layout, false)?; + layouts::generate_layout(&mut out, &inp, layout)?; } // ===== Individual Registers: ===== @@ -235,25 +228,14 @@ fn generate_traits(out: &mut dyn Write) -> Result<(), Error> { /// Decide trait prefix. If an external override is given, use that. /// Otherwise, use the local definition (Which may be in the parent /// module) -fn trait_prefix(inp: &Input, in_module: bool) -> String { +fn trait_prefix(inp: &Input) -> String { if let Some(overide) = &inp.opts.external_traits { String::from(overide) - } else if in_module { - String::from("super::") } else { String::new() } } -/// Prefix a given identifier with `super::` if required. -fn prefix_with_super(inp: &Input, s: &str, is_local: bool, in_module: bool) -> String { - if inp.opts.split_into_modules && !is_local && in_module { - format!("super::{s}") - } else { - String::from(s) - } -} - #[allow(clippy::enum_variant_names)] enum FromBytesImpl { FromBytes, diff --git a/reginald_codegen/src/builtin/rs/structs/registers.rs b/reginald_codegen/src/builtin/rs/structs/registers.rs index 83df588..da5b6de 100644 --- a/reginald_codegen/src/builtin/rs/structs/registers.rs +++ b/reginald_codegen/src/builtin/rs/structs/registers.rs @@ -7,57 +7,32 @@ use crate::{builtin::rs::array_literal, error::Error, utils::Endianess, writer:: use super::rs_pascalcase; pub fn generate_register(out: &mut dyn Write, inp: &Input, register: &Register) -> Result<(), Error> { - let mut out = IndentWriter::new(out, " "); - - writeln!(&mut out)?; - - // If seperate modules are enabled, generate module doc comment - // and open module: - if inp.opts.split_into_modules { - writeln!(out, "/// `{}` Register", register.name)?; - generate_register_header(&mut out, register, "///")?; - writeln!(&mut out, "pub mod {} {{", rs_snakecase(®ister.name))?; - out.push_indent(); - } else { - rs_generate_header_comment(&mut out, &format!("`{}` Register", register.name))?; - generate_register_header(&mut out, register, "//")?; - } + writeln!(out)?; - // Track if we are currently in a sub-module - let in_module = inp.opts.split_into_modules; + rs_generate_header_comment(out, &format!("`{}` Register", register.name))?; + generate_register_header(out, register, "//")?; if register.layout.is_local { // If the layout is local to this register, generate it and associate all properties to it: // Layout struct: - generate_register_struct(&mut out, inp, register, in_module)?; + generate_register_struct(out, inp, register)?; } else { // Otherwise generate a newtype to contain the register properties: - generate_register_newtype(&mut out, inp, register, in_module)?; - generate_register_impl(&mut out, inp, register, true, in_module)?; - } - - // Close module if opened. - if inp.opts.split_into_modules { - out.pop_indent(); - writeln!(&mut out, "}}")?; + generate_register_newtype(out, inp, register)?; + generate_register_impl(out, inp, register, true)?; } Ok(()) } -pub fn generate_register_struct( - out: &mut dyn Write, - inp: &Input, - register: &Register, - in_module: bool, -) -> Result<(), Error> { +pub fn generate_register_struct(out: &mut dyn Write, inp: &Input, register: &Register) -> Result<(), Error> { let mut out = HeaderWriter::new(out); // If the layout is local to this register, generate it and associate all properties to it: // Layout struct: - layouts::generate_layout_struct(&mut out, inp, ®ister.layout, Some(register), in_module)?; + layouts::generate_layout_struct(&mut out, inp, ®ister.layout, Some(register))?; - generate_register_impl(&mut out, inp, register, false, in_module)?; + generate_register_impl(&mut out, inp, register, false)?; out.push_section_with_header(&["\n", "// Register-specific enums:", "\n"]); for e in register.layout.nested_local_enums() { @@ -67,29 +42,24 @@ pub fn generate_register_struct( out.push_section_with_header(&["\n", "// Register-specific sub-layouts:", "\n"]); for local_layout in register.layout.nested_local_layouts() { - layouts::generate_layout_struct(&mut out, inp, local_layout, None, in_module)?; + layouts::generate_layout_struct(&mut out, inp, local_layout, None)?; } out.pop_section(); out.push_section_with_header(&["\n", "// Conversion functions:", "\n"]); - layouts::generate_layout_impls(&mut out, inp, ®ister.layout, in_module)?; + layouts::generate_layout_impls(&mut out, inp, ®ister.layout)?; for e in register.layout.nested_local_enums() { - enums::generate_enum_impls(&mut out, inp, e, in_module)?; + enums::generate_enum_impls(&mut out, inp, e)?; } for layout in register.layout.nested_local_layouts() { - layouts::generate_layout_impls(&mut out, inp, layout, in_module)?; + layouts::generate_layout_impls(&mut out, inp, layout)?; } out.pop_section(); Ok(()) } -pub fn generate_register_newtype( - out: &mut dyn Write, - inp: &Input, - register: &Register, - in_module: bool, -) -> Result<(), Error> { +pub fn generate_register_newtype(out: &mut dyn Write, inp: &Input, register: &Register) -> Result<(), Error> { // Struct doc comment: writeln!(out)?; writeln!(out, "/// `{}` Register", register.name)?; @@ -108,8 +78,7 @@ pub fn generate_register_newtype( writeln!(out, "#[derive({derives})]")?; } - let layout_name = - prefix_with_super(inp, &rs_pascalcase(®ister.layout.name), register.layout.is_local, in_module); + let layout_name = rs_pascalcase(®ister.layout.name); // Struct proper: writeln!(out, "pub struct {} ({layout_name});", rs_pascalcase(®ister.name))?; @@ -136,13 +105,12 @@ pub fn generate_register_impl( inp: &Input, register: &Register, is_newtype: bool, - in_module: bool, ) -> Result<(), Error> { let reg_name = ®ister.name; let struct_name = rs_pascalcase(reg_name); let byte_width = register.layout.width_bytes(); let address_type = &inp.address_type; - let trait_prefix = trait_prefix(inp, in_module); + let trait_prefix = trait_prefix(inp); // ==== Properties ====: writeln!(out)?; @@ -171,7 +139,7 @@ pub fn generate_register_impl( let mut init_str = String::new(); let mut init = IndentWriter::new(&mut init_str, " "); - if generate_reset_val(inp, &mut init, ®ister.layout, *reset_val, is_newtype, in_module, true).is_err() { + if generate_reset_val(&mut init, ®ister.layout, *reset_val, is_newtype, true).is_err() { return Ok(()); }; drop(init); @@ -195,54 +163,36 @@ pub fn generate_register_impl( } pub fn generate_register_block(out: &mut dyn Write, inp: &Input, block: &RegisterBlock) -> Result<(), Error> { - let mut out = IndentWriter::new(out, " "); - - writeln!(&mut out)?; + writeln!(out)?; // If seperate modules are enabled, generate module doc comment // and open module: - if inp.opts.split_into_modules { - writeln!(out, "/// `{}` Register Block", block.name)?; - generate_register_block_header(&mut out, block, "///")?; - writeln!(&mut out, "pub mod {} {{", rs_snakecase(&block.name))?; - out.push_indent(); - } else { - rs_generate_header_comment(&mut out, &format!("`{}` Register Block", block.name))?; - generate_register_block_header(&mut out, block, "//")?; - } - - // Track if we are currently in a sub-module - let in_module = inp.opts.split_into_modules; + rs_generate_header_comment(out, &format!("`{}` Register Block", block.name))?; + generate_register_block_header(out, block, "//")?; // Shared register block properties - generate_register_block_properties(&mut out, inp, block)?; + generate_register_block_properties(out, inp, block)?; // Members: for member in block.members.values() { - writeln!(&mut out)?; - rs_generate_header_comment(&mut out, &format!("`{}` Register Block Member `{}`", &block.name, &member.name))?; + writeln!(out)?; + rs_generate_header_comment(out, &format!("`{}` Register Block Member `{}`", &block.name, &member.name))?; if member.layout.is_local { - layouts::generate_layout(&mut out, inp, &member.layout, in_module)?; + layouts::generate_layout(out, inp, &member.layout)?; } if !block.instances.is_empty() { - writeln!(&mut out)?; - writeln!(&mut out, "// Instances:")?; + writeln!(out)?; + writeln!(out, "// Instances:")?; for block_instance in block.instances.values() { let member_instance = &block_instance.registers[&member.name]; - generate_register_newtype(&mut out, inp, member_instance, in_module)?; - generate_register_impl(&mut out, inp, member_instance, true, in_module)?; + generate_register_newtype(out, inp, member_instance)?; + generate_register_impl(out, inp, member_instance, true)?; } } } - // Close module if opened. - if inp.opts.split_into_modules { - out.pop_indent(); - writeln!(&mut out, "}}")?; - } - Ok(()) } @@ -325,18 +275,16 @@ pub fn generate_register_block_properties( } fn generate_reset_val( - inp: &Input, out: &mut IndentWriter, layout: &Layout, val: TypeValue, is_newtype: bool, - in_module: bool, is_top: bool, ) -> Result<(), Error> { if !is_newtype && is_top { writeln!(out, "Self {{")?; } else { - writeln!(out, "{} {{", prefix_with_super(inp, &rs_pascalcase(&layout.name), layout.is_local, in_module))?; + writeln!(out, "{} {{", rs_pascalcase(&layout.name))?; } out.push_indent(); @@ -347,7 +295,7 @@ fn generate_reset_val( write!(out, "{}: ", rs_snakecase(&field.name))?; if let FieldType::Layout(layout) = &field.accepts { - generate_reset_val(inp, out, layout, field_val, false, in_module, false)?; + generate_reset_val(out, layout, field_val, false, false)?; } else { match field.decode_value(field_val)? { crate::regmap::DecodedField::UInt(val) => { @@ -361,11 +309,7 @@ fn generate_reset_val( unreachable!() }; - // If this is a newtyp struct, the enum is defined with the layout, not with this - // newtype. - let is_local = !is_newtype && e.is_local; - - let enum_name = prefix_with_super(inp, &rs_pascalcase(&e.name), is_local, in_module); + let enum_name = rs_pascalcase(&e.name); write!(out, "{}::{}", enum_name, rs_pascalcase(&entry))?; } crate::regmap::DecodedField::Fixed { .. } => unreachable!(), diff --git a/reginald_codegen/tests/generator_rs_structs/mod.rs b/reginald_codegen/tests/generator_rs_structs/mod.rs index 8cfbbc3..0026c11 100644 --- a/reginald_codegen/tests/generator_rs_structs/mod.rs +++ b/reginald_codegen/tests/generator_rs_structs/mod.rs @@ -26,7 +26,6 @@ fn run_reginald(output_name: &str, opts: GeneratorOpts) { const GENERATOR_OPTS_DEFAULT: GeneratorOpts = GeneratorOpts { address_type: None, - split_into_modules: true, struct_derive: vec![], raw_enum_derive: vec![], add_use: vec![], @@ -68,14 +67,6 @@ fn generator_rs_structs() { }, ); - run_reginald( - "out_flat.rs", - GeneratorOpts { - split_into_modules: false, - ..GENERATOR_OPTS_DEFAULT - }, - ); - let output = Command::new("cargo") .args(&["test".to_string()]) .current_dir(&test_proj) diff --git a/reginald_codegen/tests/generator_rs_structs/test_proj/Cargo.toml b/reginald_codegen/tests/generator_rs_structs/test_proj/Cargo.toml index c2152a7..cc8f8ba 100644 --- a/reginald_codegen/tests/generator_rs_structs/test_proj/Cargo.toml +++ b/reginald_codegen/tests/generator_rs_structs/test_proj/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rs_struct_no_deps_test" +name = "rs_structs_test" version = "0.1.0" edition = "2021" diff --git a/reginald_codegen/tests/generator_rs_structs/test_proj/src/lib.rs b/reginald_codegen/tests/generator_rs_structs/test_proj/src/lib.rs index 735c068..b4739ba 100644 --- a/reginald_codegen/tests/generator_rs_structs/test_proj/src/lib.rs +++ b/reginald_codegen/tests/generator_rs_structs/test_proj/src/lib.rs @@ -11,14 +11,12 @@ pub mod out; // Unused. Included to ensure they compile: pub mod out_crate_traits; pub mod out_ext_traits; -pub mod out_flat; #[cfg(test)] mod tests { #[test] fn test_basic_reg1() { - use crate::out::reg1::*; use crate::out::*; // Basic packing: @@ -66,7 +64,6 @@ mod tests { #[test] fn test_basic_reg2() { - use crate::out::reg2::*; use crate::out::*; // Basic packing: @@ -120,7 +117,6 @@ mod tests { #[test] fn test_basic_reg3() { - use crate::out::reg3::*; use crate::out::*; // Basic packing: @@ -158,7 +154,6 @@ mod tests { #[test] fn register_validation() { - use crate::out::reg2::*; use crate::out::*; // `STAT` enum in field 1 (bits 7-6) can only be 0x1-0x3. @@ -179,7 +174,6 @@ mod tests { #[test] fn enum_validation() { - use crate::out::reg2::*; use crate::out::*; assert_eq!(Stat::try_from_le_bytes(&[0]).unwrap_err().pos, 0); @@ -234,7 +228,6 @@ mod tests { #[test] fn test_fixed_accross_byte() { - use crate::out::reg_fixed_across_bytes::*; use crate::out::*; // Packing: @@ -251,7 +244,6 @@ mod tests { #[test] fn test_layout_fields() { - use crate::out::reg_layout_field::*; use crate::out::*; // Basic packing: @@ -293,7 +285,6 @@ mod tests { #[test] fn test_nested_only_fixed() { - use crate::out::reg_nested_only_fixed::*; use crate::out::*; // Basic packing: @@ -309,7 +300,6 @@ mod tests { #[test] fn test_split_field() { - use crate::out::reg_split_field::*; use crate::out::*; // Basic packing: @@ -331,7 +321,6 @@ mod tests { #[test] fn test_split_enum() { - use crate::out::reg_split_enum::*; use crate::out::*; // Basic packing: @@ -365,7 +354,6 @@ mod tests { #[test] fn test_split_layout() { - use crate::out::reg_split_layout::*; use crate::out::*; // Basic packing: