diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 89f40fd506..85aa0940bc 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -10,6 +10,7 @@ import ( v.vmod v.checker v.parser + v.scanner v.gen v.gen.x64 ) @@ -56,6 +57,7 @@ pub fn (b mut Builder) gen_c(v_files []string) string { check_time := t2 - t1 b.info('CHECK: ${check_time}ms') if b.checker.nr_errors > 0 { + b.print_errors(b.checker.errors) exit(1) } // println('starting cgen...') @@ -267,6 +269,14 @@ pub fn (b Builder) find_module_path(mod string, fpath string) ?string { return error('module "$mod" not found in:\n$smodule_lookup_paths') } +fn (b &Builder) print_errors(errors []scanner.Error) { + for err in errors { + kind := if b.pref.is_verbose { '$err.reporter error #$b.checker.nr_errors:' } else { 'error:' } + ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) + eprintln(ferror) + } +} + fn verror(s string) { util.verror('builder error', s) } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3c8b254fa6..f4ec10ef73 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -10,6 +10,7 @@ import ( v.token v.pref v.util + v.scanner os ) @@ -22,7 +23,8 @@ pub struct Checker { mut: file ast.File nr_errors int - errors []string + errors []scanner.Error + warnings []scanner.Warning error_lines []int // to avoid printing multiple errors for the same line expected_type table.Type fn_return_type table.Type // current function's return type @@ -49,7 +51,7 @@ pub fn (c mut Checker) check(ast_file ast.File) { } } -pub fn (c mut Checker) check2(ast_file ast.File) []string { +pub fn (c mut Checker) check2(ast_file ast.File) []scanner.Error { c.file = ast_file for stmt in ast_file.stmts { c.stmt(stmt) @@ -1542,37 +1544,34 @@ pub fn (c mut Checker) warn(s string, pos token.Position) { c.warn_or_error(s, pos, allow_warnings) // allow warnings only in dev builds } -pub fn (c mut Checker) error(s string, pos token.Position) { - c.warn_or_error(s, pos, false) +pub fn (c mut Checker) error(message string, pos token.Position) { + c.warn_or_error(message, pos, false) } -fn (c mut Checker) warn_or_error(s string, pos token.Position, warn bool) { +fn (c mut Checker) warn_or_error(message string, pos token.Position, warn bool) { + // add backtrace to issue struct, how? + // if c.pref.is_verbose { + // print_backtrace() + // } if !warn { c.nr_errors++ - } - // if c.pref.is_verbose { - if c.pref.is_verbose { - print_backtrace() - } - typ := if warn { 'warning' } else { 'error' } - kind := if c.pref.is_verbose { 'checker $typ #$c.nr_errors:' } else { '$typ:' } - ferror := util.formatted_error(kind, s, c.file.path, pos) - c.errors << ferror - if !(pos.line_nr in c.error_lines) { - if warn { - println(ferror) - } else { - eprintln(ferror) + if !(pos.line_nr in c.error_lines) { + c.errors << scanner.Error{ + reporter: scanner.Reporter.checker + pos: pos + file_path: c.file.path + message: message + } + c.error_lines << pos.line_nr } - } - if !warn { - c.error_lines << pos.line_nr - } - if c.pref.is_verbose { - println('\n\n') - } - if c.nr_errors >= max_nr_errors { - exit(1) + } else { + c.warnings << scanner.Warning{ + reporter: scanner.Reporter.checker + pos: pos + file_path: c.file.path + message: message + } + } } diff --git a/vlib/v/scanner/error.v b/vlib/v/scanner/error.v new file mode 100644 index 0000000000..49a963aef3 --- /dev/null +++ b/vlib/v/scanner/error.v @@ -0,0 +1,18 @@ +module scanner + +import v.token + +pub enum Reporter { + scanner + parser + checker + gen +} + +pub struct Error { + message string + file_path string + pos token.Position + reporter Reporter + backtrace string +} diff --git a/vlib/v/scanner/warning.v b/vlib/v/scanner/warning.v new file mode 100644 index 0000000000..273ca4b93b --- /dev/null +++ b/vlib/v/scanner/warning.v @@ -0,0 +1,10 @@ +module scanner + +import v.token + +pub struct Warning { + message string + file_path string + pos token.Position + reporter Reporter +}