tamer: Read only a single map preproc:from from xmlo files
This was creating a heap-allocated `Vec` for each map symbol despite not actually needing it. We do have multiple froms for return map values. But by the time we may want this type of thing, we'll have a different IR for it anyway.main
parent
772619f6f0
commit
004f5dc312
|
@ -657,7 +657,7 @@ pub struct Source {
|
|||
///
|
||||
/// TODO: We have `parent`, `yields`, and `from`.
|
||||
/// We should begin to consolodate.
|
||||
pub from: Option<Vec<SymbolId>>,
|
||||
pub from: Option<SymbolId>,
|
||||
|
||||
/// Whether identifier is virtual (can be overridden).
|
||||
///
|
||||
|
@ -1665,7 +1665,7 @@ mod test {
|
|||
parent: Some(psym),
|
||||
yields: Some(ysym),
|
||||
desc: Some("sym desc".into()),
|
||||
from: Some(vec![fsym]),
|
||||
from: Some(fsym),
|
||||
virtual_: true,
|
||||
override_: true,
|
||||
..Default::default()
|
||||
|
@ -1679,7 +1679,7 @@ mod test {
|
|||
parent: attrs.parent,
|
||||
yields: attrs.yields,
|
||||
desc: Some("sym desc".into()),
|
||||
from: Some(vec![fsym]),
|
||||
from: Some(fsym),
|
||||
virtual_: true,
|
||||
override_: true,
|
||||
},
|
||||
|
|
|
@ -159,7 +159,9 @@ pub struct SymAttrs {
|
|||
/// - [`SymType::Map`] includes the name of the source field; and
|
||||
/// - [`SymType::Func`] lists params in order (so that the compiler
|
||||
/// knows application order).
|
||||
pub from: Option<Vec<SymbolId>>,
|
||||
///
|
||||
/// This system currently only handles the former.
|
||||
pub from: Option<SymbolId>,
|
||||
|
||||
/// Whether symbol can be overridden.
|
||||
///
|
||||
|
|
|
@ -302,19 +302,12 @@ impl<W: Write> XmleWriter<W> {
|
|||
&mut self,
|
||||
sections: &Sections<T>,
|
||||
) -> Result<&mut XmleWriter<W>> {
|
||||
let mut map_froms: FxHashSet<SymbolId> = Default::default();
|
||||
|
||||
let map_iter = sections.iter_map();
|
||||
|
||||
for map_ident in map_iter {
|
||||
let src = map_ident.src().expect("internal error: missing map src");
|
||||
|
||||
if let Some(froms) = &src.from {
|
||||
for from in froms {
|
||||
map_froms.insert(*from);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 {
|
||||
let name: &str = &from.lookup_str();
|
||||
|
@ -650,7 +643,7 @@ mod test {
|
|||
parent: Some(psym),
|
||||
yields: Some(ysym),
|
||||
desc: Some("sym desc".into()),
|
||||
from: Some(vec![fsym]),
|
||||
from: Some(fsym),
|
||||
virtual_: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
@ -688,7 +681,7 @@ mod test {
|
|||
let symb = "dest symbol".intern();
|
||||
|
||||
let mut src = Source::default();
|
||||
src.from = Some(vec![symb]);
|
||||
src.from = Some(symb);
|
||||
let object = IdentObject::Ident(sym, IdentKind::Worksheet, src);
|
||||
let mut sections = Sections::new();
|
||||
sections.map.push_body(&object);
|
||||
|
|
|
@ -313,10 +313,10 @@ where
|
|||
XmloEvent::SymDecl(_, attrs)
|
||||
if attrs.ty == Some(SymType::Map) =>
|
||||
{
|
||||
attrs.from = Some(Self::process_map_from(
|
||||
attrs.from = Self::process_map_from(
|
||||
&mut self.reader,
|
||||
&mut self.sub_buffer,
|
||||
)?);
|
||||
)?;
|
||||
|
||||
Ok(event)
|
||||
}
|
||||
|
@ -502,13 +502,22 @@ where
|
|||
fn process_map_from<'a>(
|
||||
reader: &mut XmlReader<B>,
|
||||
buffer: &mut Vec<u8>,
|
||||
) -> XmloResult<Vec<SymbolId>> {
|
||||
let mut froms = Vec::new();
|
||||
) -> XmloResult<Option<SymbolId>> {
|
||||
let mut from = None;
|
||||
|
||||
loop {
|
||||
match reader.read_event(buffer)? {
|
||||
XmlEvent::Empty(ele) if ele.name() == b"preproc:from" => froms
|
||||
.push(
|
||||
XmlEvent::Empty(ele) if ele.name() == b"preproc:from" => {
|
||||
if from.is_some() {
|
||||
// This feature isn't actually utilized for the
|
||||
// input map.
|
||||
return Err(XmloError::InvalidMapFrom(
|
||||
"multiple preproc:from found for input map entry"
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
|
||||
from.replace(
|
||||
ele.attributes()
|
||||
.with_checks(false)
|
||||
.filter_map(Result::ok)
|
||||
|
@ -523,7 +532,8 @@ where
|
|||
})
|
||||
},
|
||||
)?,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
XmlEvent::End(ele) if ele.name() == b"preproc:sym" => break,
|
||||
|
||||
|
@ -534,7 +544,7 @@ where
|
|||
};
|
||||
}
|
||||
|
||||
Ok(froms)
|
||||
Ok(from)
|
||||
}
|
||||
|
||||
/// Process `preproc:sym-dep` element.
|
||||
|
|
|
@ -487,7 +487,12 @@ xmlo_tests! {
|
|||
])),
|
||||
))),
|
||||
|
||||
1 => Ok(XmlEvent::Empty(MockBytesStart::new(
|
||||
// make sure that whitespace is permitted
|
||||
1 => Ok(XmlEvent::Text(MockBytesText::new(
|
||||
b" ",
|
||||
))),
|
||||
|
||||
2 => Ok(XmlEvent::Empty(MockBytesStart::new(
|
||||
b"preproc:from",
|
||||
Some(MockAttributes::new(vec![
|
||||
MockAttribute::new(
|
||||
|
@ -496,21 +501,7 @@ xmlo_tests! {
|
|||
])),
|
||||
))),
|
||||
|
||||
// make sure that whitespace is permitted
|
||||
2 => Ok(XmlEvent::Text(MockBytesText::new(
|
||||
b" ",
|
||||
))),
|
||||
|
||||
3 => Ok(XmlEvent::Empty(MockBytesStart::new(
|
||||
b"preproc:from",
|
||||
Some(MockAttributes::new(vec![
|
||||
MockAttribute::new(
|
||||
b"name", b"from-b",
|
||||
),
|
||||
])),
|
||||
))),
|
||||
|
||||
4 => Ok(XmlEvent::End(MockBytesEnd::new(
|
||||
3 => Ok(XmlEvent::End(MockBytesEnd::new(
|
||||
b"preproc:sym",
|
||||
))),
|
||||
|
||||
|
@ -526,10 +517,9 @@ xmlo_tests! {
|
|||
"sym-map-from".intern(),
|
||||
SymAttrs {
|
||||
ty: Some(SymType::Map),
|
||||
from: Some(vec![
|
||||
from: Some(
|
||||
"from-a".intern(),
|
||||
"from-b".intern(),
|
||||
]),
|
||||
),
|
||||
pkg_name: Some("pkg/name".intern()),
|
||||
..Default::default()
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue