From fde27fe7c2b82af7a881385f338a4649247d7d3d Mon Sep 17 00:00:00 2001 From: dalance Date: Thu, 23 Jan 2020 16:36:28 +0900 Subject: [PATCH] Change error type --- CHANGELOG.md | 1 + sv-parser-error/Cargo.toml | 2 +- sv-parser-error/src/lib.rs | 99 ++++++++-------------------------- sv-parser-pp/Cargo.toml | 1 - sv-parser-pp/src/preprocess.rs | 57 +++++++++----------- sv-parser/examples/parse_sv.rs | 14 +++-- sv-parser/src/lib.rs | 10 ++-- 7 files changed, 64 insertions(+), 120 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7918e52..e009c05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.4.20...Unreleased) - ReleaseDate +* [Changed] from `sv-parser-error::ErrorKind` to `sv-parser-error::Error` * [Changed] Refine parse_sv -t option * [Added] Display trait of SyntaxTree diff --git a/sv-parser-error/Cargo.toml b/sv-parser-error/Cargo.toml index 7b3721d..ca4a860 100644 --- a/sv-parser-error/Cargo.toml +++ b/sv-parser-error/Cargo.toml @@ -14,4 +14,4 @@ edition = "2018" disable-tag = true [dependencies] -failure = "0.1.5" +thiserror = "1.0" diff --git a/sv-parser-error/src/lib.rs b/sv-parser-error/src/lib.rs index f6e7372..638b3f8 100644 --- a/sv-parser-error/src/lib.rs +++ b/sv-parser-error/src/lib.rs @@ -1,88 +1,35 @@ -use failure::{Backtrace, Context, Fail}; -use std::fmt; -use std::fmt::Display; -use std::io::Error as IOError; use std::path::PathBuf; +use thiserror::Error; // ----------------------------------------------------------------------------- -#[derive(Fail, Debug)] -pub enum ErrorKind { - #[fail(display = "IO error")] - Io, - #[fail(display = "File error: {:?}", _0)] - File(PathBuf), - #[fail(display = "Include error")] - Include, - #[fail(display = "Parse error: {:?}", _0)] +#[derive(Error, Debug)] +pub enum Error { + #[error("IO error")] + Io(#[from] std::io::Error), + #[error("File error: {path:?}")] + File { + #[source] + source: std::io::Error, + path: PathBuf, + }, + #[error("Include error")] + Include { + #[from] + source: Box, + }, + #[error("Parse error: {0:?}")] Parse(Option<(PathBuf, usize)>), - #[fail(display = "Preprocess error")] + #[error("Preprocess error")] Preprocess, - #[fail(display = "Define argument not found: {}", _0)] + #[error("Define argument not found: {0}")] DefineArgNotFound(String), - #[fail(display = "Define not found: {}", _0)] + #[error("Define not found: {0}")] DefineNotFound(String), - #[fail(display = "Define must have argument")] + #[error("Define must have argument")] DefineNoArgs, - #[fail(display = "Exceed recursive limit")] + #[error("Exceed recursive limit")] ExceedRecursiveLimit, - #[fail(display = "Include line can't have other items")] + #[error("Include line can't have other items")] IncludeLine, } - -// ----------------------------------------------------------------------------- - -#[derive(Debug)] -pub struct Error { - inner: Context, -} - -impl Fail for Error { - fn cause(&self) -> Option<&dyn Fail> { - self.inner.cause() - } - - fn backtrace(&self) -> Option<&Backtrace> { - self.inner.backtrace() - } -} - -impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.inner, f) - } -} - -impl Error { - pub fn new(inner: Context) -> Error { - Error { inner } - } - - pub fn kind(&self) -> &ErrorKind { - self.inner.get_context() - } -} - -impl From for Error { - fn from(kind: ErrorKind) -> Error { - Error { - inner: Context::new(kind), - } - } -} - -impl From> for Error { - fn from(inner: Context) -> Error { - Error { inner } - } -} - -// ----------------------------------------------------------------------------- - -impl From for Error { - fn from(error: IOError) -> Error { - Error { - inner: error.context(ErrorKind::Io), - } - } -} diff --git a/sv-parser-pp/Cargo.toml b/sv-parser-pp/Cargo.toml index 4b0d204..b4545bc 100644 --- a/sv-parser-pp/Cargo.toml +++ b/sv-parser-pp/Cargo.toml @@ -18,7 +18,6 @@ default = [] trace = ["sv-parser-parser/trace"] [dependencies] -failure = "0.1.5" nom = "5.0.0" nom-greedyerror = "0.1.0" sv-parser-error = {version = "^0.4.20", path = "../sv-parser-error"} diff --git a/sv-parser-pp/src/preprocess.rs b/sv-parser-pp/src/preprocess.rs index 7d5df37..025299c 100644 --- a/sv-parser-pp/src/preprocess.rs +++ b/sv-parser-pp/src/preprocess.rs @@ -1,5 +1,4 @@ use crate::range::Range; -use failure::ResultExt; use nom::combinator::all_consuming; use nom_greedyerror::error_position; use std::collections::{BTreeMap, HashMap}; @@ -7,7 +6,7 @@ use std::convert::TryInto; use std::fs::File; use std::io::{BufReader, Read}; use std::path::{Path, PathBuf}; -use sv_parser_error::{Error, ErrorKind}; +use sv_parser_error::Error; use sv_parser_parser::{pp_parser, Span, SpanInfo}; use sv_parser_syntaxtree::{ IncludeCompilerDirective, Locate, NodeEvent, RefNode, SourceDescription, TextMacroUsage, @@ -120,8 +119,10 @@ pub fn preprocess, U: AsRef>( pre_defines: &Defines, include_paths: &[U], ) -> Result<(PreprocessedText, Defines), Error> { - let f = - File::open(path.as_ref()).context(ErrorKind::File(PathBuf::from(path.as_ref())).into())?; + let f = File::open(path.as_ref()).map_err(|x| Error::File { + source: x, + path: PathBuf::from(path.as_ref()), + })?; let mut reader = BufReader::new(f); let mut s = String::new(); reader.read_to_string(&mut s)?; @@ -149,19 +150,19 @@ pub fn preprocess_str, U: AsRef>( let span = Span::new_extra(&s, SpanInfo::default()); let (_, pp_text) = all_consuming(pp_parser)(span).map_err(|x| match x { - nom::Err::Incomplete(_) => ErrorKind::Parse(None), + nom::Err::Incomplete(_) => Error::Parse(None), nom::Err::Error(e) => { if let Some(pos) = error_position(&e) { - ErrorKind::Parse(Some((PathBuf::from(path.as_ref()), pos))) + Error::Parse(Some((PathBuf::from(path.as_ref()), pos))) } else { - ErrorKind::Parse(None) + Error::Parse(None) } } nom::Err::Failure(e) => { if let Some(pos) = error_position(&e) { - ErrorKind::Parse(Some((PathBuf::from(path.as_ref()), pos))) + Error::Parse(Some((PathBuf::from(path.as_ref()), pos))) } else { - ErrorKind::Parse(None) + Error::Parse(None) } } })?; @@ -186,7 +187,7 @@ pub fn preprocess_str, U: AsRef>( let locate: Locate = x.try_into().unwrap(); if let Some(last_include_line) = last_include_line { if last_include_line == locate.line { - return Err(ErrorKind::IncludeLine.into()); + return Err(Error::IncludeLine); } } } @@ -194,7 +195,7 @@ pub fn preprocess_str, U: AsRef>( let locate: Locate = x.try_into().unwrap(); if let Some(last_include_line) = last_include_line { if last_include_line == locate.line { - return Err(ErrorKind::IncludeLine.into()); + return Err(Error::IncludeLine); } } } @@ -361,7 +362,7 @@ pub fn preprocess_str, U: AsRef>( if let Some(last_item_line) = last_item_line { if last_item_line == locate.line { - return Err(ErrorKind::IncludeLine.into()); + return Err(Error::IncludeLine); } } @@ -408,7 +409,9 @@ pub fn preprocess_str, U: AsRef>( } } let (include, new_defines) = - preprocess(path, &defines, include_paths).context(ErrorKind::Include)?; + preprocess(path, &defines, include_paths).map_err(|x| Error::Include { + source: Box::new(x), + })?; defines = new_defines; ret.merge(include); } @@ -518,7 +521,7 @@ fn resolve_text_macro_usage, U: AsRef>( let id = identifier((&name.nodes.0).into(), &s).unwrap(); if resolve_depth > RECURSIVE_LIMIT { - return Err(ErrorKind::ExceedRecursiveLimit.into()); + return Err(Error::ExceedRecursiveLimit); } let mut actual_args = Vec::new(); @@ -542,7 +545,7 @@ fn resolve_text_macro_usage, U: AsRef>( let mut arg_map = HashMap::new(); if !define.arguments.is_empty() && no_args { - return Err(ErrorKind::DefineNoArgs.into()); + return Err(Error::DefineNoArgs); } for (i, (arg, default)) in define.arguments.iter().enumerate() { @@ -559,7 +562,7 @@ fn resolve_text_macro_usage, U: AsRef>( if let Some(default) = default { default } else { - return Err(ErrorKind::DefineArgNotFound(String::from(arg)).into()); + return Err(Error::DefineArgNotFound(String::from(arg))); } } }; @@ -606,7 +609,7 @@ fn resolve_text_macro_usage, U: AsRef>( } else if let Some(_) = define { Ok(None) } else { - Err(ErrorKind::DefineNotFound(String::from(id)).into()) + Err(Error::DefineNotFound(String::from(id))) } } @@ -773,39 +776,27 @@ endmodule #[test] fn test7() { let ret = preprocess(get_testcase("test7.sv"), &HashMap::new(), &[] as &[String]); - assert_eq!( - format!("{:?}", ret), - "Err(Error { inner: \n\nExceed recursive limit })" - ); + assert_eq!(format!("{:?}", ret), "Err(ExceedRecursiveLimit)"); } #[test] fn test8() { let ret = preprocess(get_testcase("test8.sv"), &HashMap::new(), &[] as &[String]); - assert_eq!( - format!("{:?}", ret), - "Err(Error { inner: \n\nExceed recursive limit })" - ); + assert_eq!(format!("{:?}", ret), "Err(ExceedRecursiveLimit)"); } #[test] fn test9() { let include_paths = [get_testcase("")]; let ret = preprocess(get_testcase("test9.sv"), &HashMap::new(), &include_paths); - assert_eq!( - format!("{:?}", ret), - "Err(Error { inner: \n\nInclude line can\'t have other items })" - ); + assert_eq!(format!("{:?}", ret), "Err(IncludeLine)"); } #[test] fn test10() { let include_paths = [get_testcase("")]; let ret = preprocess(get_testcase("test10.sv"), &HashMap::new(), &include_paths); - assert_eq!( - format!("{:?}", ret), - "Err(Error { inner: \n\nInclude line can\'t have other items })" - ); + assert_eq!(format!("{:?}", ret), "Err(IncludeLine)"); } #[test] diff --git a/sv-parser/examples/parse_sv.rs b/sv-parser/examples/parse_sv.rs index a7f5d45..556336d 100644 --- a/sv-parser/examples/parse_sv.rs +++ b/sv-parser/examples/parse_sv.rs @@ -1,11 +1,12 @@ use std::collections::HashMap; +use std::error::Error as StdError; use std::fs::File; use std::io::Read; use std::path::PathBuf; use std::{cmp, process}; use structopt::StructOpt; use sv_parser::parse_sv; -use sv_parser_error::ErrorKind; +use sv_parser_error::Error; use sv_parser_pp::preprocess::preprocess; #[derive(StructOpt)] @@ -54,13 +55,18 @@ fn main() { } } Err(x) => { - match x.kind() { - ErrorKind::Parse(Some((origin_path, origin_pos))) => { + match x { + Error::Parse(Some((origin_path, origin_pos))) => { println!("parse failed: {:?}", path); - print_parse_error(origin_path, origin_pos); + print_parse_error(&origin_path, &origin_pos); } x => { println!("parse failed: {:?} ({})", path, x); + let mut err = x.source(); + while let Some(x) = err { + println!(" Caused by {}", x); + err = x.source(); + } } } exit = 1; diff --git a/sv-parser/src/lib.rs b/sv-parser/src/lib.rs index 86998a0..70b284a 100644 --- a/sv-parser/src/lib.rs +++ b/sv-parser/src/lib.rs @@ -5,7 +5,7 @@ use nom_greedyerror::error_position; use std::collections::HashMap; use std::fmt; use std::path::{Path, PathBuf}; -pub use sv_parser_error::{Error, ErrorKind}; +pub use sv_parser_error::Error; use sv_parser_parser::{lib_parser, sv_parser, Span, SpanInfo}; pub use sv_parser_pp::preprocess::{ preprocess, preprocess_str, Define, DefineText, Defines, PreprocessedText, @@ -125,7 +125,7 @@ pub fn parse_sv, U: AsRef>( } else { None }; - Err(ErrorKind::Parse(origin).into()) + Err(Error::Parse(origin)) } } } @@ -162,7 +162,7 @@ pub fn parse_sv_str, U: AsRef>( } else { None }; - Err(ErrorKind::Parse(origin).into()) + Err(Error::Parse(origin)) } } } @@ -198,7 +198,7 @@ pub fn parse_lib, U: AsRef>( } else { None }; - Err(ErrorKind::Parse(origin).into()) + Err(Error::Parse(origin)) } } } @@ -235,7 +235,7 @@ pub fn parse_lib_str, U: AsRef>( } else { None }; - Err(ErrorKind::Parse(origin).into()) + Err(Error::Parse(origin)) } } }