mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
more error messages
This commit is contained in:
parent
09b3d40380
commit
860aa6d194
5 changed files with 154 additions and 45 deletions
|
@ -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];
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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!
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue