mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Fix a bunch of parser/formatter bugs found in fuzzing
Notably: * Unified how parens are formatted between (1) when we have a ParensAround, and (2) when we've decided an Apply needs to have parens * Made unary minus require the be indented to the same level as any other expression continuation. (it used to accidentally have rules meant for binary operators applied) * Don't apply extra indent to the backpassing continuation in the case that the call does itself require indentation * Make `try@foo` correctly parse as `try @foo`, so that formatting doesn't change the tree when it adds that space * Detect more cases where we need to outdent trailing e.g. {} blocks in applies * Approximately a bagillion other things, 90% of which I added tests for, and none of which affected the formatting of examples or builtins
This commit is contained in:
parent
335a8eb258
commit
ed62bcc15a
347 changed files with 8219 additions and 1162 deletions
|
@ -513,7 +513,6 @@ pub enum EExpect<'a> {
|
|||
Condition(&'a EExpr<'a>, Position),
|
||||
Continuation(&'a EExpr<'a>, Position),
|
||||
IndentCondition(Position),
|
||||
DbgArity(Position),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
@ -836,7 +835,7 @@ where
|
|||
}
|
||||
|
||||
// This should be enough for anyone. Right? RIGHT?
|
||||
let indent_text = "| ; : ! ".repeat(20);
|
||||
let indent_text = "| ; : ! ".repeat(100);
|
||||
|
||||
let cur_indent = INDENT.with(|i| *i.borrow());
|
||||
|
||||
|
@ -1060,11 +1059,15 @@ where
|
|||
Some(
|
||||
b' ' | b'#' | b'\n' | b'\r' | b'\t' | b',' | b'(' | b')' | b'[' | b']' | b'{'
|
||||
| b'}' | b'"' | b'\'' | b'/' | b'\\' | b'+' | b'*' | b'%' | b'^' | b'&' | b'|'
|
||||
| b'<' | b'>' | b'=' | b'!' | b'~' | b'`' | b';' | b':' | b'?' | b'.',
|
||||
| b'<' | b'>' | b'=' | b'!' | b'~' | b'`' | b';' | b':' | b'?' | b'.' | b'@',
|
||||
) => {
|
||||
state = state.advance(width);
|
||||
Ok((MadeProgress, (), state))
|
||||
}
|
||||
Some(b'-') if keyword_str != "expect" => {
|
||||
state = state.advance(width);
|
||||
Ok((MadeProgress, (), state))
|
||||
}
|
||||
None => {
|
||||
state = state.advance(width);
|
||||
Ok((MadeProgress, (), state))
|
||||
|
@ -1669,6 +1672,21 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates a parser that fails if the next byte is the given byte.
|
||||
pub fn error_on_byte<'a, T, E, F>(byte_to_match: u8, to_error: F) -> impl Parser<'a, T, E>
|
||||
where
|
||||
T: 'a,
|
||||
E: 'a,
|
||||
F: Fn(Position) -> E,
|
||||
{
|
||||
debug_assert_ne!(byte_to_match, b'\n');
|
||||
|
||||
move |_arena: &'a Bump, state: State<'a>, _min_indent: u32| match state.bytes().first() {
|
||||
Some(x) if *x == byte_to_match => Err((MadeProgress, to_error(state.pos()))),
|
||||
_ => Err((NoProgress, to_error(state.pos()))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs two parsers in succession. If both parsers succeed, the output is a tuple of both outputs.
|
||||
/// Both parsers must have the same error type.
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue