tamer: obj::xmlo::reader: Parse package attributes
Finally we get to do some actual parsing with all of the preparatory work! This means that we're finally ready to fully replace the old XmloReader, provided that I'm okay with some boilerplate / lack of abstractions for now (and I am, because all I've been doing is working on abstractions to prepare lowering operations). DEV-10863main
parent
ad8616aaa1
commit
fab7b16ea0
|
@ -45,19 +45,26 @@ mod new {
|
|||
//! it exists to make feature-flagging less confusing and error-prone.
|
||||
|
||||
use super::{XmloError, XmloEvent};
|
||||
use crate::parse::{ParseState, Transition};
|
||||
use crate::parse::{ParseState, Transition, TransitionResult};
|
||||
use crate::sym::st::*;
|
||||
use crate::xir::attr::Attr;
|
||||
use crate::xir::flat::Object as Xirf;
|
||||
|
||||
qname_const! {
|
||||
QN_LV_PACKAGE: L_LV:L_PACKAGE,
|
||||
QN_PACKAGE: :L_PACKAGE,
|
||||
QN_NAME: :L_NAME,
|
||||
QN_UUROOTPATH: :L_UUROOTPATH,
|
||||
QN_PROGRAM: :L_PROGRAM,
|
||||
QN_PREPROC_ELIG_CLASS_YIELDS: L_PREPROC:L_ELIG_CLASS_YIELDS,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
pub enum XmloReader {
|
||||
#[default]
|
||||
Ready,
|
||||
Package,
|
||||
Done,
|
||||
}
|
||||
|
||||
impl ParseState for XmloReader {
|
||||
|
@ -65,24 +72,40 @@ mod new {
|
|||
type Object = XmloEvent;
|
||||
type Error = XmloError;
|
||||
|
||||
fn parse_token(
|
||||
self,
|
||||
tok: Self::Token,
|
||||
) -> crate::parse::TransitionResult<Self> {
|
||||
use XmloReader::Ready;
|
||||
fn parse_token(self, tok: Self::Token) -> TransitionResult<Self> {
|
||||
use XmloReader::{Done, Package, Ready};
|
||||
|
||||
match (self, tok) {
|
||||
(Ready, Xirf::Open(QN_LV_PACKAGE | QN_PACKAGE, _, _)) => {
|
||||
todo!("PackageAttrs removed");
|
||||
(Ready, Xirf::Open(QN_LV_PACKAGE | QN_PACKAGE, ..)) => {
|
||||
Transition(Package).incomplete()
|
||||
}
|
||||
|
||||
(Ready, _) => Transition(Ready).err(XmloError::UnexpectedRoot),
|
||||
|
||||
(Package, Xirf::Attr(Attr(name, value, _))) => {
|
||||
Transition(Package).with(match name {
|
||||
QN_NAME => XmloEvent::PkgName(value),
|
||||
QN_UUROOTPATH => XmloEvent::PkgRootPath(value),
|
||||
QN_PROGRAM => XmloEvent::PkgProgramFlag,
|
||||
QN_PREPROC_ELIG_CLASS_YIELDS => {
|
||||
XmloEvent::PkgEligClassYields(value)
|
||||
}
|
||||
// Ignore unknown attributes for now to maintain BC,
|
||||
// since no strict xmlo schema has been defined.
|
||||
_ => return Transition(Package).incomplete(),
|
||||
})
|
||||
}
|
||||
|
||||
// Empty package (should we allow this?);
|
||||
// XIRF guarantees a matching closing tag.
|
||||
(Package, Xirf::Close(..)) => Transition(Done).incomplete(),
|
||||
|
||||
todo => todo!("{todo:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_accepting(&self) -> bool {
|
||||
// TODO
|
||||
todo!("XmloReader::is_accepting")
|
||||
*self == Self::Done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,14 +22,20 @@ use std::assert_matches::assert_matches;
|
|||
use super::*;
|
||||
use crate::{
|
||||
convert::ExpectInto,
|
||||
parse::{ParseError, ParseState},
|
||||
span::DUMMY_SPAN as DS,
|
||||
parse::{ParseError, ParseState, Parsed},
|
||||
span::{Span, DUMMY_SPAN},
|
||||
xir::{
|
||||
attr::Attr,
|
||||
flat::{Depth, Object as Xirf},
|
||||
QName,
|
||||
},
|
||||
};
|
||||
|
||||
const S1: Span = DUMMY_SPAN;
|
||||
const S2: Span = S1.offset_add(1).unwrap();
|
||||
const S3: Span = S2.offset_add(1).unwrap();
|
||||
const S4: Span = S3.offset_add(1).unwrap();
|
||||
|
||||
type Sut = XmloReader;
|
||||
|
||||
#[test]
|
||||
|
@ -37,7 +43,7 @@ fn fails_on_invalid_root() {
|
|||
let mut sut = Sut::parse(
|
||||
[Xirf::Open(
|
||||
"not-a-valid-package-node".unwrap_into(),
|
||||
DS,
|
||||
S1,
|
||||
Depth(0),
|
||||
)]
|
||||
.into_iter(),
|
||||
|
@ -49,54 +55,81 @@ fn fails_on_invalid_root() {
|
|||
);
|
||||
}
|
||||
|
||||
//#[test]
|
||||
fn _parses_package_attrs() {
|
||||
fn common_parses_package_attrs(package: QName) {
|
||||
let name = "pkgroot".into();
|
||||
let relroot = "../../".into();
|
||||
let elig = "elig-class-yields".into();
|
||||
|
||||
let mut sut = Sut::parse(
|
||||
[
|
||||
Xirf::Open("package".unwrap_into(), DS, Depth(0)),
|
||||
Xirf::Attr(Attr::new("name".unwrap_into(), name, (DS, DS))),
|
||||
Xirf::Attr(Attr::new(
|
||||
"__rootpath".unwrap_into(),
|
||||
relroot,
|
||||
(DS, DS),
|
||||
)),
|
||||
Xirf::Attr(Attr::new(
|
||||
"program".unwrap_into(),
|
||||
crate::sym::st::raw::L_TRUE,
|
||||
(DS, DS),
|
||||
)),
|
||||
Xirf::Attr(Attr::new(
|
||||
("preproc", "elig-class-yields").unwrap_into(),
|
||||
elig,
|
||||
(DS, DS),
|
||||
)),
|
||||
]
|
||||
.into_iter(),
|
||||
let toks = [
|
||||
Xirf::Open(package, S1, Depth(0)),
|
||||
Xirf::Attr(Attr::new("name".unwrap_into(), name, (S2, S3))),
|
||||
Xirf::Attr(Attr::new("__rootpath".unwrap_into(), relroot, (S2, S3))),
|
||||
Xirf::Attr(Attr::new(
|
||||
"program".unwrap_into(),
|
||||
crate::sym::st::raw::L_TRUE,
|
||||
(S3, S4),
|
||||
)),
|
||||
Xirf::Attr(Attr::new(
|
||||
("preproc", "elig-class-yields").unwrap_into(),
|
||||
elig,
|
||||
(S3, S4),
|
||||
)),
|
||||
Xirf::Close(Some(package), S2, Depth(0)),
|
||||
]
|
||||
.into_iter();
|
||||
|
||||
let sut = Sut::parse(toks);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
Parsed::Incomplete,
|
||||
Parsed::Object(XmloEvent::PkgName(name)),
|
||||
Parsed::Object(XmloEvent::PkgRootPath(relroot)),
|
||||
Parsed::Object(XmloEvent::PkgProgramFlag),
|
||||
Parsed::Object(XmloEvent::PkgEligClassYields(elig)),
|
||||
Parsed::Incomplete,
|
||||
]),
|
||||
sut.collect(),
|
||||
);
|
||||
|
||||
let _result = sut.next();
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
// The linker does not [yet] parse namespaces.
|
||||
//#[test]
|
||||
fn _parses_package_attrs_with_ns_prefix() {
|
||||
let name = "pkgrootns".into();
|
||||
|
||||
let mut sut = Sut::parse(
|
||||
[
|
||||
Xirf::Open(("lv", "package").unwrap_into(), DS, Depth(0)),
|
||||
Xirf::Attr(Attr::new("name".unwrap_into(), name, (DS, DS))),
|
||||
]
|
||||
.into_iter(),
|
||||
);
|
||||
|
||||
let _result = sut.next();
|
||||
|
||||
todo!()
|
||||
#[test]
|
||||
fn parses_package_attrs_without_ns_prefix() {
|
||||
common_parses_package_attrs("package".unwrap_into());
|
||||
}
|
||||
|
||||
// The linker does not [yet] parse namespaces.
|
||||
#[test]
|
||||
fn parses_package_attrs_with_ns_prefix() {
|
||||
common_parses_package_attrs(("lv", "package").unwrap_into());
|
||||
}
|
||||
|
||||
// Maintains BC with existing system,
|
||||
// but this ought to reject in the future.
|
||||
#[test]
|
||||
fn ignores_unknown_package_attr() {
|
||||
let package = "package".unwrap_into();
|
||||
let name = "pkgroot".into();
|
||||
|
||||
let toks = [
|
||||
Xirf::Open(package, S1, Depth(0)),
|
||||
Xirf::Attr(Attr::new("name".unwrap_into(), name, (S2, S3))),
|
||||
// This is ignored.
|
||||
Xirf::Attr(Attr::new("unknown".unwrap_into(), name, (S2, S3))),
|
||||
Xirf::Close(Some(package), S2, Depth(0)),
|
||||
]
|
||||
.into_iter();
|
||||
|
||||
let sut = Sut::parse(toks);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
Parsed::Incomplete,
|
||||
Parsed::Object(XmloEvent::PkgName(name)),
|
||||
Parsed::Incomplete, // The unknown attribute
|
||||
Parsed::Incomplete,
|
||||
]),
|
||||
sut.collect(),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue