From 1199646e29ded4d14212576918932a0bce35ab4e Mon Sep 17 00:00:00 2001 From: John Doty Date: Thu, 15 Feb 2024 06:36:14 -0800 Subject: [PATCH] [fine] File name in error messages Going to need to normalize that name though, because right now it really *really* sucks to have a big \\?\ kinda name. Probably normalize it relative to the base directory. --- fine/src/lib.rs | 3 +- fine/src/semantics.rs | 33 ++++++++++++++----- .../expression/errors/assignment_errors.fine | 8 ++--- .../expression/errors/broken_conditional.fine | 2 +- .../errors/class_as_a_variable.fine | 2 +- .../errors/class_duplicate_fields.fine | 2 +- .../tests/expression/errors/class_errors.fine | 12 +++---- .../errors/duplicate_arguments.fine | 2 +- fine/tests/expression/errors/duplicates.fine | 6 ++-- fine/tests/expression/errors/if_not_bool.fine | 2 +- .../expression/errors/if_requires_else.fine | 2 +- .../expression/errors/locals_in_globals.fine | 2 +- .../errors/no_method_variables.fine | 2 +- .../errors/return_statement_mismatch.fine | 2 +- .../expression/errors/while_not_bool.fine | 2 +- .../expression/errors/wild_member_access.fine | 4 +-- 16 files changed, 52 insertions(+), 34 deletions(-) diff --git a/fine/src/lib.rs b/fine/src/lib.rs index a9ba0872..b340968e 100644 --- a/fine/src/lib.rs +++ b/fine/src/lib.rs @@ -105,7 +105,8 @@ impl Runtime { ModuleSource::SourceText(source) => { let source: Rc = source.into(); let (tree, lines) = parse(&source); - let semantics = Rc::new(Semantics::new(source, tree, lines)); + let semantics = + Rc::new(Semantics::new(name.clone().into(), source, tree, lines)); let mut normalized_imports = Vec::new(); for import in semantics.imports() { diff --git a/fine/src/semantics.rs b/fine/src/semantics.rs index d8b21734..16e9ce5c 100644 --- a/fine/src/semantics.rs +++ b/fine/src/semantics.rs @@ -23,28 +23,36 @@ use std::{ // that will have to wait for now #[derive(Clone, PartialEq, Eq)] pub struct Error { + pub file: Rc, pub start: (usize, usize), pub end: (usize, usize), pub message: String, } impl Error { - pub fn new(line: usize, column: usize, message: T) -> Self + pub fn new(file: Rc, line: usize, column: usize, message: T) -> Self where T: ToString, { Error { + file, start: (line, column), end: (line, column), message: message.to_string(), } } - pub fn new_spanned(start: (usize, usize), end: (usize, usize), message: T) -> Self + pub fn new_spanned( + file: Rc, + start: (usize, usize), + end: (usize, usize), + message: T, + ) -> Self where T: ToString, { Error { + file, start, end, message: message.to_string(), @@ -60,7 +68,11 @@ impl fmt::Debug for Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}:{}: {}", self.start.0, self.start.1, self.message) + write!( + f, + "{}:{}:{}: {}", + self.file, self.start.0, self.start.1, self.message + ) } } @@ -622,6 +634,7 @@ enum Incremental { } pub struct Semantics { + file: Rc, source: Rc, syntax_tree: Rc, lines: Rc, @@ -641,7 +654,7 @@ pub struct Semantics { } impl Semantics { - pub fn new(source: Rc, tree: Rc, lines: Rc) -> Self { + pub fn new(file: Rc, source: Rc, tree: Rc, lines: Rc) -> Self { let mut logical_parents = vec![None; tree.len()]; if let Some(root) = tree.root() { set_logical_parents(&mut logical_parents, &tree, root, None); @@ -650,6 +663,7 @@ impl Semantics { let root_environment = Environment::new(None, Location::Module); let mut semantics = Semantics { + file, source, syntax_tree: tree.clone(), lines, @@ -730,9 +744,12 @@ impl Semantics { { let start = self.lines.position(start); let end = self.lines.position(end); - self.errors - .borrow_mut() - .push(Error::new_spanned(start, end, error.to_string())); + self.errors.borrow_mut().push(Error::new_spanned( + self.file.clone(), + start, + end, + error.to_string(), + )); } fn report_error_tree(&self, tree: &Tree, error: T) @@ -2801,7 +2818,7 @@ mod tests { pub fn ice() { let source: Rc = "1+1".into(); let (tree, lines) = parse(&source); - let semantics = Semantics::new(source, tree.clone(), lines); + let semantics = Semantics::new("__test__".into(), source, tree.clone(), lines); semantics.internal_compiler_error(tree.root(), "oh no"); } } diff --git a/fine/tests/expression/errors/assignment_errors.fine b/fine/tests/expression/errors/assignment_errors.fine index 0f6782cf..bba8eb9c 100644 --- a/fine/tests/expression/errors/assignment_errors.fine +++ b/fine/tests/expression/errors/assignment_errors.fine @@ -14,7 +14,7 @@ fun wrong() { } // @expect-errors: -// | 7:4: cannot assign a value of type 'string' to type 'f64' -// | 8:4: cannot assign a value of type 'f64' to type 'string' -// | 11:4: cannot assign a value of type 'f64' to type 'string' -// | 13:2: cannot assign a new value to a function declaration +// | __test__:7:4: cannot assign a value of type 'string' to type 'f64' +// | __test__:8:4: cannot assign a value of type 'f64' to type 'string' +// | __test__:11:4: cannot assign a value of type 'f64' to type 'string' +// | __test__:13:2: cannot assign a new value to a function declaration diff --git a/fine/tests/expression/errors/broken_conditional.fine b/fine/tests/expression/errors/broken_conditional.fine index dbcfe35c..e4a9508a 100644 --- a/fine/tests/expression/errors/broken_conditional.fine +++ b/fine/tests/expression/errors/broken_conditional.fine @@ -4,4 +4,4 @@ fun test() { // NOTE: These errors should be better // @expect-errors: -// | 2:10: Error at 'true': expected a block after `if` +// | __test__:2:10: Error at 'true': expected a block after `if` diff --git a/fine/tests/expression/errors/class_as_a_variable.fine b/fine/tests/expression/errors/class_as_a_variable.fine index 83540878..e7bad9f8 100644 --- a/fine/tests/expression/errors/class_as_a_variable.fine +++ b/fine/tests/expression/errors/class_as_a_variable.fine @@ -5,4 +5,4 @@ fun test() -> f64 { } // @expect-errors: -// | 4:6: cannot apply binary operator '+' to expressions of type 'class Foo' (on the left) and 'f64' (on the right) \ No newline at end of file +// | __test__:4:6: cannot apply binary operator '+' to expressions of type 'class Foo' (on the left) and 'f64' (on the right) \ No newline at end of file diff --git a/fine/tests/expression/errors/class_duplicate_fields.fine b/fine/tests/expression/errors/class_duplicate_fields.fine index d8d59f60..051412c7 100644 --- a/fine/tests/expression/errors/class_duplicate_fields.fine +++ b/fine/tests/expression/errors/class_duplicate_fields.fine @@ -4,4 +4,4 @@ class Foo { } // @expect-errors: -// | 3:2: duplicate definition of field 'x' +// | __test__:3:2: duplicate definition of field 'x' diff --git a/fine/tests/expression/errors/class_errors.fine b/fine/tests/expression/errors/class_errors.fine index 678cca7b..25e26048 100644 --- a/fine/tests/expression/errors/class_errors.fine +++ b/fine/tests/expression/errors/class_errors.fine @@ -16,9 +16,9 @@ fun test() { } // @expect-errors: -// | 7:12: missing an initializer for field y -// | 8:12: missing an initializer for field x -// | 9:41: Point instance does not have a field named z -// | 10:32: field x is of type f64, but this expression generates a string -// | 12:32: cannot find value x here -// | 15:31: field x is of type f64, but this expression generates a string +// | __test__:7:12: missing an initializer for field y +// | __test__:8:12: missing an initializer for field x +// | __test__:9:41: Point instance does not have a field named z +// | __test__:10:32: field x is of type f64, but this expression generates a string +// | __test__:12:32: cannot find value x here +// | __test__:15:31: field x is of type f64, but this expression generates a string diff --git a/fine/tests/expression/errors/duplicate_arguments.fine b/fine/tests/expression/errors/duplicate_arguments.fine index 071d59b4..73d32c47 100644 --- a/fine/tests/expression/errors/duplicate_arguments.fine +++ b/fine/tests/expression/errors/duplicate_arguments.fine @@ -1,4 +1,4 @@ fun something(x: f64, x: f64) {} // @expect-errors: -// | 1:22: duplicate definition of parameter 'x' +// | __test__:1:22: duplicate definition of parameter 'x' diff --git a/fine/tests/expression/errors/duplicates.fine b/fine/tests/expression/errors/duplicates.fine index f9d1f975..5d780ff1 100644 --- a/fine/tests/expression/errors/duplicates.fine +++ b/fine/tests/expression/errors/duplicates.fine @@ -11,6 +11,6 @@ class Bar {} class Bar {} // @expect-errors: -// | 3:2: duplicate definition of function 'foo' -// | 8:0: duplicate definition of function 'nested' -// | 11:0: duplicate definition of class 'Bar' \ No newline at end of file +// | __test__:3:2: duplicate definition of function 'foo' +// | __test__:8:0: duplicate definition of function 'nested' +// | __test__:11:0: duplicate definition of class 'Bar' \ No newline at end of file diff --git a/fine/tests/expression/errors/if_not_bool.fine b/fine/tests/expression/errors/if_not_bool.fine index c72335be..43aadb5f 100644 --- a/fine/tests/expression/errors/if_not_bool.fine +++ b/fine/tests/expression/errors/if_not_bool.fine @@ -1,4 +1,4 @@ if 23 { "what" } else { "the" } // @expect-errors: -// | 1:3: this condition produces 'f64', but must produce bool +// | __test__:1:3: this condition produces 'f64', but must produce bool diff --git a/fine/tests/expression/errors/if_requires_else.fine b/fine/tests/expression/errors/if_requires_else.fine index 8f60f676..47d93660 100644 --- a/fine/tests/expression/errors/if_requires_else.fine +++ b/fine/tests/expression/errors/if_requires_else.fine @@ -1,4 +1,4 @@ if (if false { true }) { 32 } else { 23 } // @expect-errors: -// | 1:3: this condition produces 'nothing or bool', but must produce bool +// | __test__:1:3: this condition produces 'nothing or bool', but must produce bool diff --git a/fine/tests/expression/errors/locals_in_globals.fine b/fine/tests/expression/errors/locals_in_globals.fine index 0d975d6d..344e27c2 100644 --- a/fine/tests/expression/errors/locals_in_globals.fine +++ b/fine/tests/expression/errors/locals_in_globals.fine @@ -9,4 +9,4 @@ fun foo() -> f64 { } // @expect-errors: -// | 8:2: cannot find value y here \ No newline at end of file +// | __test__:8:2: cannot find value y here \ No newline at end of file diff --git a/fine/tests/expression/errors/no_method_variables.fine b/fine/tests/expression/errors/no_method_variables.fine index a2a85579..d2141fa6 100644 --- a/fine/tests/expression/errors/no_method_variables.fine +++ b/fine/tests/expression/errors/no_method_variables.fine @@ -8,4 +8,4 @@ fun test() { } // @expect-errors: -// | 7:6: methods cannot be assigned to variables +// | __test__:7:6: methods cannot be assigned to variables diff --git a/fine/tests/expression/errors/return_statement_mismatch.fine b/fine/tests/expression/errors/return_statement_mismatch.fine index 521d2772..5cbf9a67 100644 --- a/fine/tests/expression/errors/return_statement_mismatch.fine +++ b/fine/tests/expression/errors/return_statement_mismatch.fine @@ -6,4 +6,4 @@ fun test() -> f64 { } // @expect-errors: -// | 3:4: callers of this function expect a value of type 'f64' but this statement returns a value of type 'string' \ No newline at end of file +// | __test__:3:4: callers of this function expect a value of type 'f64' but this statement returns a value of type 'string' \ No newline at end of file diff --git a/fine/tests/expression/errors/while_not_bool.fine b/fine/tests/expression/errors/while_not_bool.fine index f0d19504..19c89f4c 100644 --- a/fine/tests/expression/errors/while_not_bool.fine +++ b/fine/tests/expression/errors/while_not_bool.fine @@ -3,4 +3,4 @@ fun test() { } // @expect-errors: -// | 2:8: this condition produces 'f64', but must produce bool +// | __test__:2:8: this condition produces 'f64', but must produce bool diff --git a/fine/tests/expression/errors/wild_member_access.fine b/fine/tests/expression/errors/wild_member_access.fine index ae5600f5..c76ed1d5 100644 --- a/fine/tests/expression/errors/wild_member_access.fine +++ b/fine/tests/expression/errors/wild_member_access.fine @@ -8,5 +8,5 @@ fun test() { } // @expect-errors: -// | 7:12: Error at '{': expected an identifier after a '.' in member access -// | 7:26: cannot find value foo here +// | __test__:7:12: Error at '{': expected an identifier after a '.' in member access +// | __test__:7:26: cannot find value foo here