Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Frazer <joseph.frazer@ryansg.com>2020-03-07 10:28:39 -0500
committerJoseph Frazer <joseph.frazer@ryansg.com>2020-03-09 08:23:13 -0400
commit2a5551a04a6705d20e16c54aca1f875198ae89ab (patch)
treebe52192003e7e6dcaa8b70351633c14b1b23a6c7
parent06bc89a9cee68a242dfd91497c1c7ab36ac30424 (diff)
downloadtame-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.rs89
-rw-r--r--tamer/src/ld/poc.rs24
-rw-r--r--tamer/src/obj/xmlo/reader.rs5
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,)
+ }
}
}
}