diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index 89bd9b9df3..05a9eba271 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -366,8 +366,7 @@ fn (t Tree) errors(errors []errors.Error) &Node { obj.add_terse('message', t.string_node(e.message)) obj.add_terse('file_path', t.string_node(e.file_path)) obj.add('pos', t.pos(e.pos)) - obj.add_terse('backtrace', t.string_node(e.backtrace)) - obj.add_terse('reporter', t.enum_node(e.reporter)) + obj.add('reporter', t.enum_node(e.reporter)) errs.add_item(obj) } return errs @@ -377,8 +376,8 @@ fn (t Tree) warnings(warnings []errors.Warning) &Node { mut warns := new_array() for w in warnings { mut obj := new_object() - obj.add('message', t.string_node(w.message)) - obj.add('file_path', t.string_node(w.file_path)) + obj.add_terse('message', t.string_node(w.message)) + obj.add_terse('file_path', t.string_node(w.file_path)) obj.add('pos', t.pos(w.pos)) obj.add('reporter', t.enum_node(w.reporter)) warns.add_item(obj) @@ -390,8 +389,8 @@ fn (t Tree) notices(notices []errors.Notice) &Node { mut notice_array := new_array() for n in notices { mut obj := new_object() - obj.add('message', t.string_node(n.message)) - obj.add('file_path', t.string_node(n.file_path)) + obj.add_terse('message', t.string_node(n.message)) + obj.add_terse('file_path', t.string_node(n.file_path)) obj.add('pos', t.pos(n.pos)) obj.add('reporter', t.enum_node(n.reporter)) notice_array.add_item(obj) diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index b17b98b14d..212a54ddfe 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -461,11 +461,7 @@ pub fn (mut b Builder) print_warnings_and_errors() { } else { 'notice:' } - ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) - eprintln(ferror) - if err.details.len > 0 { - eprintln('Details: $err.details') - } + util.show_compiler_message(kind, err.CompilerMessage) } } } @@ -477,11 +473,7 @@ pub fn (mut b Builder) print_warnings_and_errors() { } else { 'error:' } - ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) - eprintln(ferror) - if err.details.len > 0 { - eprintln('Details: $err.details') - } + util.show_compiler_message(kind, err.CompilerMessage) } } @@ -493,11 +485,7 @@ pub fn (mut b Builder) print_warnings_and_errors() { } else { 'warning:' } - ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) - eprintln(ferror) - if err.details.len > 0 { - eprintln('Details: $err.details') - } + util.show_compiler_message(kind, err.CompilerMessage) } } } @@ -522,11 +510,7 @@ pub fn (mut b Builder) print_warnings_and_errors() { } else { 'notice:' } - ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) - eprintln(ferror) - if err.details.len > 0 { - eprintln('Details: $err.details') - } + util.show_compiler_message(kind, err.CompilerMessage) } } if b.checker.nr_warnings > 0 && !b.pref.skip_warnings { @@ -536,11 +520,7 @@ pub fn (mut b Builder) print_warnings_and_errors() { } else { 'warning:' } - ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) - eprintln(ferror) - if err.details.len > 0 { - eprintln('Details: $err.details') - } + util.show_compiler_message(kind, err.CompilerMessage) } } // @@ -554,11 +534,7 @@ pub fn (mut b Builder) print_warnings_and_errors() { } else { 'error:' } - ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) - eprintln(ferror) - if err.details.len > 0 { - eprintln('Details: $err.details') - } + util.show_compiler_message(kind, err.CompilerMessage) } b.show_total_warns_and_errors_stats() exit(1) @@ -586,12 +562,15 @@ pub fn (mut b Builder) print_warnings_and_errors() { } } if redefines.len > 0 { - ferror := util.formatted_error('builder error:', 'redefinition of function `$fn_name`', - '', token.Pos{}) - eprintln(ferror) + util.show_compiler_message('builder error:', + message: 'redefinition of function `$fn_name`' + ) for redefine in redefines { - eprintln(util.formatted_error('conflicting declaration:', redefine.fheader, - redefine.fpath, redefine.f.pos)) + util.show_compiler_message('conflicting declaration:', + message: redefine.fheader + file_path: redefine.fpath + pos: redefine.f.pos + ) } total_conflicts++ } @@ -612,8 +591,7 @@ struct FunctionRedefinition { pub fn (b &Builder) error_with_pos(s string, fpath string, pos token.Pos) errors.Error { if !b.pref.check_only { - ferror := util.formatted_error('builder error:', s, fpath, pos) - eprintln(ferror) + util.show_compiler_message('builder error:', pos: pos, file_path: fpath, message: s) exit(1) } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 0ae4eb963f..0642ed5875 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3742,11 +3742,12 @@ fn (mut c Checker) warn_or_error(message string, pos token.Pos, warn bool) { } if !warn { if c.pref.fatal_errors { - ferror := util.formatted_error('error:', message, c.file.path, pos) - eprintln(ferror) - if details.len > 0 { - eprintln('Details: $details') - } + util.show_compiler_message('error:', errors.CompilerMessage{ + pos: pos + file_path: c.file.path + message: message + details: details + }) exit(1) } c.nr_errors++ diff --git a/vlib/v/errors/errors.v b/vlib/v/errors/errors.v index fea39f8430..3eb392c745 100644 --- a/vlib/v/errors/errors.v +++ b/vlib/v/errors/errors.v @@ -10,31 +10,23 @@ pub enum Reporter { gen } -[minify] -pub struct Error { +pub struct CompilerMessage { pub: message string details string file_path string pos token.Pos - backtrace string reporter Reporter } +pub struct Error { + CompilerMessage +} + pub struct Warning { -pub: - message string - details string - file_path string - pos token.Pos - reporter Reporter + CompilerMessage } pub struct Notice { -pub: - message string - details string - file_path string - pos token.Pos - reporter Reporter + CompilerMessage } diff --git a/vlib/v/eval/expr.v b/vlib/v/eval/expr.v index a91b394c03..7e0c854d1e 100644 --- a/vlib/v/eval/expr.v +++ b/vlib/v/eval/expr.v @@ -393,8 +393,11 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object { } } else if e.table.sym(expr.typ).kind in [.interface_, .sum_type] { if e.pref.is_verbose { - eprintln(util.formatted_error('warning:', 'sumtype or interface casts return void currently', - e.cur_file, expr.pos)) + util.show_compiler_message('warning:', + pos: expr.pos + file_path: e.cur_file + message: 'sumtype or interface casts return void currently' + ) } } else { e.error('unknown cast: ${e.table.sym(expr.expr_type).str()} to ${e.table.sym(expr.typ).str()}') diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 26dd6236cc..d932b23c45 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4860,8 +4860,7 @@ fn verror(s string) { [noreturn] fn (g &Gen) error(s string, pos token.Pos) { - ferror := util.formatted_error('cgen error:', s, g.file.path, pos) - eprintln(ferror) + util.show_compiler_message('cgen error:', pos: pos, file_path: g.file.path, message: s) exit(1) } diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index 2ab29864b5..e7bdf17649 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -1080,8 +1080,7 @@ pub fn (mut g Gen) n_error(s string) { pub fn (mut g Gen) warning(s string, pos token.Pos) { if g.pref.output_mode == .stdout { - werror := util.formatted_error('warning', s, g.pref.path, pos) - eprintln(werror) + util.show_compiler_message('warning:', pos: pos, file_path: g.pref.path, message: s) } else { g.warnings << errors.Warning{ file_path: g.pref.path @@ -1098,8 +1097,7 @@ pub fn (mut g Gen) v_error(s string, pos token.Pos) { // of guessed from the pref.path ... mut kind := 'error:' if g.pref.output_mode == .stdout { - ferror := util.formatted_error(kind, s, g.pref.path, pos) - eprintln(ferror) + util.show_compiler_message(kind, pos: pos, file_path: g.pref.path, message: s) exit(1) } else { g.errors << errors.Error{ diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 3b3ebd6956..2a905b7687 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1870,8 +1870,7 @@ pub fn (mut p Parser) note(s string) { pub fn (mut p Parser) error_with_pos(s string, pos token.Pos) ast.NodeError { mut kind := 'error:' if p.pref.fatal_errors { - ferror := util.formatted_error(kind, s, p.file_name, pos) - eprintln(ferror) + util.show_compiler_message(kind, pos: pos, file_path: p.file_name, message: s) exit(1) } if p.pref.output_mode == .stdout && !p.pref.check_only { @@ -1879,8 +1878,7 @@ pub fn (mut p Parser) error_with_pos(s string, pos token.Pos) ast.NodeError { print_backtrace() kind = 'parser error:' } - ferror := util.formatted_error(kind, s, p.file_name, pos) - eprintln(ferror) + util.show_compiler_message(kind, pos: pos, file_path: p.file_name, message: s) exit(1) } else { p.errors << errors.Error{ @@ -1912,8 +1910,7 @@ pub fn (mut p Parser) error_with_pos(s string, pos token.Pos) ast.NodeError { pub fn (mut p Parser) error_with_error(error errors.Error) { mut kind := 'error:' if p.pref.fatal_errors { - ferror := util.formatted_error(kind, error.message, error.file_path, error.pos) - eprintln(ferror) + util.show_compiler_message(kind, error.CompilerMessage) exit(1) } if p.pref.output_mode == .stdout && !p.pref.check_only { @@ -1921,8 +1918,7 @@ pub fn (mut p Parser) error_with_error(error errors.Error) { print_backtrace() kind = 'parser error:' } - ferror := util.formatted_error(kind, error.message, error.file_path, error.pos) - eprintln(ferror) + util.show_compiler_message(kind, error.CompilerMessage) exit(1) } else { if p.pref.message_limit >= 0 && p.errors.len >= p.pref.message_limit { @@ -1949,8 +1945,7 @@ pub fn (mut p Parser) warn_with_pos(s string, pos token.Pos) { return } if p.pref.output_mode == .stdout && !p.pref.check_only { - ferror := util.formatted_error('warning:', s, p.file_name, pos) - eprintln(ferror) + util.show_compiler_message('warning:', pos: pos, file_path: p.file_name, message: s) } else { if p.pref.message_limit >= 0 && p.warnings.len >= p.pref.message_limit { p.should_abort = true @@ -1973,8 +1968,7 @@ pub fn (mut p Parser) note_with_pos(s string, pos token.Pos) { return } if p.pref.output_mode == .stdout && !p.pref.check_only { - ferror := util.formatted_error('notice:', s, p.file_name, pos) - eprintln(ferror) + util.show_compiler_message('notice:', pos: pos, file_path: p.file_name, message: s) } else { p.notices << errors.Notice{ file_path: p.file_name diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 8e89b26a38..736ca0c909 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1480,7 +1480,7 @@ pub fn (mut s Scanner) note(msg string) { pos: s.pos } if s.pref.output_mode == .stdout && !s.pref.check_only { - eprintln(util.formatted_error('notice:', msg, s.file_path, pos)) + util.show_compiler_message('notice:', pos: pos, file_path: s.file_path, message: msg) } else { s.notices << errors.Notice{ file_path: s.file_path @@ -1497,14 +1497,13 @@ pub fn (mut s Scanner) add_error_detail(msg string) { } pub fn (mut s Scanner) add_error_detail_with_pos(msg string, pos token.Pos) { - details := util.formatted_error('details:', msg, s.file_path, pos) - s.add_error_detail(details) + s.add_error_detail(util.formatted_error('details:', msg, s.file_path, pos)) } fn (mut s Scanner) eat_details() string { mut details := '' if s.error_details.len > 0 { - details = s.error_details.join('\n') + details = '\n' + s.error_details.join('\n') s.error_details = [] } return details @@ -1522,10 +1521,12 @@ pub fn (mut s Scanner) warn(msg string) { } details := s.eat_details() if s.pref.output_mode == .stdout && !s.pref.check_only { - eprintln(util.formatted_error('warning:', msg, s.file_path, pos)) - if details.len > 0 { - eprintln(details) - } + util.show_compiler_message('warning:', + pos: pos + file_path: s.file_path + message: msg + details: details + ) } else { if s.pref.message_limit >= 0 && s.warnings.len >= s.pref.message_limit { s.should_abort = true @@ -1549,17 +1550,21 @@ pub fn (mut s Scanner) error(msg string) { } details := s.eat_details() if s.pref.output_mode == .stdout && !s.pref.check_only { - eprintln(util.formatted_error('error:', msg, s.file_path, pos)) - if details.len > 0 { - eprintln(details) - } + util.show_compiler_message('error:', + pos: pos + file_path: s.file_path + message: msg + details: details + ) exit(1) } else { if s.pref.fatal_errors { - eprintln(util.formatted_error('error:', msg, s.file_path, pos)) - if details.len > 0 { - eprintln(details) - } + util.show_compiler_message('error:', + pos: pos + file_path: s.file_path + message: msg + details: details + ) exit(1) } if s.pref.message_limit >= 0 && s.errors.len >= s.pref.message_limit { diff --git a/vlib/v/scanner/tests/empty_character_literal_err.out b/vlib/v/scanner/tests/empty_character_literal_err.out index 636a06566c..1c47473954 100644 --- a/vlib/v/scanner/tests/empty_character_literal_err.out +++ b/vlib/v/scanner/tests/empty_character_literal_err.out @@ -4,6 +4,7 @@ vlib/v/scanner/tests/empty_character_literal_err.vv:2:8: error: invalid empty ch | ^ 3 | println(a) 4 | } +Details: vlib/v/scanner/tests/empty_character_literal_err.vv:2:7: details: use quotes for strings, backticks for characters 1 | fn main() { 2 | a := `` diff --git a/vlib/v/scanner/tests/unfinished_string_literal_err.out b/vlib/v/scanner/tests/unfinished_string_literal_err.out index 65b9377ceb..d971cd10a0 100644 --- a/vlib/v/scanner/tests/unfinished_string_literal_err.out +++ b/vlib/v/scanner/tests/unfinished_string_literal_err.out @@ -1,6 +1,7 @@ vlib/v/scanner/tests/unfinished_string_literal_err.vv:7:1: error: unfinished string literal 5 | 6 | zzzz +Details: vlib/v/scanner/tests/unfinished_string_literal_err.vv:4:6: details: literal started here 2 | a := 'abc' 3 | println(a) diff --git a/vlib/v/util/errors.v b/vlib/v/util/errors.v index d18c8f4f00..e330b8d160 100644 --- a/vlib/v/util/errors.v +++ b/vlib/v/util/errors.v @@ -7,6 +7,7 @@ module util import os import strings import term +import v.errors import v.token import v.mathutil as mu @@ -66,6 +67,9 @@ fn color(kind string, msg string) string { if kind.contains('notice') { return term.yellow(msg) } + if kind.contains('details') { + return term.bright_blue(msg) + } return term.magenta(msg) } @@ -189,3 +193,11 @@ pub fn vlines_escape_path(path string, ccompiler string) string { } return cescaped_path(os.real_path(path)) } + +pub fn show_compiler_message(kind string, err errors.CompilerMessage) { + ferror := formatted_error(kind, err.message, err.file_path, err.pos) + eprintln(ferror) + if err.details.len > 0 { + eprintln(bold('Details: ') + color('details', err.details)) + } +}