From fcc61a981dfb474466d5fdd935a607d3e71b666f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Sat, 22 Aug 2020 12:29:15 +0200 Subject: [PATCH] all: TypeSymbol.source_name (#6187) --- cmd/tools/bench/wyhash.v | 15 +- examples/x/websocket/ping.v | 2 +- vlib/net/websocket/handshake.v | 2 +- vlib/v/checker/checker.v | 180 ++++++++++--------- vlib/v/checker/tests/cannot_assign_array.out | 2 +- vlib/v/checker/tests/map_init_wrong_type.out | 2 +- vlib/v/parser/fn.v | 12 ++ vlib/v/parser/parse_type.v | 4 + vlib/v/parser/parser.v | 13 +- vlib/v/parser/struct.v | 6 + vlib/v/table/atypes.v | 43 ++++- vlib/v/table/table.v | 111 +++++++++--- vlib/x/websocket/handshake.v | 2 +- vlib/x/websocket/websocket_client.v | 2 +- vlib/x/websocket/websocket_test.v | 5 +- 15 files changed, 266 insertions(+), 135 deletions(-) diff --git a/cmd/tools/bench/wyhash.v b/cmd/tools/bench/wyhash.v index 8241671ae9..d4ee8ac394 100644 --- a/cmd/tools/bench/wyhash.v +++ b/cmd/tools/bench/wyhash.v @@ -30,29 +30,26 @@ fn main() { checksum = 0 for len in str_lens { end_pos := start_pos + len - str := string(bytepile[start_pos..end_pos], len) - checksum ^= wyhash.wyhash_c(&str.str, u64(str.len), 1) + checksum ^= wyhash.wyhash_c(unsafe { bytepile.data + start_pos }, u64(len), 1) start_pos = end_pos } - bhashing_1.measure('wyhash.wyhash_c | checksum: ${checksum:22}') + bhashing_1.measure('wyhash.wyhash_c | checksum: ${checksum:22}') mut bhashing_2 := benchmark.start() start_pos = 0 checksum = 0 for len in str_lens { end_pos := start_pos + len - str := string(bytepile[start_pos..end_pos], len) - checksum ^= wyhash.sum64_string(str, 1) + checksum ^= wyhash.sum64(bytepile[start_pos..end_pos], 1) start_pos = end_pos } - bhashing_2.measure('wyhash.sum64_string | checksum: ${checksum:22}') + bhashing_2.measure('wyhash.sum64 | checksum: ${checksum:22}') mut bhashing_3 := benchmark.start() start_pos = 0 checksum = 0 for len in str_lens { end_pos := start_pos + len - str := string(bytepile[start_pos..end_pos], len) - checksum ^= fnv1a.sum64_string(str) + checksum ^= fnv1a.sum64(bytepile[start_pos..end_pos]) start_pos = end_pos } - bhashing_3.measure('fnv1a.sum64_string | checksum: ${checksum:22}') + bhashing_3.measure('fnv1a.sum64 | checksum: ${checksum:22}') } diff --git a/examples/x/websocket/ping.v b/examples/x/websocket/ping.v index 16b59fa265..9db616aba5 100644 --- a/examples/x/websocket/ping.v +++ b/examples/x/websocket/ping.v @@ -58,7 +58,7 @@ fn start_client() ? { // use on_message_ref if you want to send any reference object ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { if msg.payload.len > 0 { - message := string(msg.payload, msg.payload.len) + message := msg.payload.bytestr() println('client got type: $msg.opcode payload:\n$message') } }) diff --git a/vlib/net/websocket/handshake.v b/vlib/net/websocket/handshake.v index e8510a1bc4..b9d7669bff 100644 --- a/vlib/net/websocket/handshake.v +++ b/vlib/net/websocket/handshake.v @@ -24,7 +24,7 @@ fn (mut ws Client) read_handshake(seckey string) { unsafe { buffer[max_buffer - 1] = `\0` } - ws.handshake_handler(string(byteptr(buffer)), seckey) + ws.handshake_handler(unsafe{ byteptr(buffer).vstring_with_len(max_buffer-1) }, seckey) } fn (mut ws Client) handshake_handler(handshake_response, seckey string) { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 38983f7f2d..83ebe096bf 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -265,10 +265,10 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) { } typ_sym := c.table.get_type_symbol(node.parent_type) if typ_sym.kind == .placeholder { - c.error("type `$typ_sym.name` doesn't exist", node.pos) + c.error("type `$typ_sym.source_name` doesn't exist", node.pos) } else if typ_sym.kind == .alias { orig_sym := c.table.get_type_symbol((typ_sym.info as table.Alias).parent_type) - c.error('type `$typ_sym.name` is an alias, use the original alias type `$orig_sym.name` instead', + c.error('type `$typ_sym.str()` is an alias, use the original alias type `$orig_sym.source_name` instead', node.pos) } } @@ -279,12 +279,12 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) { fn_info := fn_typ_info.func ret_sym := c.table.get_type_symbol(fn_info.return_type) if ret_sym.kind == .placeholder { - c.error("type `$ret_sym.name` doesn't exist", node.pos) + c.error("type `$ret_sym.source_name` doesn't exist", node.pos) } for arg in fn_info.args { arg_sym := c.table.get_type_symbol(arg.typ) if arg_sym.kind == .placeholder { - c.error("type `$arg_sym.name` doesn't exist", node.pos) + c.error("type `$arg_sym.source_name` doesn't exist", node.pos) } } } @@ -293,7 +293,7 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) { for typ in node.sub_types { typ_sym := c.table.get_type_symbol(typ) if typ_sym.kind == .placeholder { - c.error("type `$typ_sym.name` doesn't exist", node.pos) + c.error("type `$typ_sym.source_name` doesn't exist", node.pos) } } } @@ -322,21 +322,21 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) { } sym := c.table.get_type_symbol(field.typ) if sym.kind == .placeholder && decl.language != .c && !sym.name.starts_with('C.') { - c.error(util.new_suggestion(sym.name, c.table.known_type_names()).say('unknown type `$sym.name`'), + c.error(util.new_suggestion(sym.source_name, c.table.known_type_names()).say('unknown type `$sym.source_name`'), field.pos) } if sym.kind == .array { array_info := sym.array_info() elem_sym := c.table.get_type_symbol(array_info.elem_type) if elem_sym.kind == .placeholder { - c.error(util.new_suggestion(elem_sym.name, c.table.known_type_names()).say('unknown type `$elem_sym.name`'), + c.error(util.new_suggestion(elem_sym.source_name, c.table.known_type_names()).say('unknown type `$elem_sym.source_name`'), field.pos) } } if sym.kind == .struct_ { info := sym.info as table.Struct if info.is_ref_only && !field.typ.is_ptr() { - c.error('`$sym.name` type can only be used as a reference: `&$sym.name`', + c.error('`$sym.source_name` type can only be used as a reference: `&$sym.source_name`', field.pos) } } @@ -347,7 +347,8 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) { field_expr_type_sym := c.table.get_type_symbol(field_expr_type) field_type_sym := c.table.get_type_symbol(field.typ) c.error('default expression for field `$field.name` ' + - 'has type `$field_expr_type_sym.name`, but should be `$field_type_sym.name`', field.default_expr.position()) + 'has type `$field_expr_type_sym.source_name`, but should be `$field_type_sym.source_name`', + field.default_expr.position()) } } } @@ -372,26 +373,25 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { type_sym := c.table.get_type_symbol(struct_init.typ) if type_sym.kind == .sum_type && struct_init.fields.len == 1 { sexpr := struct_init.fields[0].expr.str() - c.error('cast to sum type using `${type_sym.name}($sexpr)` not `$type_sym.name{$sexpr}`', + c.error('cast to sum type using `${type_sym.source_name}($sexpr)` not `$type_sym.source_name{$sexpr}`', struct_init.pos) } if type_sym.kind == .interface_ { - c.error('cannot instantiate interface `$type_sym.name`', struct_init.pos) + c.error('cannot instantiate interface `$type_sym.source_name`', struct_init.pos) } if type_sym.kind == .alias { info := type_sym.info as table.Alias if info.parent_type.is_number() { - c.error('cannot instantiate number type alias `$type_sym.name`', struct_init.pos) + c.error('cannot instantiate number type alias `$type_sym.source_name`', struct_init.pos) return table.void_type } } if !type_sym.is_public && type_sym.kind != .placeholder && type_sym.mod != c.mod { - c.error('type `$type_sym.name` is private', struct_init.pos) + c.error('type `$type_sym.source_name` is private', struct_init.pos) } - // println('check struct $typ_sym.name') match type_sym.kind { .placeholder { - c.error('unknown struct: $type_sym.name', struct_init.pos) + c.error('unknown struct: $type_sym.source_name', struct_init.pos) } // string & array are also structs but .kind of string/array .struct_, .string, .array, .alias { @@ -400,11 +400,11 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { info_t := type_sym.info as table.Alias sym := c.table.get_type_symbol(info_t.parent_type) if sym.kind == .placeholder { // pending import symbol did not resolve - c.error('unknown struct: $type_sym.name', struct_init.pos) + c.error('unknown struct: $type_sym.source_name', struct_init.pos) return table.void_type } if sym.kind != .struct_ { - c.error('alias type name: $sym.name is not struct type', struct_init.pos) + c.error('alias type name: $sym.source_name is not struct type', struct_init.pos) } info = sym.info as table.Struct } else { @@ -437,7 +437,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { } } if !exists { - c.error('unknown field `$field.name` in struct literal of type `$type_sym.name`', + c.error('unknown field `$field.name` in struct literal of type `$type_sym.source_name`', field.pos) continue } @@ -454,7 +454,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { field_type_sym := c.table.get_type_symbol(info_field.typ) if !c.check_types(expr_type, info_field.typ) && expr_type != table.void_type && expr_type_sym.kind != .placeholder { - c.error('cannot assign $expr_type_sym.kind `$expr_type_sym.name` as `$field_type_sym.name` for field `$info_field.name`', + c.error('cannot assign $expr_type_sym.kind `$expr_type_sym.source_name` as `$field_type_sym.source_name` for field `$info_field.name`', field.pos) } if info_field.typ.is_ptr() && !expr_type.is_ptr() && !expr_type.is_pointer() && @@ -470,7 +470,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type { continue } if field.typ.is_ptr() && !c.pref.translated { - c.warn('reference field `${type_sym.name}.$field.name` must be initialized', + c.warn('reference field `${type_sym.source_name}.$field.name` must be initialized', struct_init.pos) } } @@ -515,14 +515,14 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { .array { right_sym := c.table.get_type_symbol(c.table.mktyp(right.array_info().elem_type)) if left_default.kind != right_sym.kind { - c.error('the data type on the left of `$infix_expr.op.str()` (`$left.name`) does not match the array item type (`$right_sym.name`)', + c.error('the data type on the left of `$infix_expr.op.str()` (`$left.name`) does not match the array item type (`$right_sym.source_name`)', infix_expr.pos) } } .map { key_sym := c.table.get_type_symbol(c.table.mktyp(right.map_info().key_type)) if left_default.kind != key_sym.kind { - c.error('the data type on the left of `$infix_expr.op.str()` (`$left.name`) does not match the map key type `$key_sym.name`', + c.error('the data type on the left of `$infix_expr.op.str()` (`$left.name`) does not match the map key type `$key_sym.source_name`', infix_expr.pos) } } @@ -617,8 +617,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { // []T << []T return table.void_type } - s := left.name.replace('array_', '[]') - c.error('cannot append `$right.name` to `$s`', right_pos) + c.error('cannot append `$right.source_name` to `$left.source_name`', right_pos) return table.void_type } else { return c.check_shift(left_type, right_type, left_pos, right_pos) @@ -631,7 +630,8 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type { type_expr := infix_expr.right as ast.Type typ_sym := c.table.get_type_symbol(type_expr.typ) if typ_sym.kind == .placeholder { - c.error('$infix_expr.op.str(): type `$typ_sym.name` does not exist', type_expr.pos) + c.error('$infix_expr.op.str(): type `$typ_sym.source_name` does not exist', + type_expr.pos) } if left.kind != .interface_ && left.kind != .sum_type { c.error('`$infix_expr.op.str()` can only be used with interfaces and sum types', @@ -819,11 +819,11 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e c.error('function needs exactly 1 argument', call_expr.pos) } else if is_map && (arg_expr.decl.return_type != elem_typ || arg_expr.decl.args[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a $elem_sym.name) $elem_sym.name {...}`', + c.error('type mismatch, should use `fn(a $elem_sym.source_name) $elem_sym.source_name {...}`', call_expr.pos) } else if !is_map && (arg_expr.decl.return_type != table.bool_type || arg_expr.decl.args[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`', + c.error('type mismatch, should use `fn(a $elem_sym.source_name) bool {...}`', call_expr.pos) } } @@ -836,11 +836,11 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ table.Type, call_e if func.args.len > 1 { c.error('function needs exactly 1 argument', call_expr.pos) } else if is_map && (func.return_type != elem_typ || func.args[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a $elem_sym.name) $elem_sym.name {...}`', + c.error('type mismatch, should use `fn(a $elem_sym.source_name) $elem_sym.source_name {...}`', call_expr.pos) } else if !is_map && (func.return_type != table.bool_type || func.args[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a $elem_sym.name) bool {...}`', + c.error('type mismatch, should use `fn(a $elem_sym.source_name) bool {...}`', call_expr.pos) } } @@ -939,13 +939,13 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { if sym.kind != elem_sym.kind && ((elem_sym.kind == .int && sym.kind != .any_int) || (elem_sym.kind == .f64 && sym.kind != .any_float)) { - c.error('type mismatch, should use `$elem_sym.name[]`', arg_expr.position()) + c.error('type mismatch, should use `$elem_sym.source_name[]`', arg_expr.position()) } } else { if arg_sym.kind != elem_sym.kind && ((elem_sym.kind == .int && arg_sym.kind != .any_int) || (elem_sym.kind == .f64 && arg_sym.kind != .any_float)) { - c.error('type mismatch, should use `$elem_sym.name`', arg_expr.position()) + c.error('type mismatch, should use `$elem_sym.source_name`', arg_expr.position()) } } } @@ -955,7 +955,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { // If a private method is called outside of the module // its receiver type is defined in, show an error. // println('warn $method_name lef.mod=$left_type_sym.mod c.mod=$c.mod') - c.error('method `${left_type_sym.name}.$method_name` is private', call_expr.pos) + c.error('method `${left_type_sym.source_name}.$method_name` is private', call_expr.pos) } if method.args[0].is_mut { c.fail_if_immutable(call_expr.left) @@ -968,10 +968,10 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { nr_args := if method.args.len == 0 { 0 } else { method.args.len - 1 } min_required_args := method.args.len - if method.is_variadic && method.args.len > 1 { 2 } else { 1 } if call_expr.args.len < min_required_args { - c.error('too few arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $min_required_args)', + c.error('too few arguments in call to `${left_type_sym.source_name}.$method_name` ($call_expr.args.len instead of $min_required_args)', call_expr.pos) } else if !method.is_variadic && call_expr.args.len > nr_args { - c.error('too many arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $nr_args)', + c.error('too many arguments in call to `${left_type_sym.source_name}.$method_name` ($call_expr.args.len instead of $nr_args)', call_expr.pos) return method.return_type } @@ -1008,13 +1008,13 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { } } if got_arg_typ != table.void_type { - c.error('cannot use type `$got_arg_sym.str()` as type `$exp_arg_sym.str()` in argument ${i+1} to `${left_type_sym.name}.$method_name`', + c.error('cannot use type `$got_arg_sym.source_name` as type `$exp_arg_sym.source_name` in argument ${i+1} to `${left_type_sym.source_name}.$method_name`', call_expr.pos) } } } if method.is_unsafe && !c.inside_unsafe { - c.warn('method `${left_type_sym.name}.$method_name` must be called from an `unsafe` block', + c.warn('method `${left_type_sym.source_name}.$method_name` must be called from an `unsafe` block', call_expr.pos) } // TODO: typ optimize.. this node can get processed more than once @@ -1036,7 +1036,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { // TODO: str methods if method_name == 'str' { if left_type_sym.kind == .interface_ { - iname := left_type_sym.name + iname := left_type_sym.source_name c.error('interface `$iname` does not have a .str() method. Use typeof() instead', call_expr.pos) } @@ -1065,7 +1065,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { } if left_type != table.void_type { suggestion := util.new_suggestion(method_name, left_type_sym.methods.map(it.name)) - c.error(suggestion.say('unknown method: `${left_type_sym.name}.$method_name`'), + c.error(suggestion.say('unknown method: `${left_type_sym.source_name}.$method_name`'), call_expr.pos) } return table.void_type @@ -1245,7 +1245,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { prtyp_sym := c.table.get_type_symbol(prtyp) prtyp_is_ptr := prtyp.is_ptr() prhas_str, prexpects_ptr, prnr_args := prtyp_sym.str_method_info() - eprintln('>>> println hack typ: ${prtyp} | sym.name: ${prtyp_sym.name} | is_ptr: $prtyp_is_ptr | has_str: $prhas_str | expects_ptr: $prexpects_ptr | nr_args: $prnr_args | expr: ${prexpr.str()} ') + eprintln('>>> println hack typ: ${prtyp} | sym.source_name: ${prtyp_sym.source_name} | is_ptr: $prtyp_is_ptr | has_str: $prhas_str | expects_ptr: $prexpects_ptr | nr_args: $prnr_args | expr: ${prexpr.str()} ') */ return f.return_type } @@ -1322,11 +1322,11 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { if typ_sym.kind == .array_fixed { } if typ_sym.kind == .function && arg_typ_sym.kind == .function { - candidate_fn_name := if typ_sym.name.starts_with('anon_') { 'anonymous function' } else { 'fn `$typ_sym.name`' } + candidate_fn_name := if typ_sym.source_name.starts_with('anon_') { 'anonymous function' } else { 'fn `$typ_sym.source_name`' } c.error('cannot use $candidate_fn_name as function type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`', call_expr.pos) } else { - c.error('cannot use type `$typ_sym.str()` as type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`', + c.error('cannot use type `$typ_sym.source_name` as type `$arg_typ_sym.source_name` in argument ${i+1} to `$fn_name`', call_expr.pos) } } @@ -1334,12 +1334,12 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { if call_expr.generic_type != table.void_type && f.return_type != 0 { // table.t_type { // Handle `foo() T` => `foo() int` => return int return_sym := c.table.get_type_symbol(f.return_type) - if return_sym.name == 'T' { + if return_sym.source_name == 'T' { return call_expr.generic_type } else if return_sym.kind == .array { elem_info := return_sym.info as table.Array elem_sym := c.table.get_type_symbol(elem_info.elem_type) - if elem_sym.name == 'T' { + if elem_sym.source_name == 'T' { idx := c.table.find_or_register_array(call_expr.generic_type, 1, return_sym.mod) return table.new_type(idx) } @@ -1358,7 +1358,7 @@ fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position for imethod in inter_sym.methods { if method := typ_sym.find_method(imethod.name) { if !imethod.is_same_method_as(method) { - c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`, expected `${c.table.fn_to_str(imethod)}`', + c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.source_name`, expected `${c.table.fn_to_str(imethod)}`', pos) return false } @@ -1478,17 +1478,17 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T } if field := c.table.struct_find_field(sym, field_name) { if sym.mod != c.mod && !field.is_pub { - c.error('field `${sym.name}.$field_name` is not public', selector_expr.pos) + c.error('field `${sym.source_name}.$field_name` is not public', selector_expr.pos) } selector_expr.typ = field.typ return field.typ } if sym.kind != .struct_ { if sym.kind != .placeholder { - c.error('`$sym.name` is not a struct', selector_expr.pos) + c.error('`$sym.source_name` is not a struct', selector_expr.pos) } } else { - c.error('type `$sym.name` has no field or method `$field_name`', selector_expr.pos) + c.error('type `$sym.source_name` has no field or method `$field_name`', selector_expr.pos) } return table.void_type } @@ -1554,7 +1554,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { c.type_implements(got_typ, exp_type, return_stmt.pos) continue } - c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument', + c.error('cannot use `$got_typ_sym.source_name` as type `$exp_typ_sym.source_name` in return argument', pos) } if got_typ.is_ptr() && !exp_type.is_ptr() { @@ -1765,10 +1765,10 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { .assign {} // No need to do single side check for =. But here put it first for speed. .plus_assign { if !left_sym.is_number() && left_type != table.string_type && !left_sym.is_pointer() { - c.error('operator += not defined on left operand type `$left_sym.name`', + c.error('operator += not defined on left operand type `$left_sym.source_name`', left.position()) } else if !right_sym.is_number() && right_type != table.string_type && !right_sym.is_pointer() { - c.error('operator += not defined on right operand type `$right_sym.name`', + c.error('operator += not defined on right operand type `$right_sym.source_name`', right.position()) } if right is ast.IntegerLiteral && right.str().int() == 1 { @@ -1777,10 +1777,10 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } .minus_assign { if !left_sym.is_number() && !left_sym.is_pointer() { - c.error('operator -= not defined on left operand type `$left_sym.name`', + c.error('operator -= not defined on left operand type `$left_sym.source_name`', left.position()) } else if !right_sym.is_number() && !right_sym.is_pointer() { - c.error('operator -= not defined on right operand type `$right_sym.name`', + c.error('operator -= not defined on right operand type `$right_sym.source_name`', right.position()) } if right is ast.IntegerLiteral && right.str().int() == 1 { @@ -1789,19 +1789,19 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { } .mult_assign, .div_assign { if !left_sym.is_number() { - c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.name`', + c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.source_name`', left.position()) } else if !right_sym.is_number() { - c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.name`', + c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.source_name`', right.position()) } } .and_assign, .or_assign, .xor_assign, .mod_assign, .left_shift_assign, .right_shift_assign { if !left_sym.is_int() { - c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.name`', + c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.source_name`', left.position()) } else if !right_sym.is_int() { - c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.name`', + c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.source_name`', right.position()) } } @@ -1810,7 +1810,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { // Dual sides check (compatibility check) if !is_blank_ident && !c.check_types(right_type_unwrapped, left_type_unwrapped) && right_sym.kind != .placeholder { - c.error('cannot assign `$right_sym.name` to `$left.str()` of type `$left_sym.name`', + c.error('cannot assign `$right_sym.source_name` to `$left.str()` of type `$left_sym.source_name`', right.position()) } } @@ -1838,7 +1838,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { } sym := c.table.get_type_symbol(array_init.elem_type) if sym.kind == .placeholder { - c.error('unknown type `$sym.name`', array_init.elem_type_pos) + c.error('unknown type `$sym.source_name`', array_init.elem_type_pos) } return array_init.typ } @@ -1898,7 +1898,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { } if !c.check_types(typ, elem_type) { elem_type_sym := c.table.get_type_symbol(elem_type) - c.error('expected array element with type `$elem_type_sym.name`', array_init.pos) + c.error('expected array element with type `$elem_type_sym.source_name`', + array_init.pos) } } if expecting_interface_array { @@ -2273,15 +2274,17 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { if expr_type_sym.kind == .sum_type { if type_sym.kind == .placeholder { // Unknown type used in the right part of `as` - c.error('unknown type `$type_sym.name`', node.pos) + c.error('unknown type `$type_sym.source_name`', node.pos) } if !c.table.sumtype_has_variant(node.expr_type, node.typ) { - c.error('cannot cast `$expr_type_sym.name` to `$type_sym.name`', node.pos) + c.error('cannot cast `$expr_type_sym.source_name` to `$type_sym.source_name`', + node.pos) // c.error('only $info.variants can be casted to `$typ`', node.pos) } } else { // - c.error('cannot cast non sum type `$type_sym.name` using `as`', node.pos) + c.error('cannot cast non sum type `$type_sym.source_name` using `as`', + node.pos) } return node.typ.to_ptr() // return node.typ @@ -2323,10 +2326,11 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { node.expr_type = c.promote_num(node.expr_type, if node.expr_type == table.any_int_type { table.int_type } else { table.f64_type }) } if !c.table.sumtype_has_variant(node.typ, node.expr_type) { - c.error('cannot cast `$from_type_sym.name` to `$to_type_sym.name`', + c.error('cannot cast `$from_type_sym.source_name` to `$to_type_sym.source_name`', node.pos) } - } else if node.typ == table.string_type && !(from_type_sym.kind in [.byte, .byteptr] || + } else if node.typ == table.string_type && + (from_type_sym.kind in [.any_int, .int, .byte, .byteptr] || (from_type_sym.kind == .array && from_type_sym.name == 'array_byte')) { type_name := c.table.type_to_str(node.expr_type) c.error('cannot cast type `$type_name` to string, use `x.str()` instead', @@ -2352,7 +2356,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { from_type_info := from_type_sym.info as table.Struct to_type_info := to_type_sym.info as table.Struct if !c.check_struct_signature(from_type_info, to_type_info) { - c.error('cannot convert struct `$from_type_sym.name` to struct `$to_type_sym.name`', + c.error('cannot convert struct `$from_type_sym.source_name` to struct `$to_type_sym.source_name`', node.pos) } } else { @@ -2518,7 +2522,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type { if !c.check_types(ltype, table.bool_type) { ltype_sym := c.table.get_type_symbol(ltype) lname := if node.is_likely { '_likely_' } else { '_unlikely_' } - c.error('`${lname}()` expects a boolean expression, instead it got `$ltype_sym.name`', + c.error('`${lname}()` expects a boolean expression, instead it got `$ltype_sym.source_name`', node.pos) } return table.bool_type @@ -2593,7 +2597,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type { } // if typ == table.t_type { // sym := c.table.get_type_symbol(c.cur_generic_type) - // println('IDENT T unresolved $ident.name typ=$sym.name') + // println('IDENT T unresolved $ident.name typ=$sym.source_name') // Got a var with type T, return current generic type // typ = c.cur_generic_type // } @@ -2728,7 +2732,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { c.type_implements(typ, cond_type, node.pos) } if !ok { - c.error('cannot use `$typ_sym.name` as `$cond_type_sym.name` in `match`', + c.error('cannot use `$typ_sym.source_name` as `$cond_type_sym.source_name` in `match`', node.pos) } } @@ -2745,7 +2749,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { // TODO: ask alex about this // typ := c.expr(stmt.expr) // type_sym := c.table.get_type_symbol(typ) - // p.warn('match expr ret $type_sym.name') + // p.warn('match expr ret $type_sym.source_name') // node.typ = typ // return typ } @@ -2956,7 +2960,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { mut expr_required := false if c.expected_type != table.void_type { // sym := c.table.get_type_symbol(c.expected_type) - // println('$c.file.path $node.pos.line_nr IF is expr: checker exp type = ' + sym.name) + // println('$c.file.path $node.pos.line_nr IF is expr: checker exp type = ' + sym.source_name) expr_required = true } former_expected_type := c.expected_type @@ -2975,7 +2979,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { // void types are skipped, because they mean the var was initialized incorrectly // (via missing function etc) typ_sym := c.table.get_type_symbol(cond_typ) - c.error('non-bool type `$typ_sym.name` used as if condition', branch.pos) + c.error('non-bool type `$typ_sym.source_name` used as if condition', branch.pos) } } // smartcast sumtypes when using `is` @@ -3115,7 +3119,7 @@ pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) table.Type { typ_sym := c.table.get_type_symbol(typ) // if !typ.is_number() { if !typ_sym.is_number() { - c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.name`)', + c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.source_name`)', node.pos) } else { node.auto_locked, _ = c.fail_if_immutable(node.expr) @@ -3128,12 +3132,12 @@ pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) table.Type { fn (mut c Checker) check_index_type(typ_sym &table.TypeSymbol, index_type table.Type, pos token.Position) { index_type_sym := c.table.get_type_symbol(index_type) - // println('index expr left=$typ_sym.name $node.pos.line_nr') + // println('index expr left=$typ_sym.source_name $node.pos.line_nr') // if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) && // index_type_sym.kind != .enum_) { if typ_sym.kind in [.array, .array_fixed] && !(index_type.is_number() || index_type_sym.kind == .enum_) { - c.error('non-integer index `$index_type_sym.name` (array type `$typ_sym.name`)', + c.error('non-integer index `$index_type_sym.source_name` (array type `$typ_sym.source_name`)', pos) } } @@ -3144,7 +3148,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { typ_sym := c.table.get_type_symbol(typ) if typ_sym.kind !in [.array, .array_fixed, .string, .map] && !typ.is_ptr() && !(!typ_sym.name[0].is_capital() && typ_sym.name.ends_with('ptr')) && !typ.has_flag(.variadic) { // byteptr, charptr etc - c.error('type `$typ_sym.name` does not support indexing', node.pos) + c.error('type `$typ_sym.source_name` does not support indexing', node.pos) } if typ_sym.kind == .string && !typ.is_ptr() && node.is_setter { c.error('cannot assign to s[i] since V strings are immutable\n' + @@ -3169,7 +3173,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { index_type := c.expr(node.index) c.check_index_type(typ_sym, index_type, node.pos) if typ_sym.kind == .map && index_type.idx() != table.string_type_idx { - c.error('non-string map index (map type `$typ_sym.name`)', node.pos) + c.error('non-string map index (map type `$typ_sym.source_name`)', node.pos) } value_type := c.table.value_type(typ) if value_type != table.void_type { @@ -3221,7 +3225,7 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) table.Type { return table.void_type } mut typ_sym := c.table.get_type_symbol(typ) - // println('tname=$typ_sym.name $node.pos.line_nr $c.file.path') + // println('tname=$typ_sym.source_name $node.pos.line_nr $c.file.path') if typ_sym.kind == .array && node.enum_name.len == 0 { array_info := typ_sym.info as table.Array typ = array_info.elem_type @@ -3229,7 +3233,7 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) table.Type { } if typ_sym.kind != .enum_ && !c.pref.translated { // TODO in C int fields can be compared to enums, need to handle that in C2V - c.error('expected type is not an enum (`$typ_sym.name`)', node.pos) + c.error('expected type is not an enum (`$typ_sym.source_name`)', node.pos) return table.void_type } if typ_sym.info !is table.Enum { @@ -3238,10 +3242,10 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) table.Type { } // info := typ_sym.info as table.Enum info := typ_sym.enum_info() - // rintln('checker: x = $info.x enum val $c.expected_type $typ_sym.name') + // rintln('checker: x = $info.x enum val $c.expected_type $typ_sym.source_name') // println(info.vals) if node.val !in info.vals { - c.error('enum `$typ_sym.name` does not have a value `$node.val`', node.pos) + c.error('enum `$typ_sym.source_name` does not have a value `$node.val`', node.pos) } node.typ = typ return typ @@ -3286,13 +3290,13 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type { if !c.check_types(key_type, key0_type) { key0_type_sym := c.table.get_type_symbol(key0_type) key_type_sym := c.table.get_type_symbol(key_type) - c.error('map init: cannot use `$key_type_sym.name` as `$key0_type_sym.name` for map key', + c.error('map init: cannot use `$key_type_sym.source_name` as `$key0_type_sym.source_name` for map key', node.pos) } if !c.check_types(val_type, val0_type) { val0_type_sym := c.table.get_type_symbol(val0_type) val_type_sym := c.table.get_type_symbol(val_type) - c.error('map init: cannot use `$val_type_sym.name` as `$val0_type_sym.name` for map value', + c.error('map init: cannot use `$val_type_sym.source_name` as `$val0_type_sym.source_name` for map value', node.pos) } } @@ -3404,7 +3408,7 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) table.Type { } sym := c.table.get_type_symbol(node.table_type) if sym.kind == .placeholder { - c.error('orm: unknown type `$sym.name`', node.pos) + c.error('orm: unknown type `$sym.source_name`', node.pos) return table.void_type } c.cur_orm_ts = sym @@ -3438,7 +3442,7 @@ fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) table.Type { } sym := c.table.get_type_symbol(node.table_type) if sym.kind == .placeholder { - c.error('orm: unknown type `$sym.name`', node.pos) + c.error('orm: unknown type `$sym.source_name`', node.pos) return table.void_type } c.cur_orm_ts = sym @@ -3474,7 +3478,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { for gen_type in c.table.fn_gen_types[node.name] { c.cur_generic_type = gen_type // sym:=c.table.get_type_symbol(gen_type) - // println('\ncalling check for $node.name for type $sym.name') + // println('\ncalling check for $node.name for type $sym.source_name') c.fn_decl(mut node) } c.cur_generic_type = 0 @@ -3503,8 +3507,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { } sym.methods.delete(idx) // - c.error('cannot define new methods on non-local `$sym.name` (' + - 'current module is `$c.mod`, `$sym.name` is from `$sym.mod`)', node.pos) + 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) } } if node.language == .v { @@ -3512,7 +3516,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { for arg in node.args { sym := c.table.get_type_symbol(arg.typ) if sym.kind == .placeholder { - c.error('unknown type `$sym.name`', node.pos) + c.error('unknown type `$sym.source_name`', node.pos) } } } diff --git a/vlib/v/checker/tests/cannot_assign_array.out b/vlib/v/checker/tests/cannot_assign_array.out index ea105b75dd..63a194cd8d 100644 --- a/vlib/v/checker/tests/cannot_assign_array.out +++ b/vlib/v/checker/tests/cannot_assign_array.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/cannot_assign_array.v:9:11: error: cannot assign `[]fixed_f64_8` to `ctx.vb` of type `string` +vlib/v/checker/tests/cannot_assign_array.v:9:11: error: cannot assign `[8]f64` to `ctx.vb` of type `string` 7 | mut ctx := Context{} 8 | x := 2.32 9 | ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]!! diff --git a/vlib/v/checker/tests/map_init_wrong_type.out b/vlib/v/checker/tests/map_init_wrong_type.out index 27d3a68247..0e2c8022bd 100644 --- a/vlib/v/checker/tests/map_init_wrong_type.out +++ b/vlib/v/checker/tests/map_init_wrong_type.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/map_init_wrong_type.v:3:10: error: cannot assign `map_string_f64` to `a` of type `map_string_f32` +vlib/v/checker/tests/map_init_wrong_type.v:3:10: error: cannot assign `map[string]f64` to `a` of type `map[string]f32` 1 | fn main() { 2 | mut a := map[string]f32{} 3 | a = { 'x': 12.3 } diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index cf3f781572..dbe9baa3a2 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -195,11 +195,13 @@ fn (mut p Parser) fn_decl() ast.FnDecl { if is_atomic { rec_type = rec_type.set_flag(.atomic_f) } + sym := p.table.get_type_symbol(rec_type) args << table.Arg{ pos: rec_start_pos name: rec_name is_mut: rec_mut typ: rec_type + type_source_name: sym.source_name } p.check(.rpar) } @@ -254,11 +256,13 @@ fn (mut p Parser) fn_decl() ast.FnDecl { // Register if is_method { mut type_sym := p.table.get_type_symbol(rec_type) + ret_type_sym := p.table.get_type_symbol(return_type) // p.warn('reg method $type_sym.name . $name ()') type_sym.register_method(table.Fn{ name: name args: args return_type: return_type + return_type_source_name: ret_type_sym.source_name is_variadic: is_variadic is_generic: is_generic is_pub: is_pub @@ -279,10 +283,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl { p.fn_redefinition_error(name) } // p.warn('reg functn $name ()') + ret_type_sym := p.table.get_type_symbol(return_type) p.table.register_fn(table.Fn{ name: name args: args return_type: return_type + return_type_source_name: ret_type_sym.source_name is_variadic: is_variadic is_generic: is_generic is_pub: is_pub @@ -358,10 +364,12 @@ fn (mut p Parser) anon_fn() ast.AnonFn { stmts = p.parse_block_no_scope(false) } p.close_scope() + ret_type_sym := p.table.get_type_symbol(return_type) mut func := table.Fn{ args: args is_variadic: is_variadic return_type: return_type + return_type_source_name: ret_type_sym.source_name } name := 'anon_${p.tok.pos}_$func.signature()' func.name = name @@ -447,11 +455,13 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) { } p.next() } + sym := p.table.get_type_symbol(arg_type) args << table.Arg{ pos: pos name: arg_name is_mut: is_mut typ: arg_type + type_source_name: sym.source_name } arg_no++ } @@ -507,11 +517,13 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) { typ = typ.set_flag(.variadic) } for i, arg_name in arg_names { + sym := p.table.get_type_symbol(typ) args << table.Arg{ pos: arg_pos[i] name: arg_name is_mut: is_mut typ: typ + type_source_name: sym.source_name } // if typ.typ.kind == .variadic && p.tok.kind == .comma { if is_variadic && p.tok.kind == .comma { diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index ec16e8ca71..91deee26ec 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -85,11 +85,13 @@ pub fn (mut p Parser) parse_fn_type(name string) table.Type { if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() { return_type = p.parse_type() } + ret_type_sym := p.table.get_type_symbol(return_type) func := table.Fn{ name: name args: args is_variadic: is_variadic return_type: return_type + return_type_source_name: ret_type_sym.source_name } idx := p.table.find_or_register_fn_type(p.mod, func, false, false) return table.new_type(idx) @@ -317,6 +319,7 @@ pub fn (mut p Parser) parse_generic_template_type(name string) table.Type { } idx = p.table.register_type_symbol(table.TypeSymbol{ name: name + source_name: name kind: .any is_public: true }) @@ -354,6 +357,7 @@ pub fn (mut p Parser) parse_generic_struct_inst_type(name string) table.Type { idx := p.table.register_type_symbol(table.TypeSymbol{ kind: .generic_struct_inst name: bs_name + source_name: bs_name info: table.GenericStructInst{ parent_idx: p.table.type_idxs[name] generic_types: generic_types diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 70fade5018..518bc1352f 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1537,9 +1537,11 @@ fn (mut p Parser) import_syms(mut parent ast.Import) { if alias[0].is_capital() { idx := p.table.add_placeholder_type(name) typ := table.new_type(idx) + prepend_mod_name := p.prepend_mod(alias) p.table.register_type_symbol({ kind: .alias - name: p.prepend_mod(alias) + name: prepend_mod_name + source_name: prepend_mod_name parent_idx: idx mod: p.mod info: table.Alias{ @@ -1761,6 +1763,7 @@ $pubfn (mut e $enum_name) toggle(flag $enum_name) { unsafe{ *e = int(*e) ^ ( p.table.register_type_symbol(table.TypeSymbol{ kind: .enum_ name: name + source_name: name mod: p.mod info: table.Enum{ vals: vals @@ -1821,9 +1824,11 @@ fn (mut p Parser) type_decl() ast.TypeDecl { } p.check(.pipe) } + prepend_mod_name := p.prepend_mod(name) p.table.register_type_symbol(table.TypeSymbol{ kind: .sum_type - name: p.prepend_mod(name) + name: prepend_mod_name + source_name: prepend_mod_name mod: p.mod info: table.SumType{ variants: sum_variants @@ -1848,9 +1853,11 @@ fn (mut p Parser) type_decl() ast.TypeDecl { } else { table.Language.v } + prepend_mod_name := p.prepend_mod(name) p.table.register_type_symbol({ kind: .alias - name: p.prepend_mod(name) + name: prepend_mod_name + source_name: prepend_mod_name parent_idx: pid mod: p.mod info: table.Alias{ diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 49da8dc27a..829891f328 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -230,6 +230,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { t := table.TypeSymbol{ kind: .struct_ name: name + source_name: name info: table.Struct{ fields: fields is_typedef: attrs.contains('typedef') @@ -359,6 +360,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { reg_idx := p.table.register_type_symbol(table.TypeSymbol{ kind: .interface_ name: interface_name + source_name: interface_name mod: p.mod info: table.Interface{ types: [] @@ -386,9 +388,11 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { } // field_names << name args2, _, _ := p.fn_args() // TODO merge table.Arg and ast.Arg to avoid this + sym := p.table.get_type_symbol(typ) mut args := [table.Arg{ name: 'x' typ: typ + type_source_name: sym.source_name is_hidden: true }] args << args2 @@ -406,10 +410,12 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { } methods << method // println('register method $name') + return_type_sym := p.table.get_type_symbol(method.return_type) ts.register_method(table.Fn{ name: name args: args return_type: method.return_type + return_type_source_name: return_type_sym.source_name is_pub: true }) } diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 2bcb233ab2..0688312f3e 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -26,14 +26,15 @@ pub enum Language { pub struct TypeSymbol { pub: - parent_idx int + parent_idx int pub mut: - info TypeInfo - kind Kind - name string - methods []Fn - mod string - is_public bool + info TypeInfo + kind Kind + name string // the internal name of the type, i.e. `array_fixed_int_5`. See also .source_name below. + source_name string // the original source name of the type, i.e. `[5]int`. Do not use this for logic, but just for formatting/errors. + methods []Fn + mod string + is_public bool } // max of 8 @@ -433,116 +434,139 @@ pub fn (mut t Table) register_builtin_type_symbols() { t.register_type_symbol(TypeSymbol{ kind: .void name: 'void' + source_name: 'void' mod: 'builtin' }) t.register_type_symbol({ kind: .voidptr name: 'voidptr' + source_name: 'voidptr' mod: 'builtin' }) t.register_type_symbol({ kind: .byteptr name: 'byteptr' + source_name: 'byteptr' mod: 'builtin' }) t.register_type_symbol({ kind: .charptr name: 'charptr' + source_name: 'charptr' mod: 'builtin' }) t.register_type_symbol({ kind: .i8 name: 'i8' + source_name: 'i8' mod: 'builtin' }) t.register_type_symbol({ kind: .i16 name: 'i16' + source_name: 'i16' mod: 'builtin' }) t.register_type_symbol({ kind: .int name: 'int' + source_name: 'int' mod: 'builtin' }) t.register_type_symbol({ kind: .i64 name: 'i64' + source_name: 'i64' mod: 'builtin' }) t.register_type_symbol({ kind: .byte name: 'byte' + source_name: 'byte' mod: 'builtin' }) t.register_type_symbol({ kind: .u16 name: 'u16' + source_name: 'u16' mod: 'builtin' }) t.register_type_symbol({ kind: .u32 name: 'u32' + source_name: 'u32' mod: 'builtin' }) t.register_type_symbol({ kind: .u64 name: 'u64' + source_name: 'u64' mod: 'builtin' }) t.register_type_symbol({ kind: .f32 name: 'f32' + source_name: 'f32' mod: 'builtin' }) t.register_type_symbol({ kind: .f64 name: 'f64' + source_name: 'f64' mod: 'builtin' }) t.register_type_symbol({ kind: .char name: 'char' + source_name: 'char' mod: 'builtin' }) t.register_type_symbol({ kind: .bool name: 'bool' + source_name: 'bool' mod: 'builtin' }) t.register_type_symbol({ kind: .none_ name: 'none' + source_name: 'none' mod: 'builtin' }) t.register_type_symbol({ kind: .string name: 'string' + source_name: 'string' mod: 'builtin' }) t.register_type_symbol({ kind: .ustring name: 'ustring' + source_name: 'ustring' mod: 'builtin' }) t.register_type_symbol({ kind: .array name: 'array' + source_name: 'array' mod: 'builtin' }) t.register_type_symbol({ kind: .map name: 'map' + source_name: 'map' mod: 'builtin' }) t.register_type_symbol({ kind: .chan name: 'chan' + source_name: 'chan' mod: 'builtin' }) t.register_type_symbol({ kind: .any name: 'any' + source_name: 'any' mod: 'builtin' }) // t.register_type_symbol({ @@ -554,16 +578,19 @@ pub fn (mut t Table) register_builtin_type_symbols() { t.register_type_symbol({ kind: .any_float name: 'any_float' + source_name: 'any_float' mod: 'builtin' }) t.register_type_symbol({ kind: .any_int name: 'any_int' + source_name: 'any_int' mod: 'builtin' }) t.register_type_symbol({ kind: .size_t name: 'size_t' + source_name: 'size_t' mod: 'builtin' }) // TODO: remove. for v1 map compatibility @@ -572,12 +599,14 @@ pub fn (mut t Table) register_builtin_type_symbols() { t.register_type_symbol({ kind: .alias name: 'map_string' + source_name: 'map_string' mod: 'builtin' parent_idx: map_string_string_idx }) t.register_type_symbol({ kind: .alias name: 'map_int' + source_name: 'map_int' mod: 'builtin' parent_idx: map_string_int_idx }) diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 03f3c5d2a9..db12d63819 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -22,29 +22,31 @@ pub mut: pub struct Fn { pub: - args []Arg - return_type Type - is_variadic bool - language Language - is_generic bool - is_pub bool - is_deprecated bool - is_unsafe bool - is_placeholder bool - mod string - ctdefine string // compile time define. myflag, when [if myflag] tag - attrs []Attr + args []Arg + return_type Type + return_type_source_name string + is_variadic bool + language Language + is_generic bool + is_pub bool + is_deprecated bool + is_unsafe bool + is_placeholder bool + mod string + ctdefine string // compile time define. myflag, when [if myflag] tag + attrs []Attr pub mut: - name string + name string } pub struct Arg { pub: - pos token.Position - name string - is_mut bool - typ Type - is_hidden bool // interface first arg + pos token.Position + name string + is_mut bool + typ Type + type_source_name string + is_hidden bool // interface first arg } pub struct Var { @@ -80,6 +82,22 @@ pub fn (f &Fn) signature() string { return sig } +// source_signature generates the signature of a function which looks like in the V source +pub fn (f &Fn) source_signature() string { + mut sig := '(' + for i, arg in f.args { + if arg.is_mut { + sig += 'mut ' + } + sig += '$arg.type_source_name' + if i < f.args.len - 1 { + sig += ', ' + } + } + sig += ') $f.return_type_source_name' + return sig +} + pub fn (f &Fn) is_same_method_as(func &Fn) bool { if f.return_type != func.return_type { return false @@ -306,6 +324,15 @@ pub fn (t &Table) array_name(elem_type Type, nr_dims int) string { } } +// array_source_name generates the original name for the v source. +// e. g. []int +[inline] +pub fn (t &Table) array_source_name(elem_type Type) string { + elem_type_sym := t.get_type_symbol(elem_type) + ptr := if elem_type.is_ptr() { '&' } else { '' } + return '[]$ptr$elem_type_sym.source_name' +} + [inline] pub fn (t &Table) array_fixed_name(elem_type Type, size, nr_dims int) string { elem_type_sym := t.get_type_symbol(elem_type) @@ -320,6 +347,15 @@ pub fn (t &Table) array_fixed_name(elem_type Type, size, nr_dims int) string { } } +// array_fixed_source_name generates the original name for the v source. +// e. g. [16][8]int +[inline] +pub fn (t &Table) array_fixed_source_name(elem_type Type, size int) string { + elem_type_sym := t.get_type_symbol(elem_type) + ptr := if elem_type.is_ptr() { '&' } else { '' } + return '[$size]$ptr$elem_type_sym.source_name' +} + [inline] pub fn (t &Table) chan_name(elem_type Type) string { elem_type_sym := t.get_type_symbol(elem_type) @@ -327,6 +363,13 @@ pub fn (t &Table) chan_name(elem_type Type) string { return 'chan_$elem_type_sym.name' + suffix } +[inline] +pub fn (t &Table) chan_source_name(elem_type Type) string { + elem_type_sym := t.get_type_symbol(elem_type) + ptr := if elem_type.is_ptr() { '&' } else { '' } + return 'chan $ptr$elem_type_sym.source_name' +} + [inline] pub fn (t &Table) map_name(key_type, value_type Type) string { key_type_sym := t.get_type_symbol(key_type) @@ -336,8 +379,19 @@ pub fn (t &Table) map_name(key_type, value_type Type) string { // return 'map_${value_type_sym.name}' + suffix } +// map_source_name generates the original name for the v source. +// e. g. map[string]int +[inline] +pub fn (t &Table) map_source_name(key_type, value_type Type) string { + key_type_sym := t.get_type_symbol(key_type) + value_type_sym := t.get_type_symbol(value_type) + ptr := if value_type.is_ptr() { '&' } else { '' } + return 'map[${key_type_sym.source_name}]$ptr$value_type_sym.source_name' +} + pub fn (mut t Table) find_or_register_chan(elem_type Type) int { name := t.chan_name(elem_type) + source_name := t.chan_source_name(elem_type) // existing existing_idx := t.type_idxs[name] if existing_idx > 0 { @@ -348,6 +402,7 @@ pub fn (mut t Table) find_or_register_chan(elem_type Type) int { parent_idx: chan_type_idx kind: .chan name: name + source_name: source_name info: Chan{ elem_type: elem_type } @@ -357,6 +412,7 @@ pub fn (mut t Table) find_or_register_chan(elem_type Type) int { pub fn (mut t Table) find_or_register_map(key_type, value_type Type) int { name := t.map_name(key_type, value_type) + source_name := t.map_source_name(key_type, value_type) // existing existing_idx := t.type_idxs[name] if existing_idx > 0 { @@ -367,6 +423,7 @@ pub fn (mut t Table) find_or_register_map(key_type, value_type Type) int { parent_idx: map_type_idx kind: .map name: name + source_name: source_name info: Map{ key_type: key_type value_type: value_type @@ -377,6 +434,7 @@ pub fn (mut t Table) find_or_register_map(key_type, value_type Type) int { pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int, mod string) int { name := t.array_name(elem_type, nr_dims) + source_name := t.array_source_name(elem_type) // existing existing_idx := t.type_idxs[name] if existing_idx > 0 { @@ -387,6 +445,7 @@ pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int, mod str parent_idx: array_type_idx kind: .array name: name + source_name: source_name info: Array{ elem_type: elem_type nr_dims: nr_dims @@ -398,6 +457,7 @@ pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int, mod str pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size, nr_dims int) int { name := t.array_fixed_name(elem_type, size, nr_dims) + source_name := t.array_fixed_source_name(elem_type, size) // existing existing_idx := t.type_idxs[name] if existing_idx > 0 { @@ -407,6 +467,7 @@ pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size, nr_dims array_fixed_type := TypeSymbol{ kind: .array_fixed name: name + source_name: source_name info: ArrayFixed{ elem_type: elem_type size: size @@ -418,10 +479,16 @@ pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size, nr_dims pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int { mut name := 'multi_return' - for mr_typ in mr_typs { + mut source_name := '(' + for i, mr_typ in mr_typs { mr_type_sym := t.get_type_symbol(mr_typ) name += '_$mr_type_sym.name' + source_name += mr_type_sym.source_name + if i < mr_typs.len - 1 { + source_name += ', ' + } } + source_name += ')' // existing existing_idx := t.type_idxs[name] if existing_idx > 0 { @@ -431,6 +498,7 @@ pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int { mr_type := TypeSymbol{ kind: .multi_return name: name + source_name: source_name info: MultiReturn{ types: mr_typs } @@ -439,11 +507,13 @@ pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int { } pub fn (mut t Table) find_or_register_fn_type(mod string, f Fn, is_anon, has_decl bool) int { - name := if f.name.len == 0 { 'anon_fn_$f.signature()' } else { f.name } + name := if f.name.len == 0 { 'anon_fn_$f.signature()' } else { f.name.clone() } + source_name := if f.name.len == 0 { 'fn $f.source_signature()' } else { f.name.clone() } anon := f.name.len == 0 || is_anon return t.register_type_symbol(TypeSymbol{ kind: .function name: name + source_name: source_name mod: mod info: FnType{ is_anon: anon @@ -457,6 +527,7 @@ pub fn (mut t Table) add_placeholder_type(name string) int { ph_type := TypeSymbol{ kind: .placeholder name: name + source_name: name } // println('added placeholder: $name - $ph_type.idx') return t.register_type_symbol(ph_type) diff --git a/vlib/x/websocket/handshake.v b/vlib/x/websocket/handshake.v index b7c4908db0..793355adbd 100644 --- a/vlib/x/websocket/handshake.v +++ b/vlib/x/websocket/handshake.v @@ -128,7 +128,7 @@ fn (mut ws Client) read_handshake_str() ?string { break } } - res := string(msg[..total_bytes_read]) + res := msg[..total_bytes_read].bytestr() return res } diff --git a/vlib/x/websocket/websocket_client.v b/vlib/x/websocket/websocket_client.v index 953e246a8e..2a9fef6ea5 100644 --- a/vlib/x/websocket/websocket_client.v +++ b/vlib/x/websocket/websocket_client.v @@ -183,7 +183,7 @@ pub fn (mut ws Client) listen() ? { if ws.state !in [.closing, .closed] { // sending close back according to spec ws.debug_log('close with reason, code: $code, reason: $reason') - r := if reason.len > 0 { string(reason, reason.len) } else { '' } + r := reason.bytestr() ws.close(code, r)? } unsafe { diff --git a/vlib/x/websocket/websocket_test.v b/vlib/x/websocket/websocket_test.v index 3ccd854ff5..5196cbc654 100644 --- a/vlib/x/websocket/websocket_test.v +++ b/vlib/x/websocket/websocket_test.v @@ -54,8 +54,9 @@ fn ws_test(uri string) ? { ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { println('client got type: $msg.opcode payload:\n$msg.payload') if msg.opcode == .text_frame { - println('Message: ${string(msg.payload, msg.payload.len)}') - assert string(msg.payload, msg.payload.len) == 'a' + smessage := msg.payload.bytestr() + println('Message: $smessage') + assert smessage == 'a' } else { println('Binary message: $msg') }