Skip to content

Commit 197623a

Browse files
committed
cluster aliases
1 parent 5195d7c commit 197623a

File tree

4 files changed

+61
-24
lines changed

4 files changed

+61
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- Create aliases for derived registers & clusters
1011
- Move cluster struct inside mod
1112
- Support non-sequential field arrays
1213
- Use inlined variables in `format!` (Rust 1.58)

src/generate/peripheral.rs

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use crate::svd::{
88
use log::{debug, trace, warn};
99
use proc_macro2::{Ident, Punct, Spacing, Span, TokenStream};
1010
use quote::{quote, ToTokens};
11-
use syn::Token;
11+
use syn::{punctuated::Punctuated, Token};
1212

1313
use crate::util::{
14-
self, array_proxy_type, name_to_ty, name_to_wrapped_ty, new_syn_u32, unsuffixed, Config,
15-
FullName, ToSanitizedCase, BITS_PER_BYTE,
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,
1616
};
1717
use anyhow::{anyhow, bail, Context, Result};
1818

@@ -864,8 +864,7 @@ fn render_ercs(
864864
if let Some(dpath) = dpath {
865865
cpath = derive_cluster(c, &dpath, path, index)?;
866866
}
867-
let cpath = cpath.unwrap_or_else(|| path.new_cluster(&c.name));
868-
mod_items.extend(cluster_block(c, &cpath, index, config)?);
867+
mod_items.extend(cluster_block(c, path, cpath, index, config)?);
869868
}
870869

871870
// Generate definition for each of the registers.
@@ -878,8 +877,8 @@ fn render_ercs(
878877
}
879878
let reg_name = &reg.name;
880879

881-
let rendered_reg = register::render(reg, path, &rpath, index, config)
882-
.with_context(|| {
880+
let rendered_reg =
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\nName: {reg_name}\nDescription: {descrip}"
@@ -896,33 +895,65 @@ fn render_ercs(
896895
fn 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.
905-
let mod_name = util::replace_suffix(&c.name, "");
906-
907-
let reg_block = register_or_cluster_block(&c.children, Some(&mod_name), config)?;
908-
909-
// name_snake_case needs to take into account array type.
910902
let description =
911903
util::escape_brackets(&util::respace(c.description.as_ref().unwrap_or(&c.name)));
904+
let mod_name = util::replace_suffix(&c.name, "");
912905

913-
let name_snake_case = mod_name.to_snake_case_ident(Span::call_site());
906+
// name_snake_case needs to take into account array type.
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);
914910

915911
let struct_path = name_to_ty(&mod_name);
916912

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)));
931+
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+
};
949+
917950
Ok(quote! {
918951
#[doc = #description]
919952
pub use #struct_path;
920953

921954
///Cluster
922955
#[doc = #description]
923956
pub mod #name_snake_case {
924-
#reg_block
925-
926957
#mod_items
927958
}
928959
})

src/generate/register.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use syn::punctuated::Punctuated;
1919
pub fn render(
2020
register: &Register,
2121
path: &BlockPath,
22-
dpath: &Option<RegisterPath>,
22+
dpath: Option<RegisterPath>,
2323
index: &Index,
2424
config: &Config,
2525
) -> Result<TokenStream> {
@@ -44,8 +44,7 @@ pub fn render(
4444
pub type #name_constant_case = #wrapped_name;
4545
});
4646

47-
let mod_items = if let Some(dpath) = dpath {
48-
let mut mod_items = TokenStream::new();
47+
let mod_items = if let Some(dpath) = dpath.as_ref() {
4948
let mut derived_spec = if &dpath.block == path {
5049
let mut segments = Punctuated::new();
5150
segments.push(path_segment(Ident::new("super", span)));
@@ -62,11 +61,10 @@ pub fn render(
6261
format!("{}_SPEC", dname).to_constant_case_ident(span),
6362
));
6463

65-
mod_items.extend(quote! {
64+
quote! {
6665
#[doc = #description]
6766
pub use #derived_spec as #name_constant_case_spec;
68-
});
69-
mod_items
67+
}
7068
} else {
7169
render_register_mod(register, &path.new_register(&register.name), index, config)?
7270
};

src/util.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use proc_macro2::{Ident, Span, TokenStream};
66
use quote::quote;
77
use std::collections::HashSet;
88
use std::path::{Path, PathBuf};
9+
use svd_parser::expand::BlockPath;
910
use svd_rs::{MaybeArray, PeripheralInfo};
1011

1112
use syn::{
@@ -441,6 +442,12 @@ pub fn path_segment(ident: Ident) -> PathSegment {
441442
}
442443
}
443444

445+
pub fn parent(p: &BlockPath) -> BlockPath {
446+
let mut p = p.clone();
447+
p.path.pop().unwrap();
448+
p
449+
}
450+
444451
pub trait U32Ext {
445452
fn size_to_str(&self) -> Result<&str>;
446453
fn to_ty(&self) -> Result<Ident>;

0 commit comments

Comments
 (0)