Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
path: root/tamer
diff options
context:
space:
mode:
authorMike Gerwitz <mike.gerwitz@ryansg.com>2020-04-20 15:39:22 -0400
committerMike Gerwitz <mike.gerwitz@ryansg.com>2020-04-28 09:06:25 -0400
commit21a0bdcce1dd36f59578e2eb8f4207e769f028eb (patch)
treeb1c5f98f736e84dde2654d1d925f6122ad395c28 /tamer
parentef79a763ace14cccc19b49262c4769ff25e0fa54 (diff)
downloadtame-21a0bdcce1dd36f59578e2eb8f4207e769f028eb.tar.gz
tame-21a0bdcce1dd36f59578e2eb8f4207e769f028eb.tar.bz2
tame-21a0bdcce1dd36f59578e2eb8f4207e769f028eb.zip
[DEV-7084] TAMER: AsgBuilderError: Introduce proper error variants
This is a union (sum type) of three other errors types, plus errors specific to this builder. This commit does a good job demonstrating the boilerplate, as well as a need for additional context (in the case of `IdentKindError`), that we'll want to work on abstracting away.
Diffstat (limited to 'tamer')
-rw-r--r--tamer/src/ld/poc.rs6
-rw-r--r--tamer/src/obj/xmlo/asg_builder.rs100
-rw-r--r--tamer/src/obj/xmlo/reader.rs5
3 files changed, 89 insertions, 22 deletions
diff --git a/tamer/src/ld/poc.rs b/tamer/src/ld/poc.rs
index 32a965a..0515a76 100644
--- a/tamer/src/ld/poc.rs
+++ b/tamer/src/ld/poc.rs
@@ -29,7 +29,7 @@ use crate::ir::asg::{
SortableAsg,
};
use crate::obj::xmle::writer::XmleWriter;
-use crate::obj::xmlo::reader::{XmloError, XmloReader};
+use crate::obj::xmlo::reader::XmloReader;
use crate::obj::xmlo::{AsgBuilder, AsgBuilderState};
use crate::sym::{DefaultInterner, Interner, Symbol};
use fxhash::FxBuildHasher;
@@ -148,11 +148,11 @@ fn load_xmlo<'a, 'i, I: Interner<'i>, P: AsRef<Path>>(
fn get_ident<'a, 'i>(
depgraph: &'a LinkerAsg<'i>,
name: &'i Symbol<'i>,
-) -> Result<&'a IdentObject<'i>, XmloError> {
+) -> Result<&'a IdentObject<'i>, String> {
depgraph
.lookup(name)
.and_then(|id| depgraph.get(id))
- .ok_or(XmloError::MissingFragment(String::from(name as &str)))
+ .ok_or(format!("missing identifier: {}", name))
}
fn output_xmle<'a, 'i, I: Interner<'i>>(
diff --git a/tamer/src/obj/xmlo/asg_builder.rs b/tamer/src/obj/xmlo/asg_builder.rs
index 24c51fe..da91e19 100644
--- a/tamer/src/obj/xmlo/asg_builder.rs
+++ b/tamer/src/obj/xmlo/asg_builder.rs
@@ -19,17 +19,18 @@
use super::reader::{XmloError, XmloEvent, XmloResult};
use crate::ir::asg::{
- Asg, IdentKind, IdentObjectState, IndexType, ObjectRef, Source,
+ Asg, AsgError, IdentKind, IdentKindError, IdentObjectState, IndexType,
+ ObjectRef, Source,
};
use crate::sym::Symbol;
use std::collections::HashSet;
use std::convert::TryInto;
use std::error::Error;
+use std::fmt::Display;
use std::hash::BuildHasher;
-// TODO error type
pub type Result<'i, S, Ix> =
- std::result::Result<AsgBuilderState<'i, S, Ix>, Box<dyn Error>>;
+ std::result::Result<AsgBuilderState<'i, S, Ix>, AsgBuilderError<Ix>>;
#[derive(Debug, Default)]
pub struct AsgBuilderState<'i, S, Ix>
@@ -99,10 +100,7 @@ where
} else {
let owned = attrs.src.is_none();
let extern_ = attrs.extern_;
-
- let kindval = (&attrs).try_into().map_err(|err| {
- format!("sym `{}` attrs error: {}", sym, err)
- })?;
+ let kindval = (&attrs).try_into()?;
let mut src: Source = attrs.into();
@@ -133,10 +131,9 @@ where
}
XmloEvent::Fragment(sym, text) => {
- let frag =
- self.lookup(sym).ok_or(XmloError::MissingFragment(
- String::from("missing fragment"),
- ))?;
+ let frag = self.lookup(sym).ok_or(
+ AsgBuilderError::MissingFragmentIdent(sym.to_string()),
+ )?;
self.set_fragment(frag, text)?;
}
@@ -148,11 +145,86 @@ where
}
if let Some(elig_sym) = elig {
- state.roots.push(self.lookup(elig_sym).expect(
- "internal error: package elig references nonexistant symbol",
- ));
+ state
+ .roots
+ .push(self.lookup(elig_sym).ok_or(
+ AsgBuilderError::BadEligRef(elig_sym.to_string()),
+ )?);
}
Ok(state)
}
}
+
+/// Error populating graph with [`XmloResult`]-derived data.
+#[derive(Debug)]
+pub enum AsgBuilderError<Ix: IndexType> {
+ /// Error with the source `xmlo` file.
+ XmloError(XmloError),
+
+ /// Error parsing into [`IdentKind`].
+ IdentKindError(IdentKindError),
+
+ /// [`Asg`] operation error.
+ AsgError(AsgError<Ix>),
+
+ /// Fragment encountered for an unknown identifier.
+ MissingFragmentIdent(String),
+
+ /// Eligibility classification references unknown identifier.
+ ///
+ /// This is generated by the compiler and so should never happen.
+ /// (That's not to say that it won't, but it shouldn't.)
+ BadEligRef(String),
+}
+
+impl<Ix: IndexType> Display for AsgBuilderError<Ix> {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self {
+ Self::XmloError(e) => e.fmt(fmt),
+ Self::IdentKindError(e) => e.fmt(fmt),
+ Self::AsgError(e) => e.fmt(fmt),
+
+ Self::MissingFragmentIdent(name) => write!(
+ fmt,
+ "encountered fragment for unknown identifier `{}`",
+ name,
+ ),
+
+ Self::BadEligRef(name) => write!(
+ fmt,
+ "internal error: package elig references nonexistant symbol `{}`",
+ name,
+ ),
+ }
+ }
+}
+
+impl<Ix: IndexType> From<XmloError> for AsgBuilderError<Ix> {
+ fn from(src: XmloError) -> Self {
+ Self::XmloError(src)
+ }
+}
+
+impl<Ix: IndexType> From<IdentKindError> for AsgBuilderError<Ix> {
+ fn from(src: IdentKindError) -> Self {
+ Self::IdentKindError(src)
+ }
+}
+
+impl<Ix: IndexType> From<AsgError<Ix>> for AsgBuilderError<Ix> {
+ fn from(src: AsgError<Ix>) -> Self {
+ Self::AsgError(src)
+ }
+}
+
+impl<Ix: IndexType> Error for AsgBuilderError<Ix> {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match self {
+ Self::XmloError(e) => Some(e),
+ Self::IdentKindError(e) => Some(e),
+ Self::AsgError(e) => Some(e),
+ _ => None,
+ }
+ }
+}
diff --git a/tamer/src/obj/xmlo/reader.rs b/tamer/src/obj/xmlo/reader.rs
index 491d29e..52098a1 100644
--- a/tamer/src/obj/xmlo/reader.rs
+++ b/tamer/src/obj/xmlo/reader.rs
@@ -796,8 +796,6 @@ 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 {
@@ -845,9 +843,6 @@ impl Display for XmloError {
"fragment found, but missing text for symbol `{}`",
symname,
),
- XmloError::MissingFragment(symname) => {
- write!(fmt, "fragment not found `{}`", symname,)
- }
}
}
}