fix: Handle parsing corner cases (#309)

A block with a single or expression needs to be treated as a comprehension instead of a
set/array with 1 item. e.g.: {1 | 1 }, [2 | foo]

Allow successfully parsing object comprehensions as rule body
x if { 1:2 | 1 }

fixes #306, fixes #307

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2024-09-04 10:02:14 -07:00
committed by GitHub
parent a4a80d7fc6
commit 8003cfc5b7
3 changed files with 63 additions and 0 deletions

View File

@@ -1038,6 +1038,23 @@ impl<'source> Parser<'source> {
let mut literals = vec![];
let stmt = match self.parse_literal_stmt() {
Ok(_) if self.token_text() == ":" => {
// This is likely an object comprehension.
// Restore the state and return.
*self = state;
bail!("try parsing as comprehension");
}
Ok(stmt) if self.token_text() == end_delim => {
// Treat { 1 | 1 } as a comprehension instead of a
// set of 1 element.
if let Literal::Expr { expr: e, .. } = &stmt.literal {
if matches!(e.as_ref(), Expr::BinExpr { op: BinOp::Or, .. }) {
*self = state;
bail!("try parse as comprehension");
}
}
stmt
}
Ok(stmt) => stmt,
Err(e) if is_definite_query => return Err(e),
Err(e) if matches!(self.token_text(), "=" | ":=") => return Err(e),