From ff63fb74d9828a0192e4b789d75bf9bdfaeeb864 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Mon, 30 Nov 2020 11:43:22 +1100 Subject: [PATCH] dont allow method on non-local types & no mod for arrays. closes #6971 --- vlib/v/checker/checker.v | 24 ++++--------------- .../match_range_expression_branches_keep.vv | 2 +- vlib/v/parser/containers.v | 3 +-- vlib/v/parser/fn.v | 6 +++++ vlib/v/parser/parse_type.v | 3 +-- vlib/v/parser/sql.v | 2 +- vlib/v/table/table.v | 3 +-- 7 files changed, 15 insertions(+), 28 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c128732f04..c40121599f 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1160,7 +1160,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { table.FnType { ret_type = arg_sym.info.func.return_type } else { ret_type = arg_type } } - call_expr.return_type = c.table.find_or_register_array(ret_type, 1, c.mod) + call_expr.return_type = c.table.find_or_register_array(ret_type, 1) } else if method_name == 'filter' { // check fn c.check_map_and_filter(false, elem_typ, call_expr) @@ -1608,7 +1608,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { elem_info := return_sym.info as table.Array elem_sym := c.table.get_type_symbol(elem_info.elem_type) if elem_sym.source_name == 'T' { - idx := c.table.find_or_register_array(call_expr.generic_type, 1, return_sym.mod) + idx := c.table.find_or_register_array(call_expr.generic_type, 1) return table.new_type(idx) } } @@ -2393,8 +2393,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { 1) array_init.typ = table.new_type(idx) } else { - sym := c.table.get_type_symbol(elem_type) - idx := c.table.find_or_register_array(elem_type, 1, sym.mod) + idx := c.table.find_or_register_array(elem_type, 1) array_init.typ = table.new_type(idx) } array_init.elem_type = elem_type @@ -4191,7 +4190,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { // fixed_array[1..2] => array if typ_sym.kind == .array_fixed { elem_type := c.table.value_type(typ) - idx := c.table.find_or_register_array(elem_type, 1, c.mod) + idx := c.table.find_or_register_array(elem_type, 1) return table.new_type(idx) } return typ.set_nr_muls(0) @@ -4542,21 +4541,6 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { // if sym.has_method(node.name) { // c.warn('duplicate method `$node.name`', node.pos) // } - // Do not allow to modify types from other modules - if sym.mod != c.mod && !c.is_builtin_mod && sym.mod != '' { // TODO remove != '' - // remove the method to hide other related errors (`method is private` etc) - mut idx := 0 - for i, m in sym.methods { - if m.name == node.name { - idx = i - break - } - } - sym.methods.delete(idx) - // - c.error('cannot define new methods on non-local `$sym.source_name` (' + - 'current module is `$c.mod`, `$sym.source_name` is from `$sym.mod`)', node.pos) - } // needed for proper error reporting during vweb route checking sym.methods[node.method_idx].source_fn = voidptr(node) } diff --git a/vlib/v/fmt/tests/match_range_expression_branches_keep.vv b/vlib/v/fmt/tests/match_range_expression_branches_keep.vv index d557ddb0c8..ae99b0ff35 100644 --- a/vlib/v/fmt/tests/match_range_expression_branches_keep.vv +++ b/vlib/v/fmt/tests/match_range_expression_branches_keep.vv @@ -1,4 +1,4 @@ -pub fn (b byte) str_escaped() string { +pub fn str_escaped(b byte) string { str := match b { 0 { '`\\' + '0`' } // Bug is preventing \\0 in a literal 7 { '`\\a`' } diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index 1655e942c5..2b92b4cc40 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -30,10 +30,9 @@ fn (mut p Parser) array_init() ast.ArrayInit { if p.tok.kind in [.name, .amp, .lsbr] && p.tok.line_nr == line_nr { elem_type_pos = p.tok.position() elem_type = p.parse_type() - sym := p.table.get_type_symbol(elem_type) // this is set here because it's a known type, others could be the // result of expr so we do those in checker - idx := p.table.find_or_register_array(elem_type, 1, sym.mod) + idx := p.table.find_or_register_array(elem_type, 1) array_type = table.new_type(idx) has_type = true } diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 161eaf1933..19f8f5b696 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -273,6 +273,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl { if is_method { mut type_sym := p.table.get_type_symbol(rec_type) ret_type_sym := p.table.get_type_symbol(return_type) + // Do not allow to modify / add methods to types from other modules + // arrays/maps dont belong to a module only their element types do + // we could also check if kind is .array, .array_fixed, .map instead of mod.len + if type_sym.mod.len > 0 && type_sym.mod != p.mod && type_sym.language == .v { + p.error('cannot define new methods on non-local type $type_sym.name') + } // p.warn('reg method $type_sym.name . $name ()') type_sym_method_idx = type_sym.register_method(table.Fn{ name: name diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 87194f5697..53a2c4e219 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -29,8 +29,7 @@ pub fn (mut p Parser) parse_array_type() table.Type { p.check(.rsbr) nr_dims++ } - sym := p.table.get_type_symbol(elem_type) - idx := p.table.find_or_register_array(elem_type, nr_dims, sym.mod) + idx := p.table.find_or_register_array(elem_type, nr_dims) return table.new_type(idx) } diff --git a/vlib/v/parser/sql.v b/vlib/v/parser/sql.v index 63268058a5..13c4387de1 100644 --- a/vlib/v/parser/sql.v +++ b/vlib/v/parser/sql.v @@ -76,7 +76,7 @@ fn (mut p Parser) sql_expr() ast.Expr { } if !query_one && !is_count { // return an array - typ = table.new_type(p.table.find_or_register_array(table_type, 1, p.mod)) + typ = table.new_type(p.table.find_or_register_array(table_type, 1)) } else if !is_count { // return a single object // TODO optional diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 4192176c3d..321710db2b 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -539,7 +539,7 @@ pub fn (mut t Table) find_or_register_map(key_type Type, value_type Type) int { return t.register_type_symbol(map_typ) } -pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int, mod string) int { +pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int) int { name := t.array_name(elem_type, nr_dims) source_name := t.array_source_name(elem_type) // existing @@ -558,7 +558,6 @@ pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int, mod str elem_type: elem_type nr_dims: nr_dims } - mod: mod } return t.register_type_symbol(array_type) }