mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Merge pull request #1155 from rtfeldman/outdent-parse-crash
Outdent parse crash
This commit is contained in:
commit
e4da63cc48
5 changed files with 207 additions and 66 deletions
|
@ -1,7 +1,7 @@
|
|||
use crate::ast::CommentOrNewline;
|
||||
use crate::ast::Spaceable;
|
||||
use crate::parser::{
|
||||
self, and, BadInputError, Col, Parser,
|
||||
self, and, backtrackable, BadInputError, Col, Parser,
|
||||
Progress::{self, *},
|
||||
Row, State,
|
||||
};
|
||||
|
@ -31,11 +31,50 @@ where
|
|||
space0_e(min_indent, space_problem, indent_after_problem),
|
||||
),
|
||||
),
|
||||
move |arena: &'a Bump,
|
||||
spaces_around_help,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn space0_before_optional_after<'a, P, S, E>(
|
||||
parser: P,
|
||||
min_indent: u16,
|
||||
space_problem: fn(BadInputError, Row, Col) -> E,
|
||||
indent_before_problem: fn(Row, Col) -> E,
|
||||
indent_after_problem: fn(Row, Col) -> E,
|
||||
) -> impl Parser<'a, Located<S>, E>
|
||||
where
|
||||
S: Spaceable<'a>,
|
||||
S: 'a,
|
||||
P: Parser<'a, Located<S>, E>,
|
||||
P: 'a,
|
||||
E: 'a,
|
||||
{
|
||||
parser::map_with_arena(
|
||||
and(
|
||||
space0_e(min_indent, space_problem, indent_before_problem),
|
||||
and(
|
||||
parser,
|
||||
one_of![
|
||||
backtrackable(space0_e(min_indent, space_problem, indent_after_problem)),
|
||||
succeed!(&[] as &[_]),
|
||||
],
|
||||
),
|
||||
),
|
||||
spaces_around_help,
|
||||
)
|
||||
}
|
||||
|
||||
fn spaces_around_help<'a, S>(
|
||||
arena: &'a Bump,
|
||||
tuples: (
|
||||
&'a [CommentOrNewline<'a>],
|
||||
(Located<S>, &'a [CommentOrNewline<'a>]),
|
||||
)| {
|
||||
),
|
||||
) -> Located<S>
|
||||
where
|
||||
S: Spaceable<'a>,
|
||||
S: 'a,
|
||||
{
|
||||
let (spaces_before, (loc_val, spaces_after)) = tuples;
|
||||
|
||||
if spaces_before.is_empty() {
|
||||
|
@ -59,8 +98,6 @@ where
|
|||
.alloc(wrapped_expr.value)
|
||||
.with_spaces_before(spaces_before, wrapped_expr.region)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn space0_before_e<'a, P, S, E>(
|
||||
|
|
|
@ -1273,7 +1273,7 @@ macro_rules! collection_trailing_sep_e {
|
|||
and!(
|
||||
$crate::parser::trailing_sep_by0(
|
||||
$delimiter,
|
||||
$crate::blankspace::space0_around_ee(
|
||||
$crate::blankspace::space0_before_optional_after(
|
||||
$elem,
|
||||
$min_indent,
|
||||
$space_problem,
|
||||
|
@ -1299,6 +1299,15 @@ macro_rules! collection_trailing_sep_e {
|
|||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! succeed {
|
||||
($value:expr) => {
|
||||
move |_arena: &'a bumpalo::Bump, state: $crate::parser::State<'a>| {
|
||||
Ok((NoProgress, $value, state))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! and {
|
||||
($p1:expr, $p2:expr) => {
|
||||
|
|
|
@ -147,7 +147,7 @@ fn loc_type_in_parens<'a>(
|
|||
TInParens::IndentOpen,
|
||||
TInParens::IndentEnd,
|
||||
),
|
||||
word1(b')', TInParens::End)
|
||||
word1(b')', TInParens::IndentEnd)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1750,7 +1750,7 @@ fn to_precord_report<'a>(
|
|||
}
|
||||
|
||||
PRecord::IndentEnd(row, col) => {
|
||||
match next_line_starts_with_close_curly(alloc.src_lines, row.saturating_sub(1)) {
|
||||
match next_line_starts_with_close_curly(alloc.src_lines, row) {
|
||||
Some((curly_row, curly_col)) => {
|
||||
let surroundings =
|
||||
Region::from_rows_cols(start_row, start_col, curly_row, curly_col);
|
||||
|
@ -1895,7 +1895,7 @@ fn to_pattern_in_parens_report<'a>(
|
|||
}
|
||||
|
||||
PInParens::IndentEnd(row, col) => {
|
||||
match next_line_starts_with_close_parenthesis(alloc.src_lines, row.saturating_sub(1)) {
|
||||
match next_line_starts_with_close_parenthesis(alloc.src_lines, row) {
|
||||
Some((curly_row, curly_col)) => {
|
||||
let surroundings =
|
||||
Region::from_rows_cols(start_row, start_col, curly_row, curly_col);
|
||||
|
@ -2257,7 +2257,7 @@ fn to_trecord_report<'a>(
|
|||
}
|
||||
|
||||
TRecord::IndentEnd(row, col) => {
|
||||
match next_line_starts_with_close_curly(alloc.src_lines, row.saturating_sub(1)) {
|
||||
match next_line_starts_with_close_curly(alloc.src_lines, row) {
|
||||
Some((curly_row, curly_col)) => {
|
||||
let surroundings =
|
||||
Region::from_rows_cols(start_row, start_col, curly_row, curly_col);
|
||||
|
@ -2478,7 +2478,7 @@ fn to_ttag_union_report<'a>(
|
|||
}
|
||||
|
||||
TTagUnion::IndentEnd(row, col) => {
|
||||
match next_line_starts_with_close_square_bracket(alloc.src_lines, row - 1) {
|
||||
match next_line_starts_with_close_square_bracket(alloc.src_lines, row) {
|
||||
Some((curly_row, curly_col)) => {
|
||||
let surroundings =
|
||||
Region::from_rows_cols(start_row, start_col, curly_row, curly_col);
|
||||
|
@ -2682,7 +2682,7 @@ fn to_tinparens_report<'a>(
|
|||
}
|
||||
|
||||
TInParens::IndentEnd(row, col) => {
|
||||
match next_line_starts_with_close_square_bracket(alloc.src_lines, row - 1) {
|
||||
match next_line_starts_with_close_parenthesis(alloc.src_lines, row) {
|
||||
Some((curly_row, curly_col)) => {
|
||||
let surroundings =
|
||||
Region::from_rows_cols(start_row, start_col, curly_row, curly_col);
|
||||
|
@ -2694,7 +2694,7 @@ fn to_tinparens_report<'a>(
|
|||
),
|
||||
alloc.region_with_subregion(surroundings, region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("I need this square bracket to be indented more. Try adding more spaces before it!"),
|
||||
alloc.reflow("I need this parenthesis to be indented more. Try adding more spaces before it!"),
|
||||
]),
|
||||
]);
|
||||
|
||||
|
@ -2714,9 +2714,9 @@ fn to_tinparens_report<'a>(
|
|||
),
|
||||
alloc.region_with_subregion(surroundings, region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("I was expecting to see a closing square "),
|
||||
alloc.reflow("bracket before this, so try adding a "),
|
||||
alloc.parser_suggestion("]"),
|
||||
alloc.reflow("I was expecting to see a parenthesis "),
|
||||
alloc.reflow("before this, so try adding a "),
|
||||
alloc.parser_suggestion(")"),
|
||||
alloc.reflow(" and see if that helps?"),
|
||||
]),
|
||||
note_for_tag_union_type_indent(alloc),
|
||||
|
|
|
@ -4533,8 +4533,10 @@ mod test_reporting {
|
|||
1│ f : ( I64
|
||||
^
|
||||
|
||||
I was expecting to see a closing parenthesis before this, so try
|
||||
adding a ) and see if that helps?
|
||||
I was expecting to see a parenthesis before this, so try adding a )
|
||||
and see if that helps?
|
||||
|
||||
Note: I may be confused by indentation
|
||||
"#
|
||||
),
|
||||
)
|
||||
|
@ -6208,4 +6210,97 @@ mod test_reporting {
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outdented_alias() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
Box item : [
|
||||
Box item,
|
||||
Items item item
|
||||
]
|
||||
|
||||
4
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── NEED MORE INDENTATION ───────────────────────────────────────────────────────
|
||||
|
||||
I am partway through parsing a tag union type, but I got stuck here:
|
||||
|
||||
1│ Box item : [
|
||||
2│ Box item,
|
||||
3│ Items item item
|
||||
4│ ]
|
||||
^
|
||||
|
||||
I need this square bracket to be indented more. Try adding more spaces
|
||||
before it!
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outdented_in_parens() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
Box : (
|
||||
Str
|
||||
)
|
||||
|
||||
4
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── NEED MORE INDENTATION ───────────────────────────────────────────────────────
|
||||
|
||||
I am partway through parsing a type in parentheses, but I got stuck
|
||||
here:
|
||||
|
||||
1│ Box : (
|
||||
2│ Str
|
||||
3│ )
|
||||
^
|
||||
|
||||
I need this parenthesis to be indented more. Try adding more spaces
|
||||
before it!
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outdented_record() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
Box : {
|
||||
id: Str
|
||||
}
|
||||
|
||||
4
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── NEED MORE INDENTATION ───────────────────────────────────────────────────────
|
||||
|
||||
I am partway through parsing a record type, but I got stuck here:
|
||||
|
||||
1│ Box : {
|
||||
2│ id: Str
|
||||
3│ }
|
||||
^
|
||||
|
||||
I need this curly brace to be indented more. Try adding more spaces
|
||||
before it!
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue