From 0f11d883fa47c0b2b757b09d0d4859f4e545125d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Fri, 10 Apr 2020 10:59:07 +0200 Subject: [PATCH] checker: fix error messages and add checker tests * checker: fix error messages * tests: fix command and ignore defect output --- .gitignore | 4 ++ vlib/v/ast/ast.v | 2 + vlib/v/checker/checker.v | 4 +- .../checker/tests/inout/checker_error_test.v | 51 +++++++++++++++++++ vlib/v/checker/tests/inout/enum_err.out | 6 +++ vlib/v/checker/tests/inout/enum_err.vv | 4 ++ vlib/v/parser/parser.v | 25 +++++++-- vlib/v/util/errors.v | 6 +-- 8 files changed, 91 insertions(+), 11 deletions(-) create mode 100644 vlib/v/checker/tests/inout/checker_error_test.v create mode 100644 vlib/v/checker/tests/inout/enum_err.out create mode 100644 vlib/v/checker/tests/inout/enum_err.vv diff --git a/.gitignore b/.gitignore index eb521220a4..2e4e78b6cb 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,7 @@ cachegrind.out.* /thirdparty/pg exe vlib/v/tests/inout/*.v +!vlib/v/tests/inout/*_test.v +vlib/v/checker/tests/inout/*.v +vlib/v/checker/tests/inout/*.c +!vlib/v/checker/tests/inout/*_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index ebc6eb9d35..5b13a31fd9 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -56,6 +56,7 @@ pub: val string is_raw bool is_c bool + pos token.Position } // 'name: $name' @@ -64,6 +65,7 @@ pub: vals []string exprs []Expr expr_fmts []string + pos token.Position mut: expr_types []table.Type } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index da48e1e244..f0917b0c9a 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1067,8 +1067,8 @@ fn expr_pos(node ast.Expr) token.Position { // ast.ParExpr { } ast.SelectorExpr { return it.pos } // ast.SizeOf { } - // ast.StringLiteral { } - // ast.StringInterLiteral { } + ast.StringLiteral { return it.pos } + ast.StringInterLiteral { return it.pos } ast.StructInit { return it.pos } // ast.Type { } // ast.TypeOf { } diff --git a/vlib/v/checker/tests/inout/checker_error_test.v b/vlib/v/checker/tests/inout/checker_error_test.v new file mode 100644 index 0000000000..a7c3350515 --- /dev/null +++ b/vlib/v/checker/tests/inout/checker_error_test.v @@ -0,0 +1,51 @@ +import os +import term + +fn test_all() { + $if windows { + return + } + mut total_errors := 0 + vexe := os.getenv('VEXE') + vroot := os.dir(vexe) + dir := os.join_path(vroot,'vlib/v/checker/tests/inout') + files := os.ls(dir) or { + panic(err) + } + tests := files.filter(it.ends_with('.vv')) + if tests.len == 0 { + println('no compiler tests found') + assert false + } + for test in tests { + path := os.join_path(dir,test) + print(test + ' ') + program := path.replace('.vv', '.v') + os.cp(path, program) or { + panic(err) + } + res := os.exec('$vexe $program') or { + panic(err) + } + mut expected := os.read_file(program.replace('.v', '') + '.out') or { + panic(err) + } + expected = expected.trim_space().replace(' \n', '\n').replace(' \r\n', '\n').replace('\r\n', '\n').trim('\n') + found := res.output.trim_space().replace(' \n', '\n').replace(' \r\n', '\n').replace('\r\n', '\n').trim('\n') + if expected != found { + println(term.red('FAIL')) + println('============') + println('expected:') + println(expected) + println('============') + println('found:') + println(found) + println('============\n') + total_errors++ + } + else { + println(term.green('OK')) + } + } + assert total_errors == 0 +} diff --git a/vlib/v/checker/tests/inout/enum_err.out b/vlib/v/checker/tests/inout/enum_err.out new file mode 100644 index 0000000000..99ded8c240 --- /dev/null +++ b/vlib/v/checker/tests/inout/enum_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/inout/enum_err.v:2:13: error: default value for enum has to be an integer + 1| enum Color { + 2| green = 'green', + ~~~~~~~ + 3| blue, + 4| } \ No newline at end of file diff --git a/vlib/v/checker/tests/inout/enum_err.vv b/vlib/v/checker/tests/inout/enum_err.vv new file mode 100644 index 0000000000..ec6b14fc29 --- /dev/null +++ b/vlib/v/checker/tests/inout/enum_err.vv @@ -0,0 +1,4 @@ +enum Color { + green = 'green', + blue, +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index f1eb44070d..5162d584c3 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1226,6 +1226,7 @@ fn (p mut Parser) if_expr() ast.IfExpr { } fn (p mut Parser) string_expr() ast.Expr { + first_pos := p.tok.position() is_raw := p.tok.kind == .name && p.tok.lit == 'r' is_cstr := p.tok.kind == .name && p.tok.lit == 'c' if is_raw || is_cstr { @@ -1233,13 +1234,20 @@ fn (p mut Parser) string_expr() ast.Expr { } mut node := ast.Expr{} val := p.tok.lit - node = ast.StringLiteral{ - val: val - is_raw: is_raw - is_c: is_cstr - } if p.peek_tok.kind != .str_dollar { p.next() + last_pos := p.tok.position() + pos := token.Position{ + line_nr: first_pos.line_nr + pos: first_pos.pos + len: last_pos.pos - first_pos.pos + } + node = ast.StringLiteral{ + val: val + is_raw: is_raw + is_c: is_cstr + pos: pos + } return node } mut exprs := []ast.Expr @@ -1275,10 +1283,17 @@ fn (p mut Parser) string_expr() ast.Expr { } efmts << efmt.join('') } + last_pos := p.tok.position() + pos := token.Position{ + line_nr: first_pos.line_nr + pos: first_pos.pos + len: last_pos.pos - first_pos.pos + } node = ast.StringInterLiteral{ vals: vals exprs: exprs expr_fmts: efmts + pos: pos } return node } diff --git a/vlib/v/util/errors.v b/vlib/v/util/errors.v index 177d755dfe..8a1929be7f 100644 --- a/vlib/v/util/errors.v +++ b/vlib/v/util/errors.v @@ -95,10 +95,8 @@ pub fn formatted_error(kind string /*error or warn*/, emsg string, filepath stri } continue } - for i in 0..pos.len { - underline := '~'.repeat(pos.len) - pointerline << if emanager.support_color { term.bold(term.blue(underline)) } else { underline } - } + underline := '~'.repeat(pos.len) + pointerline << if emanager.support_color { term.bold(term.blue(underline)) } else { underline } break } clines << ' ' + pointerline.join('')