Fix error reporting location for unterminated strings and add test for insufficiently indented multiline strings

This commit is contained in:
Joshua Warner 2022-07-25 19:00:11 -07:00
parent 92a9570384
commit a579edc6f0
3 changed files with 52 additions and 4 deletions

View file

@ -170,7 +170,11 @@ pub fn parse<'a>() -> impl Parser<'a, StrLiteral<'a>, EString<'a>> {
let indent = state.column();
let start_state;
if state.consume_mut("\"\"\"") {
start_state = state.clone();
// we will be parsing a multi-line string
is_multiline = true;
@ -178,6 +182,8 @@ pub fn parse<'a>() -> impl Parser<'a, StrLiteral<'a>, EString<'a>> {
state = consume_indent(state, indent)?;
}
} else if state.consume_mut("\"") {
start_state = state.clone();
// we will be parsing a single-line string
is_multiline = false;
} else {
@ -331,7 +337,11 @@ pub fn parse<'a>() -> impl Parser<'a, StrLiteral<'a>, EString<'a>> {
// all remaining chars. This will mask all other errors, but
// it should make it easiest to debug; the file will be a giant
// error starting from where the open quote appeared.
return Err((MadeProgress, EString::EndlessSingle(state.pos()), state));
return Err((
MadeProgress,
EString::EndlessSingle(start_state.pos()),
start_state,
));
}
}
b'\\' => {
@ -434,11 +444,11 @@ pub fn parse<'a>() -> impl Parser<'a, StrLiteral<'a>, EString<'a>> {
Err((
MadeProgress,
if is_multiline {
EString::EndlessMulti(state.pos())
EString::EndlessMulti(start_state.pos())
} else {
EString::EndlessSingle(state.pos())
EString::EndlessSingle(start_state.pos())
},
state,
start_state,
))
}
}

View file

@ -921,6 +921,27 @@ fn to_str_report<'a>(
severity: Severity::RuntimeError,
}
}
EString::MultilineInsufficientIndent(pos) => {
let surroundings = Region::new(start, pos);
let region = LineColumnRegion::from_pos(lines.convert_pos(pos));
let doc = alloc.stack([
alloc.reflow(r"This multiline string is not sufficiently indented:"),
alloc.region_with_subregion(lines.convert_region(surroundings), region),
alloc.concat([
alloc.reflow(r"Lines in a multi-line string must be indented at least as "),
alloc.reflow("much as the beginning \"\"\". This extra indentation is automatically removed "),
alloc.reflow("from the string during compilation."),
]),
]);
Report {
filename,
doc,
title: "INSUFFICIENT INDENT IN MULTI-LINE STRING".to_string(),
severity: Severity::RuntimeError,
}
}
}
}
fn to_expr_in_parens_report<'a>(

View file

@ -5215,6 +5215,23 @@ mod test_reporting {
"###
);
test_report!(
multi_insufficient_indent,
" \"\"\"\n testing\n \"\"\"", // 4 space indent on the start, 2 space on the `testing` line
@r###"
INSUFFICIENT INDENT IN MULTI-LINE STRING ..._insufficient_indent/Test.roc
This multiline string is not sufficiently indented:
5 testing
^
Lines in a multi-line string must be indented at least as much as the
beginning """. This extra indentation is automatically removed from
the string during compilation.
"###
);
// https://github.com/rtfeldman/roc/issues/1714
test_report!(
interpolate_concat_is_transparent_1714,