KCL: Fix cryptic error on unexpected tokens in fn call (#7295)
This program: ```kcl 1 |> extrude( length=depth, }) ``` was giving this bad error: ``` unexpected token |> ``` Now it gives ```kcl There was an unexpected }. Try removing it. ``` and it correctly puts the diagnostic on the extra }. Fixes https://github.com/KittyCAD/modeling-app/issues/6126
This commit is contained in:
@ -3141,7 +3141,7 @@ fn binding_name(i: &mut TokenSlice) -> ModalResult<Node<Identifier>> {
|
||||
|
||||
/// Either a positional or keyword function call.
|
||||
fn fn_call_pos_or_kw(i: &mut TokenSlice) -> ModalResult<Expr> {
|
||||
alt((fn_call_kw.map(Box::new).map(Expr::CallExpressionKw),)).parse_next(i)
|
||||
fn_call_kw.map(Box::new).map(Expr::CallExpressionKw).parse_next(i)
|
||||
}
|
||||
|
||||
fn labelled_fn_call(i: &mut TokenSlice) -> ModalResult<Expr> {
|
||||
@ -3270,7 +3270,22 @@ fn fn_call_kw(i: &mut TokenSlice) -> ModalResult<Node<CallExpressionKw>> {
|
||||
)?;
|
||||
ignore_whitespace(i);
|
||||
opt(comma_sep).parse_next(i)?;
|
||||
let end = close_paren.parse_next(i)?.end;
|
||||
let end = match close_paren.parse_next(i) {
|
||||
Ok(tok) => tok.end,
|
||||
Err(e) => {
|
||||
if let Some(tok) = i.next_token() {
|
||||
return Err(ErrMode::Cut(
|
||||
CompilationError::fatal(
|
||||
SourceRange::from(&tok),
|
||||
format!("There was an unexpected {}. Try removing it.", tok.value),
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
} else {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Validate there aren't any duplicate labels.
|
||||
let mut counted_labels = IndexMap::with_capacity(args.len());
|
||||
@ -3391,8 +3406,7 @@ mod tests {
|
||||
fn kw_call_as_operand() {
|
||||
let tokens = crate::parsing::token::lex("f(x = 1)", ModuleId::default()).unwrap();
|
||||
let tokens = tokens.as_slice();
|
||||
let op = operand.parse(tokens).unwrap();
|
||||
println!("{op:#?}");
|
||||
operand.parse(tokens).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -4432,8 +4446,8 @@ z(-[["#,
|
||||
assert_err(
|
||||
r#"z
|
||||
(--#"#,
|
||||
"Unexpected token: (",
|
||||
[2, 3],
|
||||
"There was an unexpected -. Try removing it.",
|
||||
[3, 4],
|
||||
);
|
||||
}
|
||||
|
||||
@ -5188,14 +5202,32 @@ bar = 1
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sensible_error_when_unexpected_token_in_fn_call() {
|
||||
let program_source = "1
|
||||
|> extrude(
|
||||
length=depth,
|
||||
})";
|
||||
let expected_src_start = program_source.find("}").expect("Program should have an extraneous }");
|
||||
let tokens = crate::parsing::token::lex(program_source, ModuleId::default()).unwrap();
|
||||
ParseContext::init();
|
||||
let err = program.parse(tokens.as_slice()).unwrap_err();
|
||||
let cause = err
|
||||
.inner()
|
||||
.cause
|
||||
.as_ref()
|
||||
.expect("Found an error, but there was no cause. Add a cause.");
|
||||
assert_eq!(cause.message, "There was an unexpected }. Try removing it.",);
|
||||
assert_eq!(cause.source_range.start(), expected_src_start);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sensible_error_when_using_keyword_as_arg_label() {
|
||||
for (i, program) in ["pow(2, fn = 8)"].into_iter().enumerate() {
|
||||
let tokens = crate::parsing::token::lex(program, ModuleId::default()).unwrap();
|
||||
let err = match fn_call_kw.parse(tokens.as_slice()) {
|
||||
Err(e) => e,
|
||||
Ok(ast) => {
|
||||
eprintln!("{ast:#?}");
|
||||
Ok(_ast) => {
|
||||
panic!("Expected this to error but it didn't");
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user