dont allow method on non-local types & no mod for arrays. closes #6971

pull/7027/head^2
joe-conigliaro 2020-11-30 11:43:22 +11:00
parent b1bff3f319
commit ff63fb74d9
No known key found for this signature in database
GPG Key ID: C12F7136C08206F1
7 changed files with 15 additions and 28 deletions

View File

@ -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 } table.FnType { ret_type = arg_sym.info.func.return_type }
else { ret_type = arg_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' { } else if method_name == 'filter' {
// check fn // check fn
c.check_map_and_filter(false, elem_typ, call_expr) 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_info := return_sym.info as table.Array
elem_sym := c.table.get_type_symbol(elem_info.elem_type) elem_sym := c.table.get_type_symbol(elem_info.elem_type)
if elem_sym.source_name == 'T' { 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) return table.new_type(idx)
} }
} }
@ -2393,8 +2393,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
1) 1)
array_init.typ = table.new_type(idx) array_init.typ = table.new_type(idx)
} else { } else {
sym := c.table.get_type_symbol(elem_type) idx := c.table.find_or_register_array(elem_type, 1)
idx := c.table.find_or_register_array(elem_type, 1, sym.mod)
array_init.typ = table.new_type(idx) array_init.typ = table.new_type(idx)
} }
array_init.elem_type = elem_type 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 // fixed_array[1..2] => array
if typ_sym.kind == .array_fixed { if typ_sym.kind == .array_fixed {
elem_type := c.table.value_type(typ) 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 table.new_type(idx)
} }
return typ.set_nr_muls(0) 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) { // if sym.has_method(node.name) {
// c.warn('duplicate method `$node.name`', node.pos) // 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 // needed for proper error reporting during vweb route checking
sym.methods[node.method_idx].source_fn = voidptr(node) sym.methods[node.method_idx].source_fn = voidptr(node)
} }

View File

@ -1,4 +1,4 @@
pub fn (b byte) str_escaped() string { pub fn str_escaped(b byte) string {
str := match b { str := match b {
0 { '`\\' + '0`' } // Bug is preventing \\0 in a literal 0 { '`\\' + '0`' } // Bug is preventing \\0 in a literal
7 { '`\\a`' } 7 { '`\\a`' }

View File

@ -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 { if p.tok.kind in [.name, .amp, .lsbr] && p.tok.line_nr == line_nr {
elem_type_pos = p.tok.position() elem_type_pos = p.tok.position()
elem_type = p.parse_type() 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 // this is set here because it's a known type, others could be the
// result of expr so we do those in checker // 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) array_type = table.new_type(idx)
has_type = true has_type = true
} }

View File

@ -273,6 +273,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
if is_method { if is_method {
mut type_sym := p.table.get_type_symbol(rec_type) mut type_sym := p.table.get_type_symbol(rec_type)
ret_type_sym := p.table.get_type_symbol(return_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 ()') // p.warn('reg method $type_sym.name . $name ()')
type_sym_method_idx = type_sym.register_method(table.Fn{ type_sym_method_idx = type_sym.register_method(table.Fn{
name: name name: name

View File

@ -29,8 +29,7 @@ pub fn (mut p Parser) parse_array_type() table.Type {
p.check(.rsbr) p.check(.rsbr)
nr_dims++ nr_dims++
} }
sym := p.table.get_type_symbol(elem_type) idx := p.table.find_or_register_array(elem_type, nr_dims)
idx := p.table.find_or_register_array(elem_type, nr_dims, sym.mod)
return table.new_type(idx) return table.new_type(idx)
} }

View File

@ -76,7 +76,7 @@ fn (mut p Parser) sql_expr() ast.Expr {
} }
if !query_one && !is_count { if !query_one && !is_count {
// return an array // 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 { } else if !is_count {
// return a single object // return a single object
// TODO optional // TODO optional

View File

@ -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) 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) name := t.array_name(elem_type, nr_dims)
source_name := t.array_source_name(elem_type) source_name := t.array_source_name(elem_type)
// existing // 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 elem_type: elem_type
nr_dims: nr_dims nr_dims: nr_dims
} }
mod: mod
} }
return t.register_type_symbol(array_type) return t.register_type_symbol(array_type)
} }