From 8c948173b08ad19483b8e7ad9b38c235f3bd13e9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 19 Jul 2024 08:46:14 -0400 Subject: [PATCH] extend calc with annotated snippets --- Cargo.toml | 1 + examples/calc/ir.rs | 17 ++++++++ examples/calc/type_check.rs | 82 ++++++++++++++++++++++++++++++------- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f006e438..0e37d4f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ salsa-macros = { path = "components/salsa-macros" } smallvec = "1.0.0" [dev-dependencies] +annotate-snippets = "0.11.4" derive-new = "0.5.9" expect-test = "1.4.0" eyre = "0.6.8" diff --git a/examples/calc/ir.rs b/examples/calc/ir.rs index 9fe356ce..f1606852 100644 --- a/examples/calc/ir.rs +++ b/examples/calc/ir.rs @@ -104,3 +104,20 @@ pub struct Diagnostic { pub message: String, } // ANCHOR_END: diagnostic + +impl Diagnostic { + pub fn render(&self, db: &dyn crate::Db, src: SourceProgram) -> String { + use annotate_snippets::*; + let line_start = src.text(db)[..self.start].lines().count() + 1; + Renderer::plain() + .render( + Level::Error.title(&self.message).snippet( + Snippet::source(src.text(db)) + .line_start(line_start) + .origin("input") + .annotation(Level::Error.span(self.start..self.end).label("here")), + ), + ) + .to_string() + } +} diff --git a/examples/calc/type_check.rs b/examples/calc/type_check.rs index c6aab81a..da5f7927 100644 --- a/examples/calc/type_check.rs +++ b/examples/calc/type_check.rs @@ -115,8 +115,13 @@ fn check_string( // Read out any diagnostics db.attach(|db| { - expected_diagnostics - .assert_debug_eq(&type_check_program::accumulated::(db, program)); + let rendered_diagnostics: String = + type_check_program::accumulated::(db, program) + .into_iter() + .map(|d| d.render(db, source_program)) + .collect::>() + .join("\n"); + expected_diagnostics.assert_eq(&rendered_diagnostics); }); // Clear logs @@ -142,9 +147,7 @@ fn check_string( fn check_print() { check_string( "print 1 + 2", - expect![[r#" - [] - "#]], + expect![""], &[], ); } @@ -154,8 +157,18 @@ fn check_bad_variable_in_program() { check_string( "print a + b", expect![[r#" - [] - "#]], + error: the variable `a` is not declared + --> input:2:7 + | + 2 | print a + b + | ^^ here + | + error: the variable `b` is not declared + --> input:2:11 + | + 2 | print a + b + | ^ here + |"#]], &[], ); } @@ -165,8 +178,12 @@ fn check_bad_function_in_program() { check_string( "print a(22)", expect![[r#" - [] - "#]], + error: the function `a` is not declared + --> input:2:7 + | + 2 | print a(22) + | ^^^^^ here + |"#]], &[], ); } @@ -179,8 +196,16 @@ fn check_bad_variable_in_function() { print add_one(22) ", expect![[r#" - [] - "#]], + error: the variable `b` is not declared + --> input:4:33 + | + 3 | + 4 | fn add_one(a) = a + b + | _________________________________^ + 5 | | print add_one(22) + | |____________^ here + 6 | + |"#]], &[], ); } @@ -193,8 +218,25 @@ fn check_bad_function_in_function() { print add_one(22) ", expect![[r#" - [] - "#]], + error: the function `add_two` is not declared + --> input:4:29 + | + 3 | + 4 | fn add_one(a) = add_two(a) + b + | ^^^^^^^^^^ here + 5 | print add_one(22) + 6 | + | + error: the variable `b` is not declared + --> input:4:42 + | + 3 | + 4 | fn add_one(a) = add_two(a) + b + | __________________________________________^ + 5 | | print add_one(22) + | |____________^ here + 6 | + |"#]], &[], ); } @@ -208,8 +250,17 @@ fn fix_bad_variable_in_function() { print quadruple(2) ", expect![[r#" - [] - "#]], + error: the variable `b` is not declared + --> input:4:32 + | + 3 | + 4 | fn double(a) = a * b + | ________________________________^ + 5 | | fn quadruple(a) = double(double(a)) + | |____________^ here + 6 | print quadruple(2) + 7 | + |"#]], &[( " fn double(a) = a * 2 @@ -222,6 +273,7 @@ fn fix_bad_variable_in_function() { expect![[r#" [ "Event: Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: parse_statements(0) } }", + "Event: Event { runtime_id: RuntimeId { counter: 0 }, kind: WillExecute { database_key: type_check_function(0) } }", ] "#]], )],