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
parent
004f5dc312
commit
e2c9944f1b
|
@ -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<_>>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue