unused def report and batch report text

This commit is contained in:
Chad Stearns 2020-03-14 12:28:36 -04:00
parent 9081b7f2d1
commit 51ad7ea0f1
2 changed files with 118 additions and 24 deletions

View file

@ -1,6 +1,6 @@
use crate::report::ReportText::{Batch, Region, Value};
use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_problem::can::Problem;
use roc_region::all::Region;
use roc_types::pretty_print::content_to_string;
use roc_types::subs::{Content, Subs};
use std::path::PathBuf;
@ -11,19 +11,32 @@ pub struct Report {
pub text: ReportText,
}
impl Report {
pub fn can_problem(_filename: PathBuf, _problem: Problem) -> Self {
// let text = match problem {
// Problem::UnusedDef(symbol, region) => {
// panic!("TODO implelment me!");
// }
// _ => {
// panic!("TODO implement others");
// }
// };
pub fn can_problem(filename: PathBuf, problem: Problem) -> Report {
let mut texts = Vec::new();
// Report { filename, text }
panic!("TODO implement me!");
match problem {
Problem::UnusedDef(symbol, region) => {
texts.push(Value(symbol));
texts.push(plain_text(" is not used anywhere in your code."));
texts.push(newline());
texts.push(newline());
texts.push(Region(region));
texts.push(newline());
texts.push(newline());
texts.push(plain_text("If you didn't intend on using "));
texts.push(Value(symbol));
texts.push(plain_text(
" then remove it so future readers of your code don't wonder why it is there.",
));
}
_ => {
panic!("TODO implement others");
}
};
Report {
filename,
text: Batch(texts),
}
}
@ -43,13 +56,25 @@ pub enum ReportText {
EmText(Box<str>),
/// A region in the original source
Region(Region),
Region(roc_region::all::Region),
/// A URL, which should be rendered as a hyperlink.
Url(Box<str>),
/// The documentation for this symbol.
Docs(Symbol),
Batch(Vec<ReportText>),
}
pub fn plain_text(str: &str) -> ReportText {
use ReportText::*;
Plain(Box::from(str))
}
fn newline() -> ReportText {
plain_text("\n")
}
impl ReportText {
@ -89,7 +114,7 @@ impl ReportText {
}
Type(content) => buf.push_str(content_to_string(content, subs, home, interns).as_str()),
Region(region) => {
for i in region.start_line..region.end_line {
for i in region.start_line..=region.end_line {
buf.push_str(i.to_string().as_str());
buf.push_str(" |");
@ -100,12 +125,19 @@ impl ReportText {
buf.push_str(src_lines[i as usize]);
}
if i != region.end_line {
buf.push('\n');
}
}
}
Docs(_) => {
panic!("TODO implment docs");
}
Batch(report_texts) => {
for report_text in report_texts {
report_text.render_ci(buf, subs, home, src_lines, interns);
}
}
}
}

View file

@ -11,24 +11,30 @@ mod helpers;
mod test_report {
use crate::helpers::test_home;
use roc_module::symbol::{Interns, ModuleId};
use roc_reporting::report::{Report, ReportText};
use roc_reporting::report::{can_problem, plain_text, Report, ReportText};
use roc_types::pretty_print::name_all_type_vars;
use roc_types::subs::Subs;
use roc_types::types;
use std::path::PathBuf;
// use roc_region::all;
use crate::helpers::{assert_correct_variable_usage, can_expr, infer_expr, CanExprOut};
use roc_reporting::report::ReportText::{EmText, Plain, Region, Type, Url, Value};
use roc_problem::can::Problem;
use roc_reporting::report::ReportText::{Batch, EmText, Plain, Region, Type, Url, Value};
use roc_types::subs::Content::{FlexVar, RigidVar, Structure};
use roc_types::subs::FlatType::EmptyRecord;
fn filename_from_string(str: &str) -> PathBuf {
let mut filename = PathBuf::new();
filename.push(str);
return filename;
}
// use roc_problem::can;
fn to_simple_report(text: ReportText) -> Report {
let mut filename = PathBuf::new();
filename.push(r"\code\proj\Main.roc");
Report {
text: text,
filename: filename,
filename: filename_from_string(r"\code\proj\Main.roc"),
}
}
@ -69,7 +75,7 @@ mod test_report {
fn report_renders_as_from_src(src: &str, report: Report, expected_rendering: &str) {
let (_type_problems, _can_problems, mut subs, home, interns) = infer_expr_help(src);
let mut buf = String::new();
let mut buf: String = String::new();
let src_lines: Vec<&str> = src.split('\n').collect();
report
@ -96,7 +102,7 @@ mod test_report {
#[test]
fn report_plain() {
report_renders_as(to_simple_report(Plain(Box::from("y"))), "y");
report_renders_as(to_simple_report(plain_text("y")), "y");
}
#[test]
@ -152,6 +158,62 @@ mod test_report {
report_renders_as(to_simple_report(Type(Structure(EmptyRecord))), "{}");
}
#[test]
fn report_batch_of_plain_text() {
let mut report_texts = Vec::new();
report_texts.push(plain_text("Wait a second. "));
report_texts.push(plain_text("There is a problem here. -> "));
report_texts.push(EmText(Box::from("y")));
report_renders_as(
to_simple_report(Batch(report_texts)),
"Wait a second. There is a problem here. -> *y*",
);
}
#[test]
fn report_unused_def() {
let src: &str = indoc!(
r#"
x = 1
y = 2
x
"#
);
let (_type_problems, can_problems, mut subs, home, interns) = infer_expr_help(src);
let mut buf: String = String::new();
let src_lines: Vec<&str> = src.split('\n').collect();
match can_problems.first() {
None => {}
Some(problem) => {
let report = can_problem(
filename_from_string(r"\code\proj\Main.roc"),
problem.clone(),
);
report
.text
.render_ci(&mut buf, &mut subs, home, &src_lines, &interns)
}
}
assert_eq!(
buf,
indoc!(
r#"
y is not used anywhere in your code.
1 | y = 2
If you didn't intend on using y then remove it so future readers of your code don't wonder why it is there."#
)
);
}
#[test]
fn report_region() {
report_renders_as_from_src(
@ -166,7 +228,7 @@ mod test_report {
),
to_simple_report(Region(roc_region::all::Region {
start_line: 1,
end_line: 4,
end_line: 3,
start_col: 0,
end_col: 0,
})),