From 2f703ab2df03c4d1c7a91a52bbf3337e37e011ca Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Thu, 10 Mar 2022 15:35:23 -0500 Subject: [PATCH] tamer: obj::xmlo: Remove PackageAttrs in favor of token stream The Options here are awkward and will be able to go away in the new reader and in AsgBuilder once it has a proper state machine. This gets rid of some of the initial migratory work for the new reader, because PackageAttrs is gone. I'm going to wait to update this to the new way until I get further into this. DEV-11449 --- tamer/src/obj/xmlo/asg_builder.rs | 46 ++++++++-------- tamer/src/obj/xmlo/ir.rs | 29 ---------- tamer/src/obj/xmlo/mod.rs | 2 +- tamer/src/obj/xmlo/reader.rs | 61 ++++------------------ tamer/src/obj/xmlo/reader/quickxml.rs | 46 ++++++++-------- tamer/src/obj/xmlo/reader/quickxml/test.rs | 61 +++++++--------------- tamer/src/obj/xmlo/reader/test.rs | 33 ++++-------- 7 files changed, 90 insertions(+), 188 deletions(-) diff --git a/tamer/src/obj/xmlo/asg_builder.rs b/tamer/src/obj/xmlo/asg_builder.rs index effe5bad..2c880aff 100644 --- a/tamer/src/obj/xmlo/asg_builder.rs +++ b/tamer/src/obj/xmlo/asg_builder.rs @@ -185,13 +185,24 @@ where while let Some(ev) = xmlo.next() { match (istate, ev?) { - (IS::None, XmloEvent::Package(attrs)) => { + (IS::None, XmloEvent::PkgName(name)) => { if first { - state.name = attrs.name; - state.relroot = attrs.relroot; + state.name = Some(name); } + } - elig = attrs.elig; + (IS::None, XmloEvent::PkgRootPath(relroot)) => { + if first { + state.relroot = Some(relroot); + } + } + + (IS::None, XmloEvent::PkgEligClassYields(pkg_elig)) => { + elig = Some(pkg_elig); + } + + (IS::None, XmloEvent::PkgProgramFlag) => { + // Unused } (IS::None | IS::SymDep(_), XmloEvent::SymDepStart(sym)) => { @@ -349,7 +360,7 @@ impl Error for AsgBuilderError { mod test { use super::*; use crate::asg::{DefaultAsg, FragmentText, IdentObject}; - use crate::obj::xmlo::{PackageAttrs, SymAttrs, SymType}; + use crate::obj::xmlo::{SymAttrs, SymType}; use crate::sym::GlobalSymbolIntern; use std::collections::hash_map::RandomState; @@ -363,15 +374,12 @@ mod test { let name = "name".intern(); let relroot = "some/path".into(); - let evs = vec![Ok(XmloEvent::Package(PackageAttrs { - name: Some(name), - relroot: Some(relroot), - ..Default::default() - }))]; + let evs = vec![ + Ok(XmloEvent::PkgName(name)), + Ok(XmloEvent::PkgRootPath(relroot)), + ]; - let state = sut - .import_xmlo(evs.into_iter(), SutState::new()) - .expect("parsing of proper PackageAttrs must succeed"); + let state = sut.import_xmlo(evs.into_iter(), SutState::new()).unwrap(); assert_eq!(Some(name), state.name); assert_eq!(Some(relroot), state.relroot); @@ -400,10 +408,7 @@ mod test { .declare(elig_sym, IdentKind::Meta, Default::default()) .unwrap(); - let evs = vec![Ok(XmloEvent::Package(PackageAttrs { - elig: Some(elig_sym), - ..Default::default() - }))]; + let evs = vec![Ok(XmloEvent::PkgEligClassYields(elig_sym))]; let state = sut.import_xmlo(evs.into_iter(), SutState::new()).unwrap(); @@ -817,15 +822,12 @@ mod test { // Stop here. Ok(XmloEvent::Eoh), // Shouldn't make it to this one. - Ok(XmloEvent::Package(PackageAttrs { - name: Some(pkg_name), - ..Default::default() - })), + Ok(XmloEvent::PkgName(pkg_name)), ]; let state = sut.import_xmlo(evs.into_iter(), SutState::new()).unwrap(); - // Should still be true because we didn't get to the `PackageAttrs` + // Should still be true because we didn't get to the `PkgName` // event. assert!(state.is_first()); } diff --git a/tamer/src/obj/xmlo/ir.rs b/tamer/src/obj/xmlo/ir.rs index 41b43fee..137985d6 100644 --- a/tamer/src/obj/xmlo/ir.rs +++ b/tamer/src/obj/xmlo/ir.rs @@ -31,35 +31,6 @@ use crate::sym::{st, GlobalSymbolResolve, SymbolId}; use std::convert::TryFrom; use std::result::Result; -/// Toplevel package attributes. -#[derive(Debug, Default, PartialEq, Eq)] -pub struct PackageAttrs { - /// Unique package identifier. - /// - /// The package name is derived from the filename relative to the - /// project root during compilation (see `relroot`). - pub name: Option, - - /// Relative path from package to project root. - pub relroot: Option, - - /// Whether this package is a program. - /// - /// A _program_ is a package intended to be linked into a final - /// executable. - /// Programs cannot be imported by other packages. - /// Non-program packages cannot be linked. - pub program: bool, - - /// Symbol representing package eligibility. - /// - /// A package is _eligible_ for computation if certain invariants are - /// met. - /// This symbol is responsible for including each of those invariants as - /// dependencies so that they are included at link-time. - pub elig: Option, -} - /// Symbol attributes. /// /// This is a subset of all available attributes available on the diff --git a/tamer/src/obj/xmlo/mod.rs b/tamer/src/obj/xmlo/mod.rs index 4c1ee963..e5307b75 100644 --- a/tamer/src/obj/xmlo/mod.rs +++ b/tamer/src/obj/xmlo/mod.rs @@ -81,5 +81,5 @@ mod reader; pub use asg_builder::{AsgBuilder, AsgBuilderState}; pub use error::XmloError; -pub use ir::{PackageAttrs, SymAttrs, SymDtype, SymType}; +pub use ir::{SymAttrs, SymDtype, SymType}; pub use reader::{XmloEvent, XmloReader}; diff --git a/tamer/src/obj/xmlo/reader.rs b/tamer/src/obj/xmlo/reader.rs index 779a97c3..71198707 100644 --- a/tamer/src/obj/xmlo/reader.rs +++ b/tamer/src/obj/xmlo/reader.rs @@ -17,10 +17,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use super::{PackageAttrs, SymAttrs, XmloError}; -use crate::iter::TryFromIterator; -use crate::sym::{st::*, SymbolId}; -use crate::xir::tree::Attr; +use super::{SymAttrs, XmloError}; +use crate::sym::SymbolId; // While the _use_ is gated, this isn't, to ensure that we still try to // compile it while the flag is off (and so it's parsed by the language @@ -39,13 +37,6 @@ pub use new::XmloReader; /// potentially fail in error. pub type XmloResult = Result; -qname_const! { - QN_NAME: :L_NAME, - QN_ROOTPATH: :L_UUROOTPATH, - QN_PROGRAM: :L_PROGRAM, - QN_PREPROC_ELIG_CLASS_YIELDS: L_PREPROC:L_ELIG_CLASS_YIELDS, -} - #[cfg(feature = "wip-xmlo-xir-reader")] mod new { //! Re-implementation of `XmloReader` using a [`TokenStream`]. @@ -54,9 +45,7 @@ mod new { //! it exists to make feature-flagging less confusing and error-prone. use super::{XmloError, XmloEvent, XmloResult}; - use crate::iter::TryCollect; use crate::sym::st::*; - use crate::xir::tree::attr_parser_from; use crate::xir::{Token, TokenStream}; qname_const! { @@ -87,10 +76,7 @@ mod new { if !self.seen_root { match token { Token::Open(QN_LV_PACKAGE | QN_PACKAGE, _) => { - return Ok(XmloEvent::Package( - attr_parser_from(&mut self.reader) - .try_collect_ok()??, - )); + todo!("PackageAttrs removed"); } _ => return Err(XmloError::UnexpectedRoot), @@ -135,10 +121,14 @@ mod new { /// be useful and can't be easily skipped without parsing. #[derive(Debug, PartialEq, Eq)] pub enum XmloEvent { - /// Package declaration. - /// - /// This contains data gathered from the root `lv:package` node. - Package(PackageAttrs), + /// Canonical package name. + PkgName(SymbolId), + /// Relative path from package to project root. + PkgRootPath(SymbolId), + /// Indicates that the package is a program. + PkgProgramFlag, + /// Name of package eligibility classification. + PkgEligClassYields(SymbolId), /// Symbol declaration. /// @@ -172,35 +162,6 @@ pub enum XmloEvent { Eoh, } -impl TryFromIterator for PackageAttrs { - type Error = XmloError; - - fn try_from_iter>( - iter: I, - ) -> Result { - let mut attrs: Self = Default::default(); - - for attr in iter.into_iter() { - let val = attr.value(); - - match attr.name() { - QN_NAME => attrs.name = Some(val), - QN_ROOTPATH => attrs.relroot = Some(val), - QN_PROGRAM => attrs.program = val == raw::L_TRUE, - QN_PREPROC_ELIG_CLASS_YIELDS => attrs.elig = Some(val), - - // Ignore anything else on the root node. - // TODO: After tamec is fully migrated from XSLT, - // before we move to a different format, - // we should error here. - _ => (), - } - } - - Ok(attrs) - } -} - #[cfg(feature = "wip-xmlo-xir-reader")] #[cfg(test)] mod test; diff --git a/tamer/src/obj/xmlo/reader/quickxml.rs b/tamer/src/obj/xmlo/reader/quickxml.rs index 5acd8590..61b899b9 100644 --- a/tamer/src/obj/xmlo/reader/quickxml.rs +++ b/tamer/src/obj/xmlo/reader/quickxml.rs @@ -47,7 +47,7 @@ //! _You should stop reading at [`XmloEvent::Eoh`];_ //! reading the remainder of the object file has not yet been implemented. -use super::super::{PackageAttrs, SymAttrs, SymType}; +use super::super::{SymAttrs, SymType}; use super::{XmloError, XmloEvent, XmloResult}; use crate::sym::{GlobalSymbolInternUnchecked, GlobalSymbolResolve, SymbolId}; #[cfg(test)] @@ -202,13 +202,11 @@ where } XmlEvent::Start(ele) => match ele.name() { - b"package" | b"lv:package" => { - let attrs = Self::process_package(&ele)?; - - self.pkg_name = attrs.name; - - Ok(XmloEvent::Package(attrs)) - } + b"package" | b"lv:package" => Self::process_package( + &ele, + &mut self.pkg_name, + &mut self.event_queue, + ), b"preproc:sym-dep" => Self::process_dep( &ele, @@ -266,13 +264,11 @@ where } /// Process `lv:package` element attributes. - /// - /// The result is an [`XmloEvent::Package`] containing each applicable - /// attribute, - /// parsed. fn process_package<'a>( ele: &'a BytesStart<'a>, - ) -> XmloResult { + pkg_name: &mut Option, + event_queue: &mut VecDeque, + ) -> XmloResult { let mut program = false; let mut elig = None; let mut name = None; @@ -303,14 +299,22 @@ where } } - // TODO: proper errors, no panic - Ok(PackageAttrs { - name, - relroot, - program, - elig, - ..Default::default() - }) + if let Some(given_name) = name { + event_queue.push_back(XmloEvent::PkgName(given_name)); + } + if let Some(given_relroot) = relroot { + event_queue.push_back(XmloEvent::PkgRootPath(given_relroot)); + } + if let Some(given_elig) = elig { + event_queue.push_back(XmloEvent::PkgEligClassYields(given_elig)); + } + if program { + event_queue.push_back(XmloEvent::PkgProgramFlag); + } + + *pkg_name = name; + + Ok(event_queue.pop_front().unwrap()) } /// Process `preproc:sym` element attributes. diff --git a/tamer/src/obj/xmlo/reader/quickxml/test.rs b/tamer/src/obj/xmlo/reader/quickxml/test.rs index e302bcba..cc610b7d 100644 --- a/tamer/src/obj/xmlo/reader/quickxml/test.rs +++ b/tamer/src/obj/xmlo/reader/quickxml/test.rs @@ -109,7 +109,9 @@ xmlo_tests! { sut.reader.next_event = Some(Box::new(|_, _| { Ok(XmlEvent::Start(MockBytesStart::new( b"package", - Some(MockAttributes::new(vec![])), + Some(MockAttributes::new(vec![ + MockAttribute::new(b"program", b"true"), + ])), ))) })); @@ -123,7 +125,9 @@ xmlo_tests! { sut.reader.next_event = Some(Box::new(|_, _| { Ok(XmlEvent::Start(MockBytesStart::new( b"lv:package", - Some(MockAttributes::new(vec![])), + Some(MockAttributes::new(vec![ + MockAttribute::new(b"program", b"true"), + ])), ))) })); @@ -144,35 +148,13 @@ xmlo_tests! { ))) })); - let result = sut.read_event()?; - assert_eq!( - XmloEvent::Package(PackageAttrs { - program: true, - elig: Some("eligClassYields".intern()), - ..Default::default() - }), - result + XmloEvent::PkgEligClassYields("eligClassYields".intern()), + sut.read_event()? ); - } - - // DONE - fn package_event_nonprogram(sut) { - sut.reader.next_event = Some(Box::new(|_, _| { - Ok(XmlEvent::Start(MockBytesStart::new( - b"package", - Some(MockAttributes::new(vec![])), - ))) - })); - - let result = sut.read_event()?; - assert_eq!( - XmloEvent::Package(PackageAttrs { - program: false, - ..Default::default() - }), - result + XmloEvent::PkgProgramFlag, + sut.read_event()? ); } @@ -188,16 +170,14 @@ xmlo_tests! { ))) })); - let result = sut.read_event()?; + assert_eq!( + XmloEvent::PkgName("pkg/name".intern()), + sut.read_event()? + ); assert_eq!( - XmloEvent::Package(PackageAttrs { - name: Some("pkg/name".intern()), - relroot: Some("../../".into()), - program: false, - ..Default::default() - }), - result + XmloEvent::PkgRootPath("../../".intern()), + sut.read_event()? ); } @@ -615,17 +595,16 @@ xmlo_tests! { sut.reader.next_event = Some(Box::new(|_, _| { Ok(XmlEvent::Start(MockBytesStart::new( b"package", - Some(MockAttributes::new(vec![])), + Some(MockAttributes::new(vec![ + MockAttribute::new(b"name", b"pkg/name"), + ])), ))) })); let result = sut.next().unwrap()?; assert_eq!( - XmloEvent::Package(PackageAttrs { - program: false, - ..Default::default() - }), + XmloEvent::PkgName("pkg/name".intern()), result ); } diff --git a/tamer/src/obj/xmlo/reader/test.rs b/tamer/src/obj/xmlo/reader/test.rs index 4397d714..6c745c9c 100644 --- a/tamer/src/obj/xmlo/reader/test.rs +++ b/tamer/src/obj/xmlo/reader/test.rs @@ -39,8 +39,8 @@ fn fails_on_invalid_root() { assert_matches!(sut.next(), Some(Err(XmloError::UnexpectedRoot))); } -#[test] -fn parses_package_attrs() { +//#[test] +fn _parses_package_attrs() { let name = "pkgroot".into(); let relroot = "../../".into(); let elig = "elig-class-yields".into(); @@ -53,29 +53,21 @@ fn parses_package_attrs() { Token::AttrName("__rootpath".unwrap_into(), DS), Token::AttrValue(relroot, DS), Token::AttrName("program".unwrap_into(), DS), - Token::AttrValue(raw::L_TRUE, DS), + Token::AttrValue(crate::sym::st::raw::L_TRUE, DS), Token::AttrName(("preproc", "elig-class-yields").unwrap_into(), DS), Token::AttrValue(elig, DS), ] .into_iter(), ); - let result = sut.next(); + let _result = sut.next(); - assert_eq!( - Some(Ok(XmloEvent::Package(PackageAttrs { - name: Some(name), - relroot: Some(relroot), - program: true, - elig: Some(elig), - }))), - result - ); + todo!() } // The linker does not [yet] parse namespaces. -#[test] -fn parses_package_attrs_with_ns_prefix() { +//#[test] +fn _parses_package_attrs_with_ns_prefix() { let name = "pkgrootns".into(); let mut sut = Sut::from_reader( @@ -87,14 +79,7 @@ fn parses_package_attrs_with_ns_prefix() { .into_iter(), ); - let result = sut.next(); + let _result = sut.next(); - // NB: This also tests defaults and non-program. - assert_eq!( - Some(Ok(XmloEvent::Package(PackageAttrs { - name: Some(name), - ..Default::default() - }))), - result - ); + todo!() }