more error messages

This commit is contained in:
Folkert 2021-02-08 21:58:39 +01:00
parent 09b3d40380
commit 860aa6d194
5 changed files with 154 additions and 45 deletions

View file

@ -4,3 +4,5 @@ pub static ELSE: &str = "else";
pub static WHEN: &str = "when"; pub static WHEN: &str = "when";
pub static AS: &str = "as"; pub static AS: &str = "as";
pub static IS: &str = "is"; pub static IS: &str = "is";
pub static KEYWORDS: [&str; 6] = [IF, THEN, ELSE, WHEN, AS, IS];

View file

@ -89,6 +89,24 @@ impl Region {
0 0
} }
} }
pub fn from_row_col(row: u32, col: u16) -> Self {
Region {
start_col: col,
start_line: row,
end_col: col + 1,
end_line: row,
}
}
pub fn from_rows_cols(start_line: u32, start_col: u16, end_line: u32, end_col: u16) -> Self {
Region {
start_col,
start_line,
end_col,
end_line,
}
}
} }
#[test] #[test]

View file

@ -124,19 +124,8 @@ fn to_trecord_report<'a>(
match parse_problem { match parse_problem {
TRecord::End(row, col) => { TRecord::End(row, col) => {
let surroundings = Region { let surroundings = Region::from_rows_cols(start_row, start_col, row, col);
start_col, let region = Region::from_row_col(row, col);
start_line: start_row,
end_col: col,
end_line: row,
};
let region = Region {
start_col: col,
start_line: row,
end_col: col,
end_line: row,
};
let doc = alloc.stack(vec![ let doc = alloc.stack(vec![
alloc.reflow("I am partway through parsing a record type, but I got stuck here:"), alloc.reflow("I am partway through parsing a record type, but I got stuck here:"),
@ -158,28 +147,42 @@ fn to_trecord_report<'a>(
} }
TRecord::IndentEnd(row, col) => { TRecord::IndentEnd(row, col) => {
// TODO check whether next character is a `}` match next_line_starts_with_close_curly(alloc.src_lines, row - 1) {
let surroundings = Region { Some((curly_row, curly_col)) => {
start_col, let surroundings =
start_line: start_row, Region::from_rows_cols(start_row, start_col, curly_row, curly_col);
end_col: col, let region = Region::from_row_col(curly_row, curly_col);
end_line: row,
};
let region = Region { dbg!(region);
start_col: col,
start_line: row,
end_col: col,
end_line: row,
};
let doc = alloc.stack(vec![ let doc = alloc.stack(vec![
alloc.reflow("I am partway through parsing a record type, but I got stuck here:"), alloc.reflow(
"I am partway through parsing a record type, but I got stuck here:",
),
alloc.region_with_subregion(surroundings, region), alloc.region_with_subregion(surroundings, region),
alloc.concat(vec![ alloc.concat(vec![
alloc.reflow("I need this curly brace to be indented more. Try adding more spaces before it!"),
]),
]);
Report {
filename: filename.clone(),
doc,
title: "NEED MORE INDENTATION".to_string(),
}
}
None => {
let surroundings = Region::from_rows_cols(start_row, start_col, row, col);
let region = Region::from_row_col(row, col);
let doc = alloc.stack(vec![
alloc.reflow( alloc.reflow(
r"I was expecting to see a closing curly brace before this, so try adding a ", r"I am partway through parsing a record type, but I got stuck here:",
), ),
alloc.region_with_subregion(surroundings, region),
alloc.concat(vec![
alloc.reflow("I was expecting to see a closing curly "),
alloc.reflow("brace before this, so try adding a "),
alloc.parser_suggestion("}"), alloc.parser_suggestion("}"),
alloc.reflow(" and see if that helps?"), alloc.reflow(" and see if that helps?"),
]), ]),
@ -191,7 +194,67 @@ fn to_trecord_report<'a>(
title: "UNFINISHED RECORD TYPE".to_string(), title: "UNFINISHED RECORD TYPE".to_string(),
} }
} }
}
}
_ => todo!("unhandled record type parse error: {:?}", &parse_problem), _ => todo!("unhandled record type parse error: {:?}", &parse_problem),
} }
} }
enum Next<'a> {
Keyword(&'a str),
Operator(&'a str),
Close(&'a str, char),
Other(Option<char>),
}
fn what_is_next<'a>(source_lines: &'a [&'a str], row: Row, col: Col) -> Next<'a> {
match source_lines.get(row as usize) {
None => Next::Other(None),
Some(line) => {
let chars = &line[col as usize..];
match roc_parse::keyword::KEYWORDS
.iter()
.find(|keyword| starts_with_keyword(chars, keyword))
{
Some(keyword) => Next::Keyword(keyword),
None => match chars.chars().nth(0) {
None => Next::Other(None),
Some(c) => match c {
')' => Next::Close("parenthesis", ')'),
']' => Next::Close("square bracket", ']'),
'}' => Next::Close("curly brace", '}'),
// _ if is_symbol(c) => todo!("it's an operator"),
_ => Next::Other(Some(c)),
},
},
}
}
}
}
fn starts_with_keyword(rest_of_line: &str, keyword: &str) -> bool {
if rest_of_line.starts_with(keyword) {
match (&rest_of_line[keyword.len()..]).chars().nth(0) {
None => true,
Some(c) => c.is_alphanumeric() || c == '_',
}
} else {
false
}
}
fn next_line_starts_with_close_curly(source_lines: &[&str], row: Row) -> Option<(Row, Col)> {
match source_lines.get(row as usize + 1) {
None => None,
Some(line) => {
let spaces_dropped = line.trim_start_matches(' ');
match spaces_dropped.chars().nth(0) {
Some('}') => Some((row + 1, (line.len() - spaces_dropped.len()) as u16)),
_ => None,
}
}
}
}

View file

@ -2,6 +2,7 @@ use inlinable_string::InlinableString;
use roc_module::ident::Ident; use roc_module::ident::Ident;
use roc_module::ident::{Lowercase, TagName, Uppercase}; use roc_module::ident::{Lowercase, TagName, Uppercase};
use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_parse::parser::{Col, Row};
use std::fmt; use std::fmt;
use std::path::PathBuf; use std::path::PathBuf;
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder, Render, RenderAnnotated}; use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder, Render, RenderAnnotated};
@ -162,7 +163,7 @@ pub const RESET_CODE: &str = "\u{001b}[0m";
// define custom allocator struct so we can `impl RocDocAllocator` custom helpers // define custom allocator struct so we can `impl RocDocAllocator` custom helpers
pub struct RocDocAllocator<'a> { pub struct RocDocAllocator<'a> {
upstream: BoxAllocator, upstream: BoxAllocator,
src_lines: &'a [&'a str], pub src_lines: &'a [&'a str],
pub home: ModuleId, pub home: ModuleId,
pub interns: &'a Interns, pub interns: &'a Interns,
} }
@ -458,7 +459,7 @@ impl<'a> RocDocAllocator<'a> {
region: roc_region::all::Region, region: roc_region::all::Region,
sub_region: roc_region::all::Region, sub_region: roc_region::all::Region,
) -> DocBuilder<'a, Self, Annotation> { ) -> DocBuilder<'a, Self, Annotation> {
debug_assert!(region.contains(&sub_region)); // debug_assert!(region.contains(&sub_region));
// If the outer region takes more than 1 full screen (~60 lines), only show the inner region // If the outer region takes more than 1 full screen (~60 lines), only show the inner region
if region.end_line - region.start_line > 60 { if region.end_line - region.start_line > 60 {

View file

@ -4086,7 +4086,6 @@ mod test_reporting {
#[test] #[test]
fn recort_type_end() { fn recort_type_end() {
// NOTE: VERY BAD ERROR MESSAGE
report_problem_as( report_problem_as(
indoc!( indoc!(
r#" r#"
@ -4100,7 +4099,7 @@ mod test_reporting {
I am partway through parsing a record type, but I got stuck here: I am partway through parsing a record type, but I got stuck here:
1 f : { a: Int, 1 f : { a: Int,
^
I was expecting to see a closing curly brace before this, so try I was expecting to see a closing curly brace before this, so try
adding a } and see if that helps? adding a } and see if that helps?
@ -4108,4 +4107,30 @@ mod test_reporting {
), ),
) )
} }
#[test]
fn recort_type_indent_end() {
report_problem_as(
indoc!(
r#"
f : { a: Int
}
"#
),
indoc!(
r#"
NEED MORE INDENTATION
I am partway through parsing a record type, but I got stuck here:
1 f : { a: Int
2 }
^
I need this curly brace to be indented more. Try adding more spaces
before it!
"#
),
)
}
} }