From 4841d62d76a9be7f9d2426ab2773a05eb72c7d52 Mon Sep 17 00:00:00 2001 From: JT Date: Tue, 21 Sep 2021 16:03:06 +1200 Subject: [PATCH] Add some improvements to errors --- TODO.md | 3 +- crates/nu-parser/src/errors.rs | 4 +- crates/nu-parser/src/parser.rs | 44 ++++++++++++++++--- crates/nu-parser/src/type_check.rs | 3 +- crates/nu-protocol/src/engine/engine_state.rs | 27 ++++++++---- src/main.rs | 10 +---- 6 files changed, 65 insertions(+), 26 deletions(-) diff --git a/TODO.md b/TODO.md index 3704ed76b..bcf501fb0 100644 --- a/TODO.md +++ b/TODO.md @@ -21,6 +21,7 @@ - [x] Simple completions - [x] Detecting `$it` currently only looks at top scope but should find any free `$it` in the expression (including subexprs) - [x] Signature needs to make parameters visible in scope before block is parsed +- [ ] Support for `$in` - [ ] Value serialization - [ ] Handling rows with missing columns during a cell path - [ ] Error shortcircuit (stopping on first error) @@ -28,7 +29,7 @@ - [ ] operator overflow - [ ] finish operator type-checking - [ ] Source -- [ ] Autoenv +- [ ] Overlays (replacement for `autoenv`) - [ ] Externals - [ ] let [first, rest] = [1, 2, 3] (design question: how do you pattern match a table?) diff --git a/crates/nu-parser/src/errors.rs b/crates/nu-parser/src/errors.rs index 7de6db499..1506723ee 100644 --- a/crates/nu-parser/src/errors.rs +++ b/crates/nu-parser/src/errors.rs @@ -78,9 +78,9 @@ pub enum ParseError { #[diagnostic(code(nu::parser::non_utf8), url(docsrs))] NonUtf8(#[label = "non-UTF8 code"] Span), - #[error("Unknown flag.")] + #[error("The `{0}` command doesn't have flag `{1}`.")] #[diagnostic(code(nu::parser::unknown_flag), url(docsrs))] - UnknownFlag(#[label = "unknown flag"] Span), + UnknownFlag(String, String, #[label = "unknown flag"] Span), #[error("Unknown type.")] #[diagnostic(code(nu::parser::unknown_type), url(docsrs))] diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 7e66e760a..71b2005fa 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -160,9 +160,13 @@ fn parse_long_flag( } } else { ( - Some(long_name), + Some(long_name.clone()), None, - Some(ParseError::UnknownFlag(arg_span)), + Some(ParseError::UnknownFlag( + sig.name.clone(), + long_name.clone(), + arg_span, + )), ) } } else { @@ -214,17 +218,45 @@ fn parse_short_flags( if String::from_utf8_lossy(arg_contents).parse::().is_ok() { return (None, None); } else if let Some(first) = unmatched_short_flags.first() { - error = error.or(Some(ParseError::UnknownFlag(*first))); + let contents = working_set.get_span_contents(*first); + error = error.or_else(|| { + Some(ParseError::UnknownFlag( + sig.name.clone(), + format!("-{}", String::from_utf8_lossy(contents).to_string()), + *first, + )) + }); } } else if let Some(first) = unmatched_short_flags.first() { - error = error.or(Some(ParseError::UnknownFlag(*first))); + let contents = working_set.get_span_contents(*first); + error = error.or_else(|| { + Some(ParseError::UnknownFlag( + sig.name.clone(), + format!("-{}", String::from_utf8_lossy(contents).to_string()), + *first, + )) + }); } } else if let Some(first) = unmatched_short_flags.first() { - error = error.or(Some(ParseError::UnknownFlag(*first))); + let contents = working_set.get_span_contents(*first); + error = error.or_else(|| { + Some(ParseError::UnknownFlag( + sig.name.clone(), + format!("-{}", String::from_utf8_lossy(contents).to_string()), + *first, + )) + }); } } else if !unmatched_short_flags.is_empty() { if let Some(first) = unmatched_short_flags.first() { - error = error.or(Some(ParseError::UnknownFlag(*first))); + let contents = working_set.get_span_contents(*first); + error = error.or_else(|| { + Some(ParseError::UnknownFlag( + sig.name.clone(), + format!("-{}", String::from_utf8_lossy(contents).to_string()), + *first, + )) + }); } } diff --git a/crates/nu-parser/src/type_check.rs b/crates/nu-parser/src/type_check.rs index 58167b47f..fa07f755d 100644 --- a/crates/nu-parser/src/type_check.rs +++ b/crates/nu-parser/src/type_check.rs @@ -32,6 +32,7 @@ pub fn math_result_type( (Type::Unknown, _) => (Type::Unknown, None), (_, Type::Unknown) => (Type::Unknown, None), (Type::Int, _) => { + let ty = rhs.ty.clone(); *rhs = Expression::garbage(rhs.span); ( Type::Unknown, @@ -40,7 +41,7 @@ pub fn math_result_type( lhs.span, lhs.ty.clone(), rhs.span, - rhs.ty.clone(), + ty, )), ) } diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 6f7e1f2d6..03c816df8 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -574,14 +574,25 @@ impl<'a> miette::SourceCode for &StateWorkingSet<'a> { let content_span = span_contents.span(); // Back to "global" indexing let retranslated = (content_span.offset() + start, content_span.len()).into(); - return Ok(Box::new(miette::MietteSpanContents::new_named( - filename.clone(), - span_contents.data(), - retranslated, - span_contents.line(), - span_contents.column(), - span_contents.line_count(), - ))); + + if filename == "" { + return Ok(Box::new(miette::MietteSpanContents::new( + span_contents.data(), + retranslated, + span_contents.line(), + span_contents.column(), + span_contents.line_count(), + ))); + } else { + return Ok(Box::new(miette::MietteSpanContents::new_named( + filename.clone(), + span_contents.data(), + retranslated, + span_contents.line(), + span_contents.column(), + span_contents.line_count(), + ))); + } } } Err(miette::MietteError::OutOfBounds) diff --git a/src/main.rs b/src/main.rs index 510cddfdd..be64627bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,7 +71,6 @@ fn main() -> Result<()> { )); let prompt = DefaultPrompt::new(1); - let mut current_line = 1; let stack = nu_protocol::engine::Stack::new(); loop { @@ -97,12 +96,8 @@ fn main() -> Result<()> { let (block, delta) = { let engine_state = engine_state.borrow(); let mut working_set = StateWorkingSet::new(&*engine_state); - let (output, err) = parse( - &mut working_set, - Some(&format!("line_{}", current_line)), - s.as_bytes(), - false, - ); + let (output, err) = + parse(&mut working_set, Some(""), s.as_bytes(), false); if let Some(err) = err { report_error(&working_set, &err); continue; @@ -145,7 +140,6 @@ fn main() -> Result<()> { } } } - current_line += 1; } Ok(())