From 5f0ad0f562003189fad84afe12808e6be3a38a02 Mon Sep 17 00:00:00 2001 From: Ned Palacios Date: Sun, 10 May 2020 17:26:57 +0800 Subject: [PATCH] compiler: add output mode for errors and warnings, support for `-silent` flag --- cmd/v/v.v | 3 +++ vlib/v/ast/ast.v | 3 +++ vlib/v/builder/builder.v | 8 +++++++ vlib/v/checker/checker.v | 8 +++++-- vlib/v/parser/parser.v | 51 ++++++++++++++++++++++++++++++---------- vlib/v/pref/pref.v | 6 +++++ 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/cmd/v/v.v b/cmd/v/v.v index f15c328ed0..9f80568fc2 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -124,6 +124,9 @@ fn parse_args(args []string) (&pref.Preferences, string) { '-v' { res.is_verbose = true } + '-silent' { + res.output_mode = .silent + } '-cg' { res.is_debug = true } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 9614c9ec15..0196afb5b7 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -5,6 +5,7 @@ module ast import v.token import v.table +import v.errors pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl @@ -306,6 +307,8 @@ pub: global_scope &Scope pub mut: imports []Import + errors []errors.Error + warnings []errors.Warning } pub struct IdentFn { diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 1a0ce32e97..c3d457642a 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -211,6 +211,14 @@ pub fn (b Builder) find_module_path(mod, fpath string) ?string { } fn (b &Builder) print_warnings_and_errors() { + if b.pref.output_mode == .silent { + if b.checker.nr_errors > 0 { + exit(1) + } + + return + } + if b.pref.is_verbose && b.checker.nr_warnings > 1 { println('$b.checker.nr_warnings warnings') } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index ce731b7aff..64812160a8 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2204,21 +2204,25 @@ fn (mut c Checker) warn_or_error(message string, pos token.Position, warn bool) // } if warn { c.nr_warnings++ - c.warnings << errors.Warning{ + wrn := errors.Warning{ reporter: errors.Reporter.checker pos: pos file_path: c.file.path message: message } + c.file.warnings << wrn + c.warnings << wrn } else { c.nr_errors++ if pos.line_nr !in c.error_lines { - c.errors << errors.Error{ + err := errors.Error{ reporter: errors.Reporter.checker pos: pos file_path: c.file.path message: message } + c.file.errors << err + c.errors << err c.error_lines << pos.line_nr } } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 195bd8a1de..dbe7521461 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -9,6 +9,7 @@ import v.token import v.table import v.pref import v.util +import v.errors import term import os @@ -43,6 +44,8 @@ mut: inside_match_case bool // to separate `match_expr { }` from `Struct{}` is_stmt_ident bool // true while the beginning of a statement is an ident/selector expecting_type bool // `is Type`, expecting type + errors []errors.Error + warnings []errors.Warning } // for tests @@ -79,6 +82,8 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme start_pos: 0 parent: 0 } + errors: []errors.Error{}, + warnings: []errors.Warning{}, global_scope: global_scope } // comments_mode: comments_mode @@ -121,7 +126,9 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme imports: p.ast_imports stmts: stmts scope: p.scope - global_scope: p.global_scope + global_scope: p.global_scope, + errors: p.errors, + warnings: p.warnings } } @@ -549,28 +556,46 @@ fn (mut p Parser) range_expr(low ast.Expr) ast.Expr { return node } */ -pub fn (p &Parser) error(s string) { +pub fn (mut p Parser) error(s string) { p.error_with_pos(s, p.tok.position()) } -pub fn (p &Parser) warn(s string) { +pub fn (mut p Parser) warn(s string) { p.warn_with_pos(s, p.tok.position()) } -pub fn (p &Parser) error_with_pos(s string, pos token.Position) { +pub fn (mut p Parser) error_with_pos(s string, pos token.Position) { mut kind := 'error:' - if p.pref.is_verbose { - print_backtrace() - kind = 'parser error:' + if p.pref.output_mode == .stdout { + if p.pref.is_verbose { + print_backtrace() + kind = 'parser error:' + } + ferror := util.formatted_error(kind, s, p.file_name, pos) + eprintln(ferror) + exit(1) + } else { + p.errors << errors.Error{ + file_path: p.file_name, + pos: pos, + reporter: .parser, + message: s + } } - ferror := util.formatted_error(kind, s, p.file_name, pos) - eprintln(ferror) - exit(1) } -pub fn (p &Parser) warn_with_pos(s string, pos token.Position) { - ferror := util.formatted_error('warning:', s, p.file_name, pos) - eprintln(ferror) +pub fn (mut p Parser) warn_with_pos(s string, pos token.Position) { + if p.pref.output_mode == .stdout { + ferror := util.formatted_error('warning:', s, p.file_name, pos) + eprintln(ferror) + } else { + p.warnings << errors.Warning{ + file_path: p.file_name, + pos: pos, + reporter: .parser, + message: s + } + } } pub fn (mut p Parser) parse_ident(is_c, is_js bool) ast.Ident { diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 77ca994002..4f5f36579e 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -12,6 +12,11 @@ pub enum BuildMode { build_module } +pub enum OutputMode { + stdout + silent +} + pub enum Backend { c // The (default) C backend js // The JavaScript backend @@ -23,6 +28,7 @@ pub mut: os OS // the OS to compile for backend Backend build_mode BuildMode + output_mode OutputMode = .stdout //verbosity VerboseLevel is_verbose bool // nofmt bool // disable vfmt