Add annotate_snippets for better parsing errors (#477)
Adds nicer errors for Podlang code, using the `annotate_snippets` crate, the same crate used by the Rust compiler to generate contextual errors. This prints a short snippet of the code containing the error within the error message, highlighting the part that needs to be fixed. It also includes a change to the `load_module` function, changing a `Vec` function argument to a slice.
This commit is contained in:
parent
acab26e5c1
commit
09d67de989
11 changed files with 612 additions and 40 deletions
|
|
@ -26,6 +26,7 @@
|
|||
//! Large predicates are automatically split into chains of smaller predicates;
|
||||
//! `apply_predicate` handles this transparently.
|
||||
//!
|
||||
pub mod diagnostics;
|
||||
pub mod error;
|
||||
pub mod frontend_ast;
|
||||
pub mod frontend_ast_lower;
|
||||
|
|
@ -37,7 +38,8 @@ pub mod pretty_print;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
pub use error::LangError;
|
||||
pub use diagnostics::render_error;
|
||||
pub use error::{LangError, LangErrorKind};
|
||||
pub use frontend_ast_split::{SplitChainInfo, SplitChainPiece, SplitResult};
|
||||
pub use module::{Module, MultiOperationError};
|
||||
pub use parser::{parse_podlang, Pairs, ParseError, Rule};
|
||||
|
|
@ -57,7 +59,17 @@ pub fn load_module(
|
|||
source: &str,
|
||||
name: &str,
|
||||
params: &Params,
|
||||
available_modules: Vec<Arc<Module>>,
|
||||
available_modules: &[Arc<Module>],
|
||||
) -> Result<Module, LangError> {
|
||||
load_module_inner(source, name, params, available_modules)
|
||||
.map_err(|e| e.with_source(source.to_string(), None))
|
||||
}
|
||||
|
||||
fn load_module_inner(
|
||||
source: &str,
|
||||
name: &str,
|
||||
params: &Params,
|
||||
available_modules: &[Arc<Module>],
|
||||
) -> Result<Module, LangError> {
|
||||
let pairs = parse_podlang(source)?;
|
||||
let document_pair = pairs
|
||||
|
|
@ -89,6 +101,15 @@ pub fn parse_request(
|
|||
source: &str,
|
||||
params: &Params,
|
||||
available_modules: &[Arc<Module>],
|
||||
) -> Result<PodRequest, LangError> {
|
||||
parse_request_inner(source, params, available_modules)
|
||||
.map_err(|e| e.with_source(source.to_string(), None))
|
||||
}
|
||||
|
||||
fn parse_request_inner(
|
||||
source: &str,
|
||||
params: &Params,
|
||||
available_modules: &[Arc<Module>],
|
||||
) -> Result<PodRequest, LangError> {
|
||||
let pairs = parse_podlang(source)?;
|
||||
let document_pair = pairs
|
||||
|
|
@ -160,7 +181,7 @@ mod tests {
|
|||
"#;
|
||||
|
||||
let params = Params::default();
|
||||
let module = load_module(input, "test_module", ¶ms, vec![])?;
|
||||
let module = load_module(input, "test_module", ¶ms, &[])?;
|
||||
|
||||
assert_eq!(module.batch.predicates().len(), 1);
|
||||
|
||||
|
|
@ -235,7 +256,7 @@ mod tests {
|
|||
"#;
|
||||
|
||||
let params = Params::default();
|
||||
let module = load_module(input, "test_module", ¶ms, vec![])?;
|
||||
let module = load_module(input, "test_module", ¶ms, &[])?;
|
||||
|
||||
assert_eq!(module.batch.predicates().len(), 1);
|
||||
|
||||
|
|
@ -281,7 +302,7 @@ mod tests {
|
|||
"#;
|
||||
|
||||
let params = Params::default();
|
||||
let module = Arc::new(load_module(module_input, "my_module", ¶ms, vec![])?);
|
||||
let module = Arc::new(load_module(module_input, "my_module", ¶ms, &[])?);
|
||||
|
||||
assert_eq!(module.batch.predicates().len(), 1);
|
||||
|
||||
|
|
@ -330,7 +351,7 @@ mod tests {
|
|||
"#;
|
||||
|
||||
let params = Params::default();
|
||||
let module = Arc::new(load_module(module_input, "some_module", ¶ms, vec![])?);
|
||||
let module = Arc::new(load_module(module_input, "some_module", ¶ms, &[])?);
|
||||
|
||||
let module_hash = module.id().encode_hex::<String>();
|
||||
|
||||
|
|
@ -585,7 +606,7 @@ mod tests {
|
|||
)
|
||||
"#;
|
||||
|
||||
let module = load_module(input, "ethdos", ¶ms, vec![])?;
|
||||
let module = load_module(input, "ethdos", ¶ms, &[])?;
|
||||
|
||||
assert_eq!(
|
||||
module.batch.predicates().len(),
|
||||
|
|
@ -855,7 +876,7 @@ mod tests {
|
|||
);
|
||||
|
||||
// 3. Load as module
|
||||
let module = load_module(&input, "test", ¶ms, vec![extmod])?;
|
||||
let module = load_module(&input, "test", ¶ms, &[extmod])?;
|
||||
|
||||
assert_eq!(
|
||||
module.batch.predicates().len(),
|
||||
|
|
@ -1011,8 +1032,8 @@ mod tests {
|
|||
|
||||
assert!(result.is_err());
|
||||
|
||||
match result.err().unwrap() {
|
||||
LangError::Validation(e) => match *e {
|
||||
match result.err().unwrap().kind {
|
||||
LangErrorKind::Validation(e) => match *e {
|
||||
frontend_ast_validate::ValidationError::ModuleNotFound { name, .. } => {
|
||||
// The error now carries the hex-formatted hash
|
||||
assert_eq!(name, fake_hash);
|
||||
|
|
@ -1034,12 +1055,12 @@ mod tests {
|
|||
)
|
||||
"#;
|
||||
|
||||
let result = load_module(input, "test", ¶ms, vec![]);
|
||||
let result = load_module(input, "test", ¶ms, &[]);
|
||||
|
||||
assert!(result.is_err());
|
||||
|
||||
match result.err().unwrap() {
|
||||
LangError::Validation(e) => match *e {
|
||||
match result.err().unwrap().kind {
|
||||
LangErrorKind::Validation(e) => match *e {
|
||||
frontend_ast_validate::ValidationError::UndefinedWildcard {
|
||||
name,
|
||||
pred_name,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue