diff options
author | Joseph Frazer <joseph.frazer@ryansg.com> | 2020-03-07 10:28:39 -0500 |
---|---|---|
committer | Joseph Frazer <joseph.frazer@ryansg.com> | 2020-03-09 08:23:13 -0400 |
commit | 2a5551a04a6705d20e16c54aca1f875198ae89ab (patch) | |
tree | be52192003e7e6dcaa8b70351633c14b1b23a6c7 | |
parent | 06bc89a9cee68a242dfd91497c1c7ab36ac30424 (diff) | |
download | tame-2a5551a04a6705d20e16c54aca1f875198ae89ab.tar.gz tame-2a5551a04a6705d20e16c54aca1f875198ae89ab.tar.bz2 tame-2a5551a04a6705d20e16c54aca1f875198ae89ab.zip |
[DEV-7134] Propagate errors setting fragments
If we cannot set a fragment, we need to display the error to the user.
We are currently ignoring "___head", "___tail", and objects that are
both virtual and overridden. Those will be corrected in with future
changes.
-rw-r--r-- | tamer/src/ir/asg/base.rs | 89 | ||||
-rw-r--r-- | tamer/src/ld/poc.rs | 24 | ||||
-rw-r--r-- | tamer/src/obj/xmlo/reader.rs | 5 |
3 files changed, 106 insertions, 12 deletions
diff --git a/tamer/src/ir/asg/base.rs b/tamer/src/ir/asg/base.rs index ba0bd21..a50fe8b 100644 --- a/tamer/src/ir/asg/base.rs +++ b/tamer/src/ir/asg/base.rs @@ -213,6 +213,43 @@ where Object::Ident(sym, kind, src) => { Ok(Object::IdentFragment(sym, kind, src, text)) } + Object::IdentFragment(_, IdentKind::MapHead, _, _) => Ok(ty), + Object::IdentFragment(_, IdentKind::MapTail, _, _) => Ok(ty), + Object::IdentFragment(_, IdentKind::RetMapHead, _, _) => Ok(ty), + Object::IdentFragment(_, IdentKind::RetMapTail, _, _) => Ok(ty), + // TODO remove these ignores when fixed + Object::IdentFragment( + sym, + IdentKind::Map, + Source { + virtual_: true, + override_: true, + .. + }, + _, + ) => { + eprintln!( + "ignoring virtual and overridden map object: {}", + sym + ); + Ok(ty) + } + Object::IdentFragment( + sym, + IdentKind::RetMap, + Source { + virtual_: true, + override_: true, + .. + }, + _, + ) => { + eprintln!( + "ignoring virtual and overridden retmap object: {}", + sym + ); + Ok(ty) + } _ => { let err = Err(AsgError::BadFragmentDest(format!( "identifier is not a Object::Ident): {:?}", @@ -536,6 +573,58 @@ mod test { Ok(()) } + fn add_ident_kind_ignores( + given: IdentKind, + expected: IdentKind, + ) -> AsgResult<()> { + let mut sut = Sut::with_capacity(0, 0); + + let sym = Symbol::new_dummy(SymbolIndex::from_u32(1), "tofrag"); + let src = Source { + generated: true, + ..Default::default() + }; + + let node = sut.declare(&sym, given, src.clone())?; + + let fragment = "a fragment".to_string(); + let node_with_frag = sut.set_fragment(node, fragment.clone())?; + + // Attaching a fragment should _replace_ the node, not create a + // new one + assert_eq!( + node, node_with_frag, + "fragment node does not match original node" + ); + + assert_eq!( + Some(&Object::IdentFragment(&sym, expected, src, fragment)), + sut.get(node) + ); + + Ok(()) + } + + #[test] + fn add_fragment_to_ident_map_head() -> AsgResult<()> { + add_ident_kind_ignores(IdentKind::MapHead, IdentKind::MapHead) + } + + #[test] + fn add_fragment_to_ident_map_tail() -> AsgResult<()> { + add_ident_kind_ignores(IdentKind::MapTail, IdentKind::MapTail) + } + + #[test] + fn add_fragment_to_ident_retmap_head() -> AsgResult<()> { + add_ident_kind_ignores(IdentKind::RetMapHead, IdentKind::RetMapHead) + } + + #[test] + fn add_fragment_to_ident_retmap_tail() -> AsgResult<()> { + add_ident_kind_ignores(IdentKind::RetMapTail, IdentKind::RetMapTail) + } + #[test] fn add_fragment_to_fragment_fails() -> AsgResult<()> { let mut sut = Sut::with_capacity(0, 0); diff --git a/tamer/src/ld/poc.rs b/tamer/src/ld/poc.rs index 6bedd7a..6d3d175 100644 --- a/tamer/src/ld/poc.rs +++ b/tamer/src/ld/poc.rs @@ -21,8 +21,7 @@ //! banished to its own file to try to make that more clear. use crate::global; -use crate::ir::asg::IdentKind; -use crate::ir::asg::{Asg, DefaultAsg, Object, ObjectRef, Source}; +use crate::ir::asg::{Asg, DefaultAsg, IdentKind, Object, ObjectRef, Source}; use crate::obj::xmle::writer::{Sections, XmleWriter}; use crate::obj::xmlo::reader::{XmloError, XmloEvent, XmloReader}; use crate::sym::{DefaultInterner, Interner, Symbol}; @@ -187,16 +186,17 @@ fn load_xmlo<'a, 'i, I: Interner<'i>>( } Ok(XmloEvent::Fragment(sym, text)) => { - let result = depgraph.set_fragment( - depgraph.lookup(sym).unwrap_or_else(|| { - panic!("missing symbol for fragment: {}", sym) - }), - text, - ); - - match result { - Ok(_) => (), - Err(e) => println!("{:?}; skipping...", e), + match depgraph.lookup(sym) { + Some(frag) => match depgraph.set_fragment(frag, text) { + Ok(_) => (), + Err(e) => return Err(e.into()), + }, + None => { + return Err(XmloError::MissingFragment(String::from( + "missing fragment", + )) + .into()); + } }; } diff --git a/tamer/src/obj/xmlo/reader.rs b/tamer/src/obj/xmlo/reader.rs index 55723ed..ded13c0 100644 --- a/tamer/src/obj/xmlo/reader.rs +++ b/tamer/src/obj/xmlo/reader.rs @@ -764,6 +764,8 @@ pub enum XmloError { UnassociatedFragment, /// A `preproc:fragment` element was found, but is missing `text()`. MissingFragmentText(String), + /// A `preproc:fragment` element was not found + MissingFragment(String), } impl From<XmlError> for XmloError { @@ -811,6 +813,9 @@ impl Display for XmloError { "fragment found, but missing text for symbol `{}`", symname, ), + XmloError::MissingFragment(symname) => { + write!(fmt, "fragment not found `{}`", symname,) + } } } } |