From 81ed6ad2a162d39079b60a60da891dc60120e75e Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 30 Apr 2020 18:17:31 +0800 Subject: [PATCH] checker: check duplicate consts --- vlib/v/checker/checker.v | 7 ++++++- vlib/v/checker/tests/const_field_name_duplicate_err.out | 7 +++++++ vlib/v/checker/tests/const_field_name_duplicate_err.vv | 7 +++++++ .../checker/tests/multi_const_field_name_duplicate_err.out | 6 ++++++ .../checker/tests/multi_const_field_name_duplicate_err.vv | 5 +++++ vlib/v/parser/parser.v | 3 ++- 6 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/const_field_name_duplicate_err.out create mode 100644 vlib/v/checker/tests/const_field_name_duplicate_err.vv create mode 100644 vlib/v/checker/tests/multi_const_field_name_duplicate_err.out create mode 100644 vlib/v/checker/tests/multi_const_field_name_duplicate_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index e1356d5489..b3ca5f4ca6 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -29,6 +29,7 @@ mut: fn_return_type table.Type // current function's return type const_decl string const_deps []string + const_names []string pref &pref.Preferences // Preferences shared from V struct in_for_count int // if checker is currently in an for loop // checked_ident string // to avoid infinit checker loops @@ -1271,6 +1272,10 @@ fn (mut c Checker) stmt(node ast.Stmt) { mut field_names := []string{} mut field_order := []int{} for i, field in it.fields { + if field.name in c.const_names { + c.error('field name `$field.name` duplicate', field.pos) + } + c.const_names << field.name field_names << field.name field_order << i } @@ -1873,7 +1878,7 @@ pub fn (mut c Checker) if_expr(node mut ast.IfExpr) table.Type { t := c.expr(it.expr) if is_ternary && t != first_typ { c.error('mismatched types `${c.table.type_to_str(first_typ)}` and `${c.table.type_to_str(t)}`', node.pos) - } + } node.typ = t return t } diff --git a/vlib/v/checker/tests/const_field_name_duplicate_err.out b/vlib/v/checker/tests/const_field_name_duplicate_err.out new file mode 100644 index 0000000000..89a5ce9d92 --- /dev/null +++ b/vlib/v/checker/tests/const_field_name_duplicate_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/const_field_name_duplicate_err.v:3:2: error: field name `aaa` duplicate + 1| const ( + 2| aaa = 1 + 3| aaa = 2 + ~~~ + 4| ) + 5| fn main() { diff --git a/vlib/v/checker/tests/const_field_name_duplicate_err.vv b/vlib/v/checker/tests/const_field_name_duplicate_err.vv new file mode 100644 index 0000000000..f489f51671 --- /dev/null +++ b/vlib/v/checker/tests/const_field_name_duplicate_err.vv @@ -0,0 +1,7 @@ +const ( + aaa = 1 + aaa = 2 +) +fn main() { + println(aaa) +} diff --git a/vlib/v/checker/tests/multi_const_field_name_duplicate_err.out b/vlib/v/checker/tests/multi_const_field_name_duplicate_err.out new file mode 100644 index 0000000000..6bfcd34874 --- /dev/null +++ b/vlib/v/checker/tests/multi_const_field_name_duplicate_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/multi_const_field_name_duplicate_err.v:2:8: error: field name `aaa` duplicate + 1| const (aaa = 1) + 2| const (aaa = 2) + ~~~ + 3| fn main() { + 4| println(aaa) diff --git a/vlib/v/checker/tests/multi_const_field_name_duplicate_err.vv b/vlib/v/checker/tests/multi_const_field_name_duplicate_err.vv new file mode 100644 index 0000000000..883abac8b6 --- /dev/null +++ b/vlib/v/checker/tests/multi_const_field_name_duplicate_err.vv @@ -0,0 +1,5 @@ +const (aaa = 1) +const (aaa = 2) +fn main() { + println(aaa) +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 00286960a7..100d0c1f74 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1002,6 +1002,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl { if p.tok.kind == .comment { p.comment() } + pos := p.tok.position() name := p.prepend_mod(p.check_name()) // name := p.check_name() // println('!!const: $name') @@ -1010,7 +1011,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl { field := ast.ConstField{ name: name expr: expr - pos: p.tok.position() + pos: pos } fields << field p.global_scope.register(field.name, field)