REFACTOR: Rename our error::Error type to BuildError.

This commit is contained in:
Jeremy Wall 2018-11-07 18:24:44 -06:00
parent 39b6fea2fe
commit 15026423db
8 changed files with 59 additions and 75 deletions

6
Cargo.lock generated
View File

@ -1,6 +1,6 @@
[[package]]
name = "abortable_parser"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -228,7 +228,7 @@ dependencies = [
name = "ucg"
version = "0.2.2"
dependencies = [
"abortable_parser 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"abortable_parser 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bencher 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.26.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -285,7 +285,7 @@ dependencies = [
]
[metadata]
"checksum abortable_parser 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09cdf5378b5e4a079fa886e621519fcb2502d9cb008d3f76b92f61f3890d5906"
"checksum abortable_parser 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "685d99bbca3566d6b7f34b09d68039089ce4a36226f6f99f61ed8495850e3213"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f"

View File

@ -10,7 +10,7 @@ keywords = ["compiler", "config"]
license = "Apache-2.0"
[dependencies]
abortable_parser = "0.2.1"
abortable_parser = "~0.2.2"
clap = "~2.26.0"
serde_json = "~1.0.9"
simple-error = "0.1"

View File

@ -58,7 +58,7 @@ impl Val {
target: &Self,
file_name: &str,
pos: Position,
) -> Result<bool, error::Error> {
) -> Result<bool, error::BuildError> {
// first we do a type equality comparison
match (self, target) {
// Empty values are always equal.
@ -100,12 +100,12 @@ impl Val {
Ok(true)
}
}
(&Val::Macro(_), &Val::Macro(_)) => Err(error::Error::new(
(&Val::Macro(_), &Val::Macro(_)) => Err(error::BuildError::new(
format!("Macros are not comparable in file: {}", file_name),
error::ErrorType::TypeFail,
pos,
)),
(me, tgt) => Err(error::Error::new(
(me, tgt) => Err(error::BuildError::new(
format!("Types differ for {}, {} in file: {}", me, tgt, file_name),
error::ErrorType::TypeFail,
pos,

View File

@ -50,7 +50,7 @@ impl MacroDef {
// Error conditions. If the args don't match the length and types of the argdefs then this is
// macro call error.
if args.len() > self.argdefs.len() {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Macro called with too many args in file: {}",
root.to_string_lossy()
@ -125,7 +125,7 @@ macro_rules! eval_binary_expr {
return Ok(Rc::new($result));
}
val => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("Expected {} but got {}", $msg, val),
error::ErrorType::TypeFail,
$pos.clone(),
@ -163,7 +163,7 @@ impl<'a> Builder<'a> {
&Value::Str(ref s) => Ok(Rc::new(Val::Str(s.val.to_string()))),
&Value::Symbol(ref s) => {
self.lookup_sym(&(s.into()))
.ok_or(Box::new(error::Error::new(
.ok_or(Box::new(error::BuildError::new(
format!(
"Unable to find {} in file: {}",
s.val,
@ -263,7 +263,7 @@ impl<'a> Builder<'a> {
Some(val) => Ok(val),
}
}
Err(err) => Err(Box::new(error::Error::new(
Err(err) => Err(Box::new(error::BuildError::new(
format!("{}", err,),
error::ErrorType::ParseError,
(&input).into(),
@ -317,7 +317,7 @@ impl<'a> Builder<'a> {
};
let key = sym.into();
if self.build_output.contains_key(&key) {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("Binding for import name {} already exists", sym.fragment),
error::ErrorType::DuplicateBinding,
def.path.pos.clone(),
@ -333,7 +333,7 @@ impl<'a> Builder<'a> {
let name = &def.name;
match self.build_output.entry(name.into()) {
Entry::Occupied(e) => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Binding \
for {:?} already \
@ -366,7 +366,7 @@ impl<'a> Builder<'a> {
self.out_lock = Some((typ.fragment.to_string(), val.clone()));
Ok(val)
} else {
Err(Box::new(error::Error::new(
Err(Box::new(error::BuildError::new(
format!("You can only have one output per file."),
error::ErrorType::DuplicateBinding,
typ.pos.clone(),
@ -408,7 +408,7 @@ impl<'a> Builder<'a> {
if let Some(vv) = Self::find_in_fieldlist(next.1, fs) {
stack.push_back(vv.clone());
} else {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Unable to \
match element {} in selector \
@ -435,7 +435,7 @@ impl<'a> Builder<'a> {
if idx < elems.len() {
stack.push_back(elems[idx].clone());
} else {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Unable to \
match element {} in selector \
@ -495,7 +495,7 @@ impl<'a> Builder<'a> {
continue;
}
_ => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("{} is not a Tuple or List", vref),
error::ErrorType::TypeFail,
next.pos.clone(),
@ -526,7 +526,7 @@ impl<'a> Builder<'a> {
return Ok(Rc::new(Val::Str([s.to_string(), ss.clone()].concat())))
}
val => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Expected \
String \
@ -547,7 +547,7 @@ impl<'a> Builder<'a> {
return Ok(Rc::new(Val::List(new_vec)));
}
val => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Expected \
List \
@ -561,7 +561,7 @@ impl<'a> Builder<'a> {
}
},
ref expr => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("{} does not support the '+' operation", expr.type_name()),
error::ErrorType::Unsupported,
pos.clone(),
@ -584,7 +584,7 @@ impl<'a> Builder<'a> {
eval_binary_expr!(&Val::Float(ff), pos, right, Val::Float(f - ff), "Float")
}
ref expr => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("{} does not support the '-' operation", expr.type_name()),
error::ErrorType::Unsupported,
pos.clone(),
@ -607,7 +607,7 @@ impl<'a> Builder<'a> {
eval_binary_expr!(&Val::Float(ff), pos, right, Val::Float(f * ff), "Float")
}
ref expr => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("{} does not support the '*' operation", expr.type_name()),
error::ErrorType::Unsupported,
pos.clone(),
@ -630,7 +630,7 @@ impl<'a> Builder<'a> {
eval_binary_expr!(&Val::Float(ff), pos, right, Val::Float(f / ff), "Float")
}
ref expr => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("{} does not support the '*' operation", expr.type_name()),
error::ErrorType::Unsupported,
pos.clone(),
@ -677,7 +677,7 @@ impl<'a> Builder<'a> {
return Ok(Rc::new(Val::Boolean(l > r)));
}
}
Err(Box::new(error::Error::new(
Err(Box::new(error::BuildError::new(
format!(
"Incompatible types for numeric comparison {} with {}",
left.type_name(),
@ -700,7 +700,7 @@ impl<'a> Builder<'a> {
return Ok(Rc::new(Val::Boolean(l < r)));
}
}
Err(Box::new(error::Error::new(
Err(Box::new(error::BuildError::new(
format!(
"Incompatible types for numeric comparison {} with {}",
left.type_name(),
@ -727,7 +727,7 @@ impl<'a> Builder<'a> {
return Ok(Rc::new(Val::Boolean(l <= r)));
}
}
Err(Box::new(error::Error::new(
Err(Box::new(error::BuildError::new(
format!(
"Incompatible types for numeric comparison {} with {}",
left.type_name(),
@ -754,7 +754,7 @@ impl<'a> Builder<'a> {
return Ok(Rc::new(Val::Boolean(l >= r)));
}
}
Err(Box::new(error::Error::new(
Err(Box::new(error::BuildError::new(
format!(
"Incompatible types for numeric comparison {} with {}",
left.type_name(),
@ -802,7 +802,7 @@ impl<'a> Builder<'a> {
v.insert((count, val.clone()));
count += 1;
} else {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Duplicate \
field: {} in \
@ -829,7 +829,7 @@ impl<'a> Builder<'a> {
if src_val.1.type_equal(&expr_result) {
v.insert((src_val.0, expr_result));
} else {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Expected type {} for field {} but got {}",
src_val.1.type_name(),
@ -861,7 +861,7 @@ impl<'a> Builder<'a> {
}).collect(),
)));
}
Err(Box::new(error::Error::new(
Err(Box::new(error::BuildError::new(
format!("Expected Tuple got {}", v),
error::ErrorType::TypeFail,
def.selector.pos.clone(),
@ -898,7 +898,7 @@ impl<'a> Builder<'a> {
));
return Ok(Rc::new(Val::Tuple(fields)));
}
Err(Box::new(error::Error::new(
Err(Box::new(error::BuildError::new(
// We should pretty print the selectors here.
format!("{} is not a Macro", v),
error::ErrorType::TypeFail,
@ -909,7 +909,7 @@ impl<'a> Builder<'a> {
fn eval_macro_def(&self, def: &MacroDef) -> Result<Rc<Val>, Box<Error>> {
match def.validate_symbols() {
Ok(()) => Ok(Rc::new(Val::Macro(def.clone()))),
Err(set) => Err(Box::new(error::Error::new(
Err(set) => Err(Box::new(error::BuildError::new(
format!(
"Macro has the following \
undefined symbols: {:?}",
@ -939,7 +939,7 @@ impl<'a> Builder<'a> {
// Otherwise return the default.
return self.eval_expr(def_expr);
} else {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!(
"Expected String but got \
{} in Select expression",
@ -956,7 +956,7 @@ impl<'a> Builder<'a> {
let l = match maybe_list.as_ref() {
&Val::List(ref elems) => elems,
other => {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("Expected List as target but got {:?}", other.type_name()),
error::ErrorType::TypeFail,
def.target.pos().clone(),
@ -994,7 +994,7 @@ impl<'a> Builder<'a> {
}
return Ok(Rc::new(Val::List(out)));
}
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
format!("Expected macro but got {:?}", mac),
error::ErrorType::TypeFail,
def.pos.clone(),

View File

@ -22,7 +22,7 @@ use build::Val;
use build::Val::Tuple;
use convert;
use convert::traits::{Converter, Result};
use error::Error;
use error::BuildError;
use error::ErrorType;
pub struct ExecConverter {}
@ -43,7 +43,7 @@ impl ExecConverter {
if let &Tuple(ref fields) = v {
// We expect no more than three fields in our exec tuple.
if fields.len() > 3 {
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"Exec tuples must have no more than 3 fields",
ErrorType::TypeFail,
Position::new(0, 0, 0),
@ -56,7 +56,7 @@ impl ExecConverter {
// We require a command field in our exec tuple.
if name.val == "command" {
if command.is_some() {
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"There can only be one command field in an exec tuple",
ErrorType::TypeFail,
name.pos.clone(),
@ -66,7 +66,7 @@ impl ExecConverter {
command = Some(s);
continue;
}
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"The command field of an exec tuple must be a string",
ErrorType::TypeFail,
name.pos.clone(),
@ -76,7 +76,7 @@ impl ExecConverter {
if name.val == "env" {
if let &Val::Tuple(ref l) = val.as_ref() {
if env.is_some() {
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"There can only be one env field in an exec tuple",
ErrorType::TypeFail,
name.pos.clone(),
@ -85,7 +85,7 @@ impl ExecConverter {
env = Some(l);
continue;
}
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"The env field of an exec tuple must be a list",
ErrorType::TypeFail,
name.pos.clone(),
@ -95,7 +95,7 @@ impl ExecConverter {
if name.val == "args" {
if let &Val::List(ref l) = val.as_ref() {
if args.is_some() {
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"There can only be one args field of an exec tuple",
ErrorType::TypeFail,
name.pos.clone(),
@ -104,7 +104,7 @@ impl ExecConverter {
args = Some(l);
continue;
}
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"The args field of an exec tuple must be a list",
ErrorType::TypeFail,
name.pos.clone(),
@ -112,7 +112,7 @@ impl ExecConverter {
}
}
if command.is_none() {
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"An exec tuple must have a command field",
ErrorType::TypeFail,
Position::new(0, 0, 0),
@ -133,7 +133,7 @@ impl ExecConverter {
try!(write!(script, "{}=\"{}\"\n", name.val, s));
continue;
}
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"The env fields of an exec tuple must contain only string values",
ErrorType::TypeFail,
name.pos.clone(),
@ -154,7 +154,7 @@ impl ExecConverter {
}
&Val::Tuple(_) => try!(flag_converter.convert(v.clone(), &mut script)),
_ => {
return Err(Box::new(Error::new(
return Err(Box::new(BuildError::new(
"Exec args must be a list of strings or tuples of strings.",
ErrorType::TypeFail,
Position::new(0, 0, 0),
@ -170,7 +170,7 @@ impl ExecConverter {
return Ok(());
}
Err(Box::new(Error::new(
Err(Box::new(BuildError::new(
"Exec outputs must be of type Tuple",
ErrorType::TypeFail,
Position::new(0, 0, 0),

View File

@ -27,14 +27,11 @@ pub enum ErrorType {
// Build Errors
TypeFail,
DuplicateBinding,
IncompleteParsing,
Unsupported,
NoSuchSymbol,
BadArgLen,
FormatError,
// Parsing Errors
UnexpectedToken,
EmptyExpression,
ParseError,
AssertError,
}
@ -44,13 +41,10 @@ impl fmt::Display for ErrorType {
let name = match self {
&ErrorType::TypeFail => "TypeFail",
&ErrorType::DuplicateBinding => "DuplicateBinding",
&ErrorType::IncompleteParsing => "IncompleteParsing",
&ErrorType::Unsupported => "Unsupported",
&ErrorType::NoSuchSymbol => "NoSuchSymbol",
&ErrorType::BadArgLen => "BadArgLen",
&ErrorType::FormatError => "FormatError",
&ErrorType::UnexpectedToken => "UnexpectedToken",
&ErrorType::EmptyExpression => "EmptyExpression",
&ErrorType::ParseError => "ParseError",
&ErrorType::AssertError => "AssertError",
};
@ -59,16 +53,16 @@ impl fmt::Display for ErrorType {
}
/// Error defines an Error type for parsing and building UCG code.
pub struct Error {
pub struct BuildError {
pub err_type: ErrorType,
pub pos: Position,
pub msg: String,
_pkgonly: (),
}
impl Error {
impl BuildError {
pub fn new<S: Into<String>>(msg: S, t: ErrorType, pos: Position) -> Self {
Error {
BuildError {
err_type: t,
pos: pos,
msg: msg.into(),
@ -86,19 +80,19 @@ impl Error {
}
}
impl Debug for Error {
impl Debug for BuildError {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
self.render(w)
}
}
impl fmt::Display for Error {
impl fmt::Display for BuildError {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
self.render(w)
}
}
impl error::Error for Error {
impl error::Error for BuildError {
fn description(&self) -> &str {
&self.msg
}

View File

@ -45,7 +45,7 @@ impl<V: Into<String> + Clone> Formatter<V> {
for c in self.tmpl.chars() {
if c == '@' && !should_escape {
if count == self.args.len() {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
"Too few arguments to string \
formatter.",
error::ErrorType::FormatError,
@ -63,7 +63,7 @@ impl<V: Into<String> + Clone> Formatter<V> {
}
}
if self.args.len() != count {
return Err(Box::new(error::Error::new(
return Err(Box::new(error::BuildError::new(
"Too many arguments to string \
formatter.",
error::ErrorType::FormatError,

View File

@ -846,7 +846,7 @@ make_fn!(
name => wrap_err!(match_type!(BAREWORD), "Expected name for binding"),
_ => punct!("="),
// TODO(jwall): Wrap this error with an appropriate abortable_parser::Error
val => wrap_err!(trace_nom!(expression), "Expected Expression"),
val => with_err!(trace_nom!(expression), "Expected Expression"),
_ => punct!(";"),
(tuple_to_let(name, val))
)
@ -904,7 +904,7 @@ make_fn!(
do_each!(
_ => word!("out"),
typ => wrap_err!(must!(match_type!(BAREWORD)), "Expected converter name"),
expr => wrap_err!(must!(expression), "Expected Expression to export"),
expr => with_err!(must!(expression), "Expected Expression to export"),
_ => must!(punct!(";")),
(Statement::Output(typ.clone(), expr.clone()))
)
@ -937,21 +937,11 @@ pub fn parse<'a>(input: OffsetStrIter<'a>) -> std::result::Result<Vec<Statement>
}
match statement(i.clone()) {
Result::Abort(e) => {
let err = abortable_parser::Error::caused_by(
"Statement Parse Error",
Box::new(e),
Box::new(i.clone()),
);
let ctx_err = StackPrinter { err: err };
let ctx_err = StackPrinter { err: e };
return Err(format!("{}", ctx_err));
}
Result::Fail(e) => {
let err = abortable_parser::Error::caused_by(
"Statement Parse Error",
Box::new(e),
Box::new(i.clone()),
);
let ctx_err = StackPrinter { err: err };
let ctx_err = StackPrinter { err: e };
return Err(format!("{}", ctx_err));
}
Result::Incomplete(_ei) => {