From 30dadd882c2cceeb511bf9d223893a14902479c0 Mon Sep 17 00:00:00 2001 From: Chad Stearns Date: Wed, 1 Apr 2020 22:17:39 -0400 Subject: [PATCH] Binop precedence problem report test --- compiler/parse/src/operator.rs | 2 +- compiler/reporting/Cargo.toml | 2 +- compiler/reporting/src/report.rs | 31 +++++++++++++++--- compiler/reporting/tests/test_reporting.rs | 37 +++++++++++----------- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/compiler/parse/src/operator.rs b/compiler/parse/src/operator.rs index 068fa17d11..85c827bb9b 100644 --- a/compiler/parse/src/operator.rs +++ b/compiler/parse/src/operator.rs @@ -133,6 +133,6 @@ impl std::fmt::Display for BinOp { Pizza => "|>", }; - write!(f, "({})", as_str) + write!(f, "{}", as_str) } } diff --git a/compiler/reporting/Cargo.toml b/compiler/reporting/Cargo.toml index 5f0a9858d2..a9a414eea1 100644 --- a/compiler/reporting/Cargo.toml +++ b/compiler/reporting/Cargo.toml @@ -8,13 +8,13 @@ edition = "2018" roc_collections = { path = "../collections" } roc_region = { path = "../region" } roc_module = { path = "../module" } +roc_parse = { path = "../parse" } roc_problem = { path = "../problem" } roc_types = { path = "../types" } roc_load = { path = "../load" } roc_can = { path = "../can" } inlinable_string = "0.1.0" - [dev-dependencies] roc_constrain = { path = "../constrain" } roc_builtins = { path = "../builtins" } diff --git a/compiler/reporting/src/report.rs b/compiler/reporting/src/report.rs index b27aa5ba57..ff87e7072b 100644 --- a/compiler/reporting/src/report.rs +++ b/compiler/reporting/src/report.rs @@ -1,4 +1,4 @@ -use crate::report::ReportText::{Batch, Module, Region, Value}; +use crate::report::ReportText::{Batch, BinOp, Module, Region, Value}; use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_problem::can::PrecedenceProblem::BothNonAssociative; use roc_problem::can::Problem; @@ -24,6 +24,7 @@ pub struct Palette { pub line_number: Color, pub gutter_bar: Color, pub module_name: Color, + pub binop: Color, } #[derive(Copy, Clone)] @@ -49,6 +50,7 @@ pub const TEST_PALETTE: Palette = Palette { line_number: Color::Cyan, gutter_bar: Color::Magenta, module_name: Color::Green, + binop: Color::Green, }; impl Color { @@ -109,10 +111,21 @@ pub fn can_problem(filename: PathBuf, problem: Problem) -> Report { texts.push(plain_text("\". Adding an underscore at the start of a variable name is a way of saying that the variable is not used.")); } Problem::PrecedenceProblem(BothNonAssociative(region, left_bin_op, right_bin_op)) => { - texts.push(plain_text(&*format!( - "You cannot mix {} and {} without parentheses", - left_bin_op.value, right_bin_op.value - ))); + if left_bin_op.value == right_bin_op.value { + texts.push(plain_text("Using more than one ")); + texts.push(BinOp(left_bin_op.value)); + texts.push(plain_text( + " like this requires parentheses, to clarify how things should be grouped.", + )) + } else { + texts.push(plain_text("Using ")); + texts.push(BinOp(left_bin_op.value)); + texts.push(plain_text(" and ")); + texts.push(BinOp(right_bin_op.value)); + texts.push(plain_text( + " together requires parentheses, to clarify how they should be grouped.", + )) + } texts.push(Region(region)); } Problem::UnsupportedPattern(_pattern_type, _region) => { @@ -165,6 +178,8 @@ pub enum ReportText { /// The documentation for this symbol. Docs(Symbol), + BinOp(roc_parse::operator::BinOp), + /// Many ReportText that should be concatenated together. Batch(Vec), } @@ -367,6 +382,9 @@ impl ReportText { report_text.render_ci(buf, subs, home, src_lines, interns); } } + BinOp(bin_op) => { + buf.push_str(bin_op.to_string().as_str()); + } } } @@ -507,6 +525,9 @@ impl ReportText { report_text.render_color_terminal(buf, subs, home, src_lines, interns, palette); } } + BinOp(bin_op) => { + buf.push_str(&palette.binop.render(bin_op.to_string().as_str())); + } _ => panic!("TODO implement more ReportTexts in render color terminal"), } } diff --git a/compiler/reporting/tests/test_reporting.rs b/compiler/reporting/tests/test_reporting.rs index 09b729a9b3..595505a185 100644 --- a/compiler/reporting/tests/test_reporting.rs +++ b/compiler/reporting/tests/test_reporting.rs @@ -291,23 +291,22 @@ mod test_reporting { ) } - // hits a TODO in reporting - // #[test] - // fn report_shadow() { - // report_problem_as( - // indoc!( - // r#" - // i = 1 + // #[test] + // fn report_shadow() { + // report_problem_as( + // indoc!( + // r#" + // i = 1 // - // s = \i -> - // i + 1 + // s = \i -> + // i + 1 // - // s i - // "# - // ), - // indoc!(r#" "#), - // ) - // } + // s i + // "# + // ), + // indoc!(r#" "#), + // ) + // } // #[test] // fn report_unsupported_top_level_def() { @@ -342,7 +341,7 @@ mod test_reporting { ), indoc!( r#" - You cannot mix (!=) and (==) without parentheses + Using != and == together requires parentheses, to clarify how they should be grouped. 3 ┆ if selectedId != thisId == adminsId then ┆ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -359,7 +358,7 @@ mod test_reporting { r#" if 1 - != 2 + == 2 == 3 then 2 @@ -370,10 +369,10 @@ mod test_reporting { ), indoc!( r#" - You cannot mix (!=) and (==) without parentheses + Using more than one == like this requires parentheses, to clarify how things should be grouped. 2 ┆> 1 - 3 ┆> != 2 + 3 ┆> == 2 4 ┆> == 3 "#