Improve error message if if
is missing the else
(#1252)
This commit is contained in:
parent
0b750b6cd7
commit
e1f729efbc
@ -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")?;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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
31
tests/assignment.rs
Normal 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,
|
||||||
|
}
|
@ -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,
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user