[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.
master
Joseph Frazer 2020-03-07 10:28:39 -05:00
parent 06bc89a9ce
commit 2a5551a04a
3 changed files with 106 additions and 12 deletions

View File

@ -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);

View File

@ -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());
}
};
}

View File

@ -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,)
}
}
}
}