fix: make error for missing a closing bracket clearer (#4974)

* fix: make error for missing a closing bracket clearer

* Fix test for error message

---------

Co-authored-by: Tom Pridham <pridham.tom@gmail.com>
This commit is contained in:
Jonathan Tran
2025-01-07 20:55:07 -05:00
committed by GitHub
parent c8afd3399b
commit a9ceaf2678
2 changed files with 25 additions and 6 deletions

View File

@ -47,7 +47,7 @@ describe('parsing errors', () => {
const result = parse(code)
if (err(result)) throw result
const error = result.errors[0]
expect(error.message).toBe('Unexpected token: (')
expect(error.sourceRange).toEqual([27, 28, 0])
expect(error.message).toBe('Array is missing a closing bracket(`]`)')
expect(error.sourceRange).toEqual([28, 29, 0])
})
})

View File

@ -12,6 +12,7 @@ use winnow::{
token::{any, one_of, take_till},
};
use super::{ast::types::LabelledExpression, token::NumericSuffix};
use crate::{
docs::StdLibFn,
errors::{CompilationError, Severity, Tag},
@ -33,8 +34,6 @@ use crate::{
SourceRange,
};
use super::{ast::types::LabelledExpression, token::NumericSuffix};
thread_local! {
/// The current `ParseContext`. `None` if parsing is not currently happening on this thread.
static CTXT: RefCell<Option<ParseContext>> = const { RefCell::new(None) };
@ -683,8 +682,8 @@ pub enum NonCodeOr<T> {
fn array(i: &mut TokenSlice) -> PResult<Expr> {
alt((
array_empty.map(Box::new).map(Expr::ArrayExpression),
array_elem_by_elem.map(Box::new).map(Expr::ArrayExpression),
array_end_start.map(Box::new).map(Expr::ArrayRangeExpression),
array_elem_by_elem.map(Box::new).map(Expr::ArrayExpression),
))
.parse_next(i)
}
@ -732,7 +731,20 @@ pub(crate) fn array_elem_by_elem(i: &mut TokenSlice) -> PResult<Node<ArrayExpres
.context(expected("array contents, a list of elements (like [1, 2, 3])"))
.parse_next(i)?;
ignore_whitespace(i);
let end = close_bracket(i)?.end;
let end = close_bracket(i)
.map_err(|e| {
if let Some(mut err) = e.clone().into_inner() {
err.cause = Some(CompilationError::fatal(
open.as_source_range(),
"Array is missing a closing bracket(`]`)",
));
ErrMode::Cut(err)
} else {
// ErrMode::Incomplete, not sure if it's actually possible to end up with this here
e
}
})?
.end;
// Sort the array's elements (i.e. expression nodes) from the noncode nodes.
let (elements, non_code_nodes): (Vec<_>, HashMap<usize, _>) = elements.into_iter().enumerate().fold(
@ -4319,6 +4331,13 @@ let myBox = box([0,0], -3, -16, -10)
assert_no_err(some_program_string);
}
#[test]
fn test_parse_missing_closing_bracket() {
let some_program_string = r#"
sketch001 = startSketchOn('XZ') |> startProfileAt([90.45, 119.09, %)"#;
assert_err(some_program_string, "Array is missing a closing bracket(`]`)", [51, 52]);
}
#[test]
fn warn_object_expr() {
let some_program_string = "{ foo: bar }";