tamer: Move Sections map from unique from writer into Sections

We're implementing an new XIR-based writer and don't want to have to
duplicate this; it didn't really belong there to begin with.
main
Mike Gerwitz 2021-10-04 16:30:34 -04:00
parent 004f5dc312
commit e2c9944f1b
2 changed files with 66 additions and 11 deletions

View File

@ -24,6 +24,9 @@
//!
//! [`SortableAsg::sort`]: super::SortableAsg::sort
use super::IdentObjectData;
use crate::sym::SymbolId;
use fxhash::FxHashSet;
use std::iter::Chain;
use std::slice::Iter;
@ -121,7 +124,7 @@ pub struct Sections<'a, T> {
pub rater: Section<'a, T>,
}
impl<'a, T> Sections<'a, T> {
impl<'a, T: IdentObjectData> Sections<'a, T> {
/// New collection of empty sections.
pub fn new() -> Self {
Self {
@ -189,6 +192,19 @@ impl<'a, T> Sections<'a, T> {
SectionsIter(SectionsIterType::Single(self.map.iter()))
}
/// Iterate over each unique map `from` entry.
///
/// Multiple mappings may reference the same source field,
/// which would produce duplicate values if they are not filtered.
pub fn iter_map_froms_uniq(&self) -> impl Iterator<Item = SymbolId> {
self.iter_map()
.filter_map(|ident| {
ident.src().expect("internal error: missing map src").from
})
.collect::<FxHashSet<SymbolId>>()
.into_iter()
}
/// Construct an iterator over the return map section.
pub fn iter_retmap(&self) -> SectionsIter<T> {
SectionsIter(SectionsIterType::Single(self.retmap.iter()))
@ -236,12 +252,20 @@ impl<'a, T> Iterator for SectionsIter<'a, T> {
SectionsIterType::Single(inner) => inner.next(),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match &self.0 {
SectionsIterType::All(inner) => inner.size_hint(),
SectionsIterType::Static(inner) => inner.size_hint(),
SectionsIterType::Single(inner) => inner.size_hint(),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::ir::asg::IdentObject;
use crate::ir::asg::{IdentKind, IdentObject, Source};
use crate::sym::GlobalSymbolIntern;
type Sut<'a, 'i> = Section<'a, IdentObject>;
@ -376,4 +400,43 @@ mod test {
objs.iter().collect::<Vec<_>>()
);
}
#[test]
fn sections_iter_map_froms_uniq() {
let mut sut_a = Sections::new();
let mut sut_b = Sections::new();
let a = IdentObject::Ident(
"a".intern(),
IdentKind::Map,
Source {
from: Some("froma".intern()),
..Default::default()
},
);
let b = IdentObject::Ident(
"a".intern(),
IdentKind::Map,
Source {
from: Some("fromb".intern()),
..Default::default()
},
);
// A contains duplicates.
sut_a.map.body.push(&a);
sut_a.map.body.push(&a);
sut_a.map.body.push(&b);
// B does not.
sut_b.map.body.push(&a);
sut_b.map.body.push(&b);
// They should compare the same.
assert_eq!(
sut_a.iter_map_froms_uniq().collect::<Vec<_>>(),
sut_b.iter_map_froms_uniq().collect::<Vec<_>>(),
);
}
}

View File

@ -22,7 +22,6 @@ use crate::ir::asg::{
IdentKind, IdentObject, IdentObjectData, Sections, SectionsIter,
};
use crate::sym::{GlobalSymbolResolve, SymbolId};
use fxhash::FxHashSet;
#[cfg(test)]
use mock::MockXmlWriter as XmlWriter;
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
@ -302,14 +301,7 @@ impl<W: Write> XmleWriter<W> {
&mut self,
sections: &Sections<T>,
) -> Result<&mut XmleWriter<W>> {
let map_froms: FxHashSet<SymbolId> = sections
.iter_map()
.filter_map(|ident| {
ident.src().expect("internal error: missing map src").from
})
.collect();
for from in map_froms {
for from in sections.iter_map_froms_uniq() {
let name: &str = &from.lookup_str();
self.writer.write_event(Event::Empty(