Improve error message if if is missing the else (#1252)

This commit is contained in:
Nick Kocharhook 2022-06-30 11:34:11 +01:00 committed by GitHub
parent 0b750b6cd7
commit e1f729efbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 16 deletions

View File

@ -117,12 +117,23 @@ impl Display for CompileError<'_> {
DuplicateVariable { variable } => { DuplicateVariable { variable } => {
write!(f, "Variable `{}` has multiple definitions", variable)?; write!(f, "Variable `{}` has multiple definitions", variable)?;
} }
ExpectedKeyword { expected, found } => write!( ExpectedKeyword { expected, found } => {
if found.kind == TokenKind::Identifier {
write!(
f, f,
"Expected keyword {} but found identifier `{}`", "Expected keyword {} but found identifier `{}`",
List::or_ticked(expected), List::or_ticked(expected),
found found.lexeme()
)?, )?;
} else {
write!(
f,
"Expected keyword {} but found `{}`",
List::or_ticked(expected),
found.kind
)?;
}
}
ExtraLeadingWhitespace => { ExtraLeadingWhitespace => {
write!(f, "Recipe line has extra leading whitespace")?; write!(f, "Recipe line has extra leading whitespace")?;
} }

View File

@ -42,7 +42,7 @@ pub(crate) enum CompileErrorKind<'src> {
}, },
ExpectedKeyword { ExpectedKeyword {
expected: Vec<Keyword>, expected: Vec<Keyword>,
found: &'src str, found: Token<'src>,
}, },
ExtraLeadingWhitespace, ExtraLeadingWhitespace,
FunctionArgumentCountMismatch { FunctionArgumentCountMismatch {

View File

@ -33,7 +33,7 @@ pub(crate) struct Parser<'tokens, 'src> {
/// Current expected tokens /// Current expected tokens
expected: BTreeSet<TokenKind>, expected: BTreeSet<TokenKind>,
/// Current recursion depth /// Current recursion depth
depth: u8, depth: usize,
} }
impl<'tokens, 'src> Parser<'tokens, 'src> { impl<'tokens, 'src> Parser<'tokens, 'src> {
@ -157,13 +157,12 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
} }
fn expect_keyword(&mut self, expected: Keyword) -> CompileResult<'src, ()> { fn expect_keyword(&mut self, expected: Keyword) -> CompileResult<'src, ()> {
let identifier = self.expect(Identifier)?; let found = self.advance()?;
let found = identifier.lexeme();
if expected == found { if found.kind == Identifier && expected == found.lexeme() {
Ok(()) Ok(())
} else { } else {
Err(identifier.error(CompileErrorKind::ExpectedKeyword { Err(found.error(CompileErrorKind::ExpectedKeyword {
expected: vec![expected], expected: vec![expected],
found, found,
})) }))
@ -394,7 +393,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
/// Parse an expression, e.g. `1 + 2` /// Parse an expression, e.g. `1 + 2`
fn parse_expression(&mut self) -> CompileResult<'src, Expression<'src>> { fn parse_expression(&mut self) -> CompileResult<'src, Expression<'src>> {
if self.depth == if cfg!(windows) { 64 } else { 255 } { if self.depth == if cfg!(windows) { 48 } else { 256 } {
return Err(CompileError { return Err(CompileError {
token: self.next()?, token: self.next()?,
kind: CompileErrorKind::ParsingRecursionDepthExceeded, kind: CompileErrorKind::ParsingRecursionDepthExceeded,
@ -422,6 +421,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
}; };
self.depth -= 1; self.depth -= 1;
Ok(expression) Ok(expression)
} }
@ -735,7 +735,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
} else { } else {
return Err(identifier.error(CompileErrorKind::ExpectedKeyword { return Err(identifier.error(CompileErrorKind::ExpectedKeyword {
expected: vec![Keyword::True, Keyword::False], expected: vec![Keyword::True, Keyword::False],
found: identifier.lexeme(), found: identifier,
})); }));
}; };

31
tests/assignment.rs Normal file
View File

@ -0,0 +1,31 @@
use super::*;
test! {
name: set_export_parse_error,
justfile: "
set export := fals
",
stdout: "",
stderr: "
error: Expected keyword `true` or `false` but found identifier `fals`
|
1 | set export := fals
| ^^^^
",
status: EXIT_FAILURE,
}
test! {
name: set_export_parse_error_EOL,
justfile: "
set export := fals
",
stdout: "",
stderr: "
error: Expected keyword `true` or `false` but found `end of line`
|
1 | set export :=
| ^
",
status: EXIT_FAILURE,
}

View File

@ -168,3 +168,33 @@ test! {
stdout: "b\n", stdout: "b\n",
stderr: "echo b\n", stderr: "echo b\n",
} }
test! {
name: missing_else,
justfile: "
TEST := if path_exists('/bin/bash') == 'true' {'yes'}
",
stdout: "",
stderr: "
error: Expected keyword `else` but found `end of line`
|
1 | TEST := if path_exists('/bin/bash') == 'true' {'yes'}
| ^
",
status: EXIT_FAILURE,
}
test! {
name: incorrect_else_identifier,
justfile: "
TEST := if path_exists('/bin/bash') == 'true' {'yes'} els {'no'}
",
stdout: "",
stderr: "
error: Expected keyword `else` but found identifier `els`
|
1 | TEST := if path_exists('/bin/bash') == 'true' {'yes'} els {'no'}
| ^^^
",
status: EXIT_FAILURE,
}