[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.master
parent
ef79a763ac
commit
21a0bdcce1
|
@ -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>>(
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue