Skip to content

Commit

Permalink
Resolve name conflicts when deriving
Browse files Browse the repository at this point in the history
  • Loading branch information
n8tlarsen committed Nov 7, 2022
1 parent 3a49b32 commit 874f7df
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 31 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Test patched STM32
- simplify ci strategy
- Fix generated code for MSP430 atomics
- Add handling for disjoint arrays

## [v0.27.1] - 2022-10-25

Expand Down Expand Up @@ -40,7 +41,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Bring documentation on how to generate MSP430 PACs up to date (in line with
[msp430_svd](https://github.com/pftbest/msp430_svd)).
- Prefix submodule path with self:: when reexporting submodules to avoid ambiguity in crate path.
- Add handling for disjoint arrays

## [v0.25.1] - 2022-08-22

Expand Down
57 changes: 31 additions & 26 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ fn register_or_cluster_block(
let ercs_expanded = expand(ercs, derive_infos, config)
.with_context(|| "Could not expand register or cluster block")?;

// Locate conflicting regions; we'll need to use unions to derive_infoesent them.
// Locate conflicting regions; we'll need to use unions to represent them.
let mut regions = FieldRegions::default();

for reg_block_field in &ercs_expanded {
Expand Down Expand Up @@ -1084,15 +1084,15 @@ fn expand_register(
let description = register.description.clone().unwrap_or_default();

let info_name = register.fullname(config.ignore_groups);
let ty_name = if register.is_single() {
let mut ty_name = if register.is_single() {
info_name.to_string()
} else {
util::replace_suffix(&info_name, "")
};
let ty = name_to_ty(&ty_name);

match register {
Register::Single(info) => {
let ty = name_to_ty(&ty_name);
let syn_field = new_syn_field(ty_name.to_snake_case_ident(Span::call_site()), ty);
register_expanded.push(RegisterBlockField {
syn_field,
Expand All @@ -1114,20 +1114,36 @@ fn expand_register(
false => true,
};

// force expansion if we're implicitly deriving so we don't get name collisions
let array_convertible = if let DeriveInfo::Implicit(_) = derive_info {
false
// if dimIndex exists, test if it is a sequence of numbers from 0 to dim
let sequential_indexes_from0 = array_info
.indexes_as_range()
.filter(|r| *r.start() == 0)
.is_some();

// force expansion and rename if we're deriving an array that doesnt start at 0 so we don't get name collisions
let index: Cow<str> = if let Some(dim_index) = &array_info.dim_index {
dim_index.first().unwrap().into()
} else {
sequential_addresses && convert_list
if sequential_indexes_from0 {
"0".into()
} else {
"".into()
}
};
let array_convertible = match derive_info {
DeriveInfo::Implicit(_) => {
ty_name = util::replace_suffix(&info_name, &index);
sequential_addresses && convert_list && sequential_indexes_from0
}
DeriveInfo::Explicit(_) => {
ty_name = util::replace_suffix(&info_name, &index);
sequential_addresses && convert_list && sequential_indexes_from0
}
_ => sequential_addresses && convert_list,
};
let ty = name_to_ty(&ty_name);

if array_convertible {
// if dimIndex exists, test if it is a sequence of numbers from 0 to dim
let sequential_indexes_from0 = array_info
.indexes_as_range()
.filter(|r| *r.start() == 0)
.is_some();

let accessors = if sequential_indexes_from0 {
Vec::new()
} else {
Expand Down Expand Up @@ -1211,33 +1227,22 @@ fn render_ercs(
RegisterCluster::Register(reg) => {
trace!("Register: {}, DeriveInfo: {}", reg.name, derive_info);
let mut rpath = None;
let before_name = reg.name.to_string();
if let DeriveInfo::Implicit(rp) = derive_info {
let mut idx_name = None;
let info_name = reg.fullname(config.ignore_groups).to_string();
if let Register::Array(_, array_info) = reg {
for (_, i) in array_info.indexes().enumerate() {
idx_name = Some(util::replace_suffix(&info_name, &i).to_string());
}
}
if let Some(name) = idx_name {
reg.name = name;
}
rpath = Some(rp.clone());
} else {
let dpath = reg.derived_from.take();
if let Some(dpath) = dpath {
rpath = derive_register(reg, &dpath, path, index)?;
}
}
let reg_name = &reg.name;
let rendered_reg =
register::render(reg, path, rpath, index, config).with_context(|| {
let descrip = reg.description.as_deref().unwrap_or("No description");
format!(
"Error rendering register\nName: {before_name}\nDescription: {descrip}"
"Error rendering register\nName: {reg_name}\nDescription: {descrip}"
)
})?;
reg.name = before_name;
mod_items.extend(rendered_reg)
}
}
Expand Down
22 changes: 18 additions & 4 deletions src/generate/register.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
use crate::svd::{
Access, BitRange, EnumeratedValues, Field, ModifiedWriteValues, ReadAction, Register,
RegisterProperties, Usage, WriteConstraint,
Access, BitRange, EnumeratedValues, Field, MaybeArray, ModifiedWriteValues, ReadAction,
Register, RegisterProperties, Usage, WriteConstraint,
};
use core::u64;
use log::warn;
use proc_macro2::{Ident, Punct, Spacing, Span, TokenStream};
use quote::{quote, ToTokens};
use std::borrow::Cow;
use std::collections::HashSet;
use svd_parser::expand::{
derive_enumerated_values, derive_field, BlockPath, EnumPath, FieldPath, Index, RegisterPath,
};

use crate::util::{self, ident_to_path, path_segment, type_path, Config, ToSanitizedCase, U32Ext};
use crate::util::{
self, ident_to_path, path_segment, replace_suffix, type_path, Config, FullName,
ToSanitizedCase, U32Ext,
};
use anyhow::{anyhow, Result};
use syn::punctuated::Punctuated;

Expand All @@ -22,7 +26,17 @@ pub fn render(
index: &Index,
config: &Config,
) -> Result<TokenStream> {
let name = util::name_of(register, config.ignore_groups);
let mut name = util::name_of(register, config.ignore_groups);
// Rename if this is a derived array
if dpath.is_some() {
if let MaybeArray::Array(info, array_info) = register {
if let Some(dim_index) = &array_info.dim_index {
let index: Cow<str> = dim_index.first().unwrap().into();
name =
replace_suffix(&info.fullname(config.ignore_groups), &index.to_string()).into()
}
}
}
let span = Span::call_site();
let name_constant_case = name.to_constant_case_ident(span);
let name_snake_case = name.to_snake_case_ident(span);
Expand Down

0 comments on commit 874f7df

Please sign in to comment.