Skip to content

Commit

Permalink
Improve error message if if is missing the else (#1252)
Browse files Browse the repository at this point in the history
  • Loading branch information
nk9 authored Jun 30, 2022
1 parent 0b750b6 commit e1f729e
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 16 deletions.
23 changes: 17 additions & 6 deletions src/compile_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,23 @@ impl Display for CompileError<'_> {
DuplicateVariable { variable } => {
write!(f, "Variable `{}` has multiple definitions", variable)?;
}
ExpectedKeyword { expected, found } => write!(
f,
"Expected keyword {} but found identifier `{}`",
List::or_ticked(expected),
found
)?,
ExpectedKeyword { expected, found } => {
if found.kind == TokenKind::Identifier {
write!(
f,
"Expected keyword {} but found identifier `{}`",
List::or_ticked(expected),
found.lexeme()
)?;
} else {
write!(
f,
"Expected keyword {} but found `{}`",
List::or_ticked(expected),
found.kind
)?;
}
}
ExtraLeadingWhitespace => {
write!(f, "Recipe line has extra leading whitespace")?;
}
Expand Down
2 changes: 1 addition & 1 deletion src/compile_error_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub(crate) enum CompileErrorKind<'src> {
},
ExpectedKeyword {
expected: Vec<Keyword>,
found: &'src str,
found: Token<'src>,
},
ExtraLeadingWhitespace,
FunctionArgumentCountMismatch {
Expand Down
14 changes: 7 additions & 7 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub(crate) struct Parser<'tokens, 'src> {
/// Current expected tokens
expected: BTreeSet<TokenKind>,
/// Current recursion depth
depth: u8,
depth: usize,
}

impl<'tokens, 'src> Parser<'tokens, 'src> {
Expand Down Expand Up @@ -157,13 +157,12 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
}

fn expect_keyword(&mut self, expected: Keyword) -> CompileResult<'src, ()> {
let identifier = self.expect(Identifier)?;
let found = identifier.lexeme();
let found = self.advance()?;

if expected == found {
if found.kind == Identifier && expected == found.lexeme() {
Ok(())
} else {
Err(identifier.error(CompileErrorKind::ExpectedKeyword {
Err(found.error(CompileErrorKind::ExpectedKeyword {
expected: vec![expected],
found,
}))
Expand Down Expand Up @@ -394,7 +393,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {

/// Parse an expression, e.g. `1 + 2`
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 {
token: self.next()?,
kind: CompileErrorKind::ParsingRecursionDepthExceeded,
Expand Down Expand Up @@ -422,6 +421,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
};

self.depth -= 1;

Ok(expression)
}

Expand Down Expand Up @@ -735,7 +735,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
} else {
return Err(identifier.error(CompileErrorKind::ExpectedKeyword {
expected: vec![Keyword::True, Keyword::False],
found: identifier.lexeme(),
found: identifier,
}));
};

Expand Down
31 changes: 31 additions & 0 deletions tests/assignment.rs
Original file line number Diff line number Diff line change
@@ -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,
}
30 changes: 30 additions & 0 deletions tests/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,33 @@ test! {
stdout: "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,
}
4 changes: 2 additions & 2 deletions tests/recursion_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ const RECURSION_LIMIT_REACHED: &str = "
error: Parsing recursion depth exceeded
|
1 | foo: (x ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
| ^
| ^
";

#[cfg(windows)]
const RECURSION_LIMIT_REACHED: &str = "
error: Parsing recursion depth exceeded
|
1 | foo: (x ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
| ^
| ^
";

0 comments on commit e1f729e

Please sign in to comment.