all: TypeSymbol.source_name (#6187)

pull/6195/head
Daniel Däschle 2020-08-22 12:29:15 +02:00 committed by GitHub
parent b5ca114a96
commit fcc61a981d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 266 additions and 135 deletions

View File

@ -30,29 +30,26 @@ fn main() {
checksum = 0 checksum = 0
for len in str_lens { for len in str_lens {
end_pos := start_pos + len end_pos := start_pos + len
str := string(bytepile[start_pos..end_pos], len) checksum ^= wyhash.wyhash_c(unsafe { bytepile.data + start_pos }, u64(len), 1)
checksum ^= wyhash.wyhash_c(&str.str, u64(str.len), 1)
start_pos = end_pos 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() mut bhashing_2 := benchmark.start()
start_pos = 0 start_pos = 0
checksum = 0 checksum = 0
for len in str_lens { for len in str_lens {
end_pos := start_pos + len end_pos := start_pos + len
str := string(bytepile[start_pos..end_pos], len) checksum ^= wyhash.sum64(bytepile[start_pos..end_pos], 1)
checksum ^= wyhash.sum64_string(str, 1)
start_pos = end_pos 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() mut bhashing_3 := benchmark.start()
start_pos = 0 start_pos = 0
checksum = 0 checksum = 0
for len in str_lens { for len in str_lens {
end_pos := start_pos + len end_pos := start_pos + len
str := string(bytepile[start_pos..end_pos], len) checksum ^= fnv1a.sum64(bytepile[start_pos..end_pos])
checksum ^= fnv1a.sum64_string(str)
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}')
} }

View File

@ -58,7 +58,7 @@ fn start_client() ? {
// use on_message_ref if you want to send any reference object // use on_message_ref if you want to send any reference object
ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? {
if msg.payload.len > 0 { 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') println('client got type: $msg.opcode payload:\n$message')
} }
}) })

View File

@ -24,7 +24,7 @@ fn (mut ws Client) read_handshake(seckey string) {
unsafe { unsafe {
buffer[max_buffer - 1] = `\0` 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) { fn (mut ws Client) handshake_handler(handshake_response, seckey string) {

View File

@ -265,10 +265,10 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
} }
typ_sym := c.table.get_type_symbol(node.parent_type) typ_sym := c.table.get_type_symbol(node.parent_type)
if typ_sym.kind == .placeholder { 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 { } else if typ_sym.kind == .alias {
orig_sym := c.table.get_type_symbol((typ_sym.info as table.Alias).parent_type) 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) node.pos)
} }
} }
@ -279,12 +279,12 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
fn_info := fn_typ_info.func fn_info := fn_typ_info.func
ret_sym := c.table.get_type_symbol(fn_info.return_type) ret_sym := c.table.get_type_symbol(fn_info.return_type)
if ret_sym.kind == .placeholder { 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 { for arg in fn_info.args {
arg_sym := c.table.get_type_symbol(arg.typ) arg_sym := c.table.get_type_symbol(arg.typ)
if arg_sym.kind == .placeholder { 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 { for typ in node.sub_types {
typ_sym := c.table.get_type_symbol(typ) typ_sym := c.table.get_type_symbol(typ)
if typ_sym.kind == .placeholder { 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) sym := c.table.get_type_symbol(field.typ)
if sym.kind == .placeholder && decl.language != .c && !sym.name.starts_with('C.') { 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) field.pos)
} }
if sym.kind == .array { if sym.kind == .array {
array_info := sym.array_info() array_info := sym.array_info()
elem_sym := c.table.get_type_symbol(array_info.elem_type) elem_sym := c.table.get_type_symbol(array_info.elem_type)
if elem_sym.kind == .placeholder { 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) field.pos)
} }
} }
if sym.kind == .struct_ { if sym.kind == .struct_ {
info := sym.info as table.Struct info := sym.info as table.Struct
if info.is_ref_only && !field.typ.is_ptr() { 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) 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_expr_type_sym := c.table.get_type_symbol(field_expr_type)
field_type_sym := c.table.get_type_symbol(field.typ) field_type_sym := c.table.get_type_symbol(field.typ)
c.error('default expression for field `$field.name` ' + 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) type_sym := c.table.get_type_symbol(struct_init.typ)
if type_sym.kind == .sum_type && struct_init.fields.len == 1 { if type_sym.kind == .sum_type && struct_init.fields.len == 1 {
sexpr := struct_init.fields[0].expr.str() 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) struct_init.pos)
} }
if type_sym.kind == .interface_ { 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 { if type_sym.kind == .alias {
info := type_sym.info as table.Alias info := type_sym.info as table.Alias
if info.parent_type.is_number() { 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 return table.void_type
} }
} }
if !type_sym.is_public && type_sym.kind != .placeholder && type_sym.mod != c.mod { 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 { match type_sym.kind {
.placeholder { .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 // string & array are also structs but .kind of string/array
.struct_, .string, .array, .alias { .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 info_t := type_sym.info as table.Alias
sym := c.table.get_type_symbol(info_t.parent_type) sym := c.table.get_type_symbol(info_t.parent_type)
if sym.kind == .placeholder { // pending import symbol did not resolve 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 return table.void_type
} }
if sym.kind != .struct_ { 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 info = sym.info as table.Struct
} else { } else {
@ -437,7 +437,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
} }
} }
if !exists { 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) field.pos)
continue 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) 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 && if !c.check_types(expr_type, info_field.typ) && expr_type != table.void_type &&
expr_type_sym.kind != .placeholder { 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) field.pos)
} }
if info_field.typ.is_ptr() && !expr_type.is_ptr() && !expr_type.is_pointer() && 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 continue
} }
if field.typ.is_ptr() && !c.pref.translated { 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) struct_init.pos)
} }
} }
@ -515,14 +515,14 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
.array { .array {
right_sym := c.table.get_type_symbol(c.table.mktyp(right.array_info().elem_type)) right_sym := c.table.get_type_symbol(c.table.mktyp(right.array_info().elem_type))
if left_default.kind != right_sym.kind { 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) infix_expr.pos)
} }
} }
.map { .map {
key_sym := c.table.get_type_symbol(c.table.mktyp(right.map_info().key_type)) key_sym := c.table.get_type_symbol(c.table.mktyp(right.map_info().key_type))
if left_default.kind != key_sym.kind { 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) infix_expr.pos)
} }
} }
@ -617,8 +617,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
// []T << []T // []T << []T
return table.void_type return table.void_type
} }
s := left.name.replace('array_', '[]') c.error('cannot append `$right.source_name` to `$left.source_name`', right_pos)
c.error('cannot append `$right.name` to `$s`', right_pos)
return table.void_type return table.void_type
} else { } else {
return c.check_shift(left_type, right_type, left_pos, right_pos) 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 type_expr := infix_expr.right as ast.Type
typ_sym := c.table.get_type_symbol(type_expr.typ) typ_sym := c.table.get_type_symbol(type_expr.typ)
if typ_sym.kind == .placeholder { 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 { if left.kind != .interface_ && left.kind != .sum_type {
c.error('`$infix_expr.op.str()` can only be used with interfaces and sum types', 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) c.error('function needs exactly 1 argument', call_expr.pos)
} else if is_map && } else if is_map &&
(arg_expr.decl.return_type != elem_typ || arg_expr.decl.args[0].typ != elem_typ) { (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) call_expr.pos)
} else if !is_map && } else if !is_map &&
(arg_expr.decl.return_type != table.bool_type || arg_expr.decl.args[0].typ != elem_typ) { (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) 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 { if func.args.len > 1 {
c.error('function needs exactly 1 argument', call_expr.pos) 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) { } 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) call_expr.pos)
} else if !is_map && } else if !is_map &&
(func.return_type != table.bool_type || func.args[0].typ != elem_typ) { (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) 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 && if sym.kind != elem_sym.kind &&
((elem_sym.kind == .int && sym.kind != .any_int) || ((elem_sym.kind == .int && sym.kind != .any_int) ||
(elem_sym.kind == .f64 && sym.kind != .any_float)) { (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 { } else {
if arg_sym.kind != elem_sym.kind && if arg_sym.kind != elem_sym.kind &&
((elem_sym.kind == .int && arg_sym.kind != .any_int) || ((elem_sym.kind == .int && arg_sym.kind != .any_int) ||
(elem_sym.kind == .f64 && arg_sym.kind != .any_float)) { (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 // If a private method is called outside of the module
// its receiver type is defined in, show an error. // its receiver type is defined in, show an error.
// println('warn $method_name lef.mod=$left_type_sym.mod c.mod=$c.mod') // 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 { if method.args[0].is_mut {
c.fail_if_immutable(call_expr.left) 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 } 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 } 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 { 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) call_expr.pos)
} else if !method.is_variadic && call_expr.args.len > nr_args { } 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) call_expr.pos)
return method.return_type 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 { 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) call_expr.pos)
} }
} }
} }
if method.is_unsafe && !c.inside_unsafe { 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) call_expr.pos)
} }
// TODO: typ optimize.. this node can get processed more than once // 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 // TODO: str methods
if method_name == 'str' { if method_name == 'str' {
if left_type_sym.kind == .interface_ { 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', c.error('interface `$iname` does not have a .str() method. Use typeof() instead',
call_expr.pos) 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 { if left_type != table.void_type {
suggestion := util.new_suggestion(method_name, left_type_sym.methods.map(it.name)) 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) call_expr.pos)
} }
return table.void_type 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_sym := c.table.get_type_symbol(prtyp)
prtyp_is_ptr := prtyp.is_ptr() prtyp_is_ptr := prtyp.is_ptr()
prhas_str, prexpects_ptr, prnr_args := prtyp_sym.str_method_info() 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 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 == .array_fixed {
} }
if typ_sym.kind == .function && arg_typ_sym.kind == .function { 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`', c.error('cannot use $candidate_fn_name as function type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`',
call_expr.pos) call_expr.pos)
} else { } 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) 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 { if call_expr.generic_type != table.void_type && f.return_type != 0 { // table.t_type {
// Handle `foo<T>() T` => `foo<int>() int` => return int // Handle `foo<T>() T` => `foo<int>() int` => return int
return_sym := c.table.get_type_symbol(f.return_type) 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 return call_expr.generic_type
} else if return_sym.kind == .array { } else if return_sym.kind == .array {
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.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_sym.mod)
return table.new_type(idx) 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 { for imethod in inter_sym.methods {
if method := typ_sym.find_method(imethod.name) { if method := typ_sym.find_method(imethod.name) {
if !imethod.is_same_method_as(method) { 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) pos)
return false 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 field := c.table.struct_find_field(sym, field_name) {
if sym.mod != c.mod && !field.is_pub { 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 selector_expr.typ = field.typ
return field.typ return field.typ
} }
if sym.kind != .struct_ { if sym.kind != .struct_ {
if sym.kind != .placeholder { 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 { } 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 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) c.type_implements(got_typ, exp_type, return_stmt.pos)
continue 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) pos)
} }
if got_typ.is_ptr() && !exp_type.is_ptr() { 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. .assign {} // No need to do single side check for =. But here put it first for speed.
.plus_assign { .plus_assign {
if !left_sym.is_number() && left_type != table.string_type && !left_sym.is_pointer() { 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()) left.position())
} else if !right_sym.is_number() && right_type != table.string_type && !right_sym.is_pointer() { } 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()) right.position())
} }
if right is ast.IntegerLiteral && right.str().int() == 1 { 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 { .minus_assign {
if !left_sym.is_number() && !left_sym.is_pointer() { 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()) left.position())
} else if !right_sym.is_number() && !right_sym.is_pointer() { } 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()) right.position())
} }
if right is ast.IntegerLiteral && right.str().int() == 1 { 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 { .mult_assign, .div_assign {
if !left_sym.is_number() { 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()) left.position())
} else if !right_sym.is_number() { } 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()) right.position())
} }
} }
.and_assign, .or_assign, .xor_assign, .mod_assign, .left_shift_assign, .right_shift_assign { .and_assign, .or_assign, .xor_assign, .mod_assign, .left_shift_assign, .right_shift_assign {
if !left_sym.is_int() { 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()) left.position())
} else if !right_sym.is_int() { } 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()) right.position())
} }
} }
@ -1810,7 +1810,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
// Dual sides check (compatibility check) // Dual sides check (compatibility check)
if !is_blank_ident && !c.check_types(right_type_unwrapped, left_type_unwrapped) && if !is_blank_ident && !c.check_types(right_type_unwrapped, left_type_unwrapped) &&
right_sym.kind != .placeholder { 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()) 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) sym := c.table.get_type_symbol(array_init.elem_type)
if sym.kind == .placeholder { 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 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) { if !c.check_types(typ, elem_type) {
elem_type_sym := c.table.get_type_symbol(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 { 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 expr_type_sym.kind == .sum_type {
if type_sym.kind == .placeholder { if type_sym.kind == .placeholder {
// Unknown type used in the right part of `as` // 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) { 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) // c.error('only $info.variants can be casted to `$typ`', node.pos)
} }
} else { } 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.to_ptr()
// return node.typ // 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 }) 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) { 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) 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')) { (from_type_sym.kind == .array && from_type_sym.name == 'array_byte')) {
type_name := c.table.type_to_str(node.expr_type) type_name := c.table.type_to_str(node.expr_type)
c.error('cannot cast type `$type_name` to string, use `x.str()` instead', 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 from_type_info := from_type_sym.info as table.Struct
to_type_info := to_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) { 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) node.pos)
} }
} else { } else {
@ -2518,7 +2522,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
if !c.check_types(ltype, table.bool_type) { if !c.check_types(ltype, table.bool_type) {
ltype_sym := c.table.get_type_symbol(ltype) ltype_sym := c.table.get_type_symbol(ltype)
lname := if node.is_likely { '_likely_' } else { '_unlikely_' } 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) node.pos)
} }
return table.bool_type 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 { // if typ == table.t_type {
// sym := c.table.get_type_symbol(c.cur_generic_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 // Got a var with type T, return current generic type
// typ = c.cur_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) c.type_implements(typ, cond_type, node.pos)
} }
if !ok { 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) node.pos)
} }
} }
@ -2745,7 +2749,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type {
// TODO: ask alex about this // TODO: ask alex about this
// typ := c.expr(stmt.expr) // typ := c.expr(stmt.expr)
// type_sym := c.table.get_type_symbol(typ) // 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 // node.typ = typ
// return typ // return typ
} }
@ -2956,7 +2960,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
mut expr_required := false mut expr_required := false
if c.expected_type != table.void_type { if c.expected_type != table.void_type {
// sym := c.table.get_type_symbol(c.expected_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 expr_required = true
} }
former_expected_type := c.expected_type 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 // void types are skipped, because they mean the var was initialized incorrectly
// (via missing function etc) // (via missing function etc)
typ_sym := c.table.get_type_symbol(cond_typ) 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` // 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) typ_sym := c.table.get_type_symbol(typ)
// if !typ.is_number() { // if !typ.is_number() {
if !typ_sym.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) node.pos)
} else { } else {
node.auto_locked, _ = c.fail_if_immutable(node.expr) 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) { 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) 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) && // if typ_sym.kind == .array && (!(table.type_idx(index_type) in table.number_type_idxs) &&
// index_type_sym.kind != .enum_) { // index_type_sym.kind != .enum_) {
if typ_sym.kind in [.array, .array_fixed] && !(index_type.is_number() || index_type_sym.kind == if typ_sym.kind in [.array, .array_fixed] && !(index_type.is_number() || index_type_sym.kind ==
.enum_) { .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) 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) 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() && 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 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 { if typ_sym.kind == .string && !typ.is_ptr() && node.is_setter {
c.error('cannot assign to s[i] since V strings are immutable\n' + 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) index_type := c.expr(node.index)
c.check_index_type(typ_sym, index_type, node.pos) c.check_index_type(typ_sym, index_type, node.pos)
if typ_sym.kind == .map && index_type.idx() != table.string_type_idx { 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) value_type := c.table.value_type(typ)
if value_type != table.void_type { 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 return table.void_type
} }
mut typ_sym := c.table.get_type_symbol(typ) 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 { if typ_sym.kind == .array && node.enum_name.len == 0 {
array_info := typ_sym.info as table.Array array_info := typ_sym.info as table.Array
typ = array_info.elem_type 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 { if typ_sym.kind != .enum_ && !c.pref.translated {
// TODO in C int fields can be compared to enums, need to handle that in C2V // 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 return table.void_type
} }
if typ_sym.info !is table.Enum { 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.info as table.Enum
info := typ_sym.enum_info() 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) // println(info.vals)
if node.val !in 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 node.typ = typ
return 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) { if !c.check_types(key_type, key0_type) {
key0_type_sym := c.table.get_type_symbol(key0_type) key0_type_sym := c.table.get_type_symbol(key0_type)
key_type_sym := c.table.get_type_symbol(key_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) node.pos)
} }
if !c.check_types(val_type, val0_type) { if !c.check_types(val_type, val0_type) {
val0_type_sym := c.table.get_type_symbol(val0_type) val0_type_sym := c.table.get_type_symbol(val0_type)
val_type_sym := c.table.get_type_symbol(val_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) 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) sym := c.table.get_type_symbol(node.table_type)
if sym.kind == .placeholder { 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 return table.void_type
} }
c.cur_orm_ts = sym 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) sym := c.table.get_type_symbol(node.table_type)
if sym.kind == .placeholder { 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 return table.void_type
} }
c.cur_orm_ts = sym 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] { for gen_type in c.table.fn_gen_types[node.name] {
c.cur_generic_type = gen_type c.cur_generic_type = gen_type
// sym:=c.table.get_type_symbol(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.fn_decl(mut node)
} }
c.cur_generic_type = 0 c.cur_generic_type = 0
@ -3503,8 +3507,8 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
} }
sym.methods.delete(idx) sym.methods.delete(idx)
// //
c.error('cannot define new methods on non-local `$sym.name` (' + c.error('cannot define new methods on non-local `$sym.source_name` (' +
'current module is `$c.mod`, `$sym.name` is from `$sym.mod`)', node.pos) 'current module is `$c.mod`, `$sym.source_name` is from `$sym.mod`)', node.pos)
} }
} }
if node.language == .v { if node.language == .v {
@ -3512,7 +3516,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
for arg in node.args { for arg in node.args {
sym := c.table.get_type_symbol(arg.typ) sym := c.table.get_type_symbol(arg.typ)
if sym.kind == .placeholder { if sym.kind == .placeholder {
c.error('unknown type `$sym.name`', node.pos) c.error('unknown type `$sym.source_name`', node.pos)
} }
} }
} }

View File

@ -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{} 7 | mut ctx := Context{}
8 | x := 2.32 8 | x := 2.32
9 | ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]!! 9 | ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]!!

View File

@ -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() { 1 | fn main() {
2 | mut a := map[string]f32{} 2 | mut a := map[string]f32{}
3 | a = { 'x': 12.3 } 3 | a = { 'x': 12.3 }

View File

@ -195,11 +195,13 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
if is_atomic { if is_atomic {
rec_type = rec_type.set_flag(.atomic_f) rec_type = rec_type.set_flag(.atomic_f)
} }
sym := p.table.get_type_symbol(rec_type)
args << table.Arg{ args << table.Arg{
pos: rec_start_pos pos: rec_start_pos
name: rec_name name: rec_name
is_mut: rec_mut is_mut: rec_mut
typ: rec_type typ: rec_type
type_source_name: sym.source_name
} }
p.check(.rpar) p.check(.rpar)
} }
@ -254,11 +256,13 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
// Register // Register
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)
// p.warn('reg method $type_sym.name . $name ()') // p.warn('reg method $type_sym.name . $name ()')
type_sym.register_method(table.Fn{ type_sym.register_method(table.Fn{
name: name name: name
args: args args: args
return_type: return_type return_type: return_type
return_type_source_name: ret_type_sym.source_name
is_variadic: is_variadic is_variadic: is_variadic
is_generic: is_generic is_generic: is_generic
is_pub: is_pub is_pub: is_pub
@ -279,10 +283,12 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
p.fn_redefinition_error(name) p.fn_redefinition_error(name)
} }
// p.warn('reg functn $name ()') // p.warn('reg functn $name ()')
ret_type_sym := p.table.get_type_symbol(return_type)
p.table.register_fn(table.Fn{ p.table.register_fn(table.Fn{
name: name name: name
args: args args: args
return_type: return_type return_type: return_type
return_type_source_name: ret_type_sym.source_name
is_variadic: is_variadic is_variadic: is_variadic
is_generic: is_generic is_generic: is_generic
is_pub: is_pub is_pub: is_pub
@ -358,10 +364,12 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
stmts = p.parse_block_no_scope(false) stmts = p.parse_block_no_scope(false)
} }
p.close_scope() p.close_scope()
ret_type_sym := p.table.get_type_symbol(return_type)
mut func := table.Fn{ mut func := table.Fn{
args: args args: args
is_variadic: is_variadic is_variadic: is_variadic
return_type: return_type return_type: return_type
return_type_source_name: ret_type_sym.source_name
} }
name := 'anon_${p.tok.pos}_$func.signature()' name := 'anon_${p.tok.pos}_$func.signature()'
func.name = name func.name = name
@ -447,11 +455,13 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
} }
p.next() p.next()
} }
sym := p.table.get_type_symbol(arg_type)
args << table.Arg{ args << table.Arg{
pos: pos pos: pos
name: arg_name name: arg_name
is_mut: is_mut is_mut: is_mut
typ: arg_type typ: arg_type
type_source_name: sym.source_name
} }
arg_no++ arg_no++
} }
@ -507,11 +517,13 @@ fn (mut p Parser) fn_args() ([]table.Arg, bool, bool) {
typ = typ.set_flag(.variadic) typ = typ.set_flag(.variadic)
} }
for i, arg_name in arg_names { for i, arg_name in arg_names {
sym := p.table.get_type_symbol(typ)
args << table.Arg{ args << table.Arg{
pos: arg_pos[i] pos: arg_pos[i]
name: arg_name name: arg_name
is_mut: is_mut is_mut: is_mut
typ: typ typ: typ
type_source_name: sym.source_name
} }
// if typ.typ.kind == .variadic && p.tok.kind == .comma { // if typ.typ.kind == .variadic && p.tok.kind == .comma {
if is_variadic && p.tok.kind == .comma { if is_variadic && p.tok.kind == .comma {

View File

@ -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() { if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() {
return_type = p.parse_type() return_type = p.parse_type()
} }
ret_type_sym := p.table.get_type_symbol(return_type)
func := table.Fn{ func := table.Fn{
name: name name: name
args: args args: args
is_variadic: is_variadic is_variadic: is_variadic
return_type: return_type 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) idx := p.table.find_or_register_fn_type(p.mod, func, false, false)
return table.new_type(idx) 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{ idx = p.table.register_type_symbol(table.TypeSymbol{
name: name name: name
source_name: name
kind: .any kind: .any
is_public: true 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{ idx := p.table.register_type_symbol(table.TypeSymbol{
kind: .generic_struct_inst kind: .generic_struct_inst
name: bs_name name: bs_name
source_name: bs_name
info: table.GenericStructInst{ info: table.GenericStructInst{
parent_idx: p.table.type_idxs[name] parent_idx: p.table.type_idxs[name]
generic_types: generic_types generic_types: generic_types

View File

@ -1537,9 +1537,11 @@ fn (mut p Parser) import_syms(mut parent ast.Import) {
if alias[0].is_capital() { if alias[0].is_capital() {
idx := p.table.add_placeholder_type(name) idx := p.table.add_placeholder_type(name)
typ := table.new_type(idx) typ := table.new_type(idx)
prepend_mod_name := p.prepend_mod(alias)
p.table.register_type_symbol({ p.table.register_type_symbol({
kind: .alias kind: .alias
name: p.prepend_mod(alias) name: prepend_mod_name
source_name: prepend_mod_name
parent_idx: idx parent_idx: idx
mod: p.mod mod: p.mod
info: table.Alias{ 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{ p.table.register_type_symbol(table.TypeSymbol{
kind: .enum_ kind: .enum_
name: name name: name
source_name: name
mod: p.mod mod: p.mod
info: table.Enum{ info: table.Enum{
vals: vals vals: vals
@ -1821,9 +1824,11 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
} }
p.check(.pipe) p.check(.pipe)
} }
prepend_mod_name := p.prepend_mod(name)
p.table.register_type_symbol(table.TypeSymbol{ p.table.register_type_symbol(table.TypeSymbol{
kind: .sum_type kind: .sum_type
name: p.prepend_mod(name) name: prepend_mod_name
source_name: prepend_mod_name
mod: p.mod mod: p.mod
info: table.SumType{ info: table.SumType{
variants: sum_variants variants: sum_variants
@ -1848,9 +1853,11 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
} else { } else {
table.Language.v table.Language.v
} }
prepend_mod_name := p.prepend_mod(name)
p.table.register_type_symbol({ p.table.register_type_symbol({
kind: .alias kind: .alias
name: p.prepend_mod(name) name: prepend_mod_name
source_name: prepend_mod_name
parent_idx: pid parent_idx: pid
mod: p.mod mod: p.mod
info: table.Alias{ info: table.Alias{

View File

@ -230,6 +230,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
t := table.TypeSymbol{ t := table.TypeSymbol{
kind: .struct_ kind: .struct_
name: name name: name
source_name: name
info: table.Struct{ info: table.Struct{
fields: fields fields: fields
is_typedef: attrs.contains('typedef') 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{ reg_idx := p.table.register_type_symbol(table.TypeSymbol{
kind: .interface_ kind: .interface_
name: interface_name name: interface_name
source_name: interface_name
mod: p.mod mod: p.mod
info: table.Interface{ info: table.Interface{
types: [] types: []
@ -386,9 +388,11 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
} }
// field_names << name // field_names << name
args2, _, _ := p.fn_args() // TODO merge table.Arg and ast.Arg to avoid this 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{ mut args := [table.Arg{
name: 'x' name: 'x'
typ: typ typ: typ
type_source_name: sym.source_name
is_hidden: true is_hidden: true
}] }]
args << args2 args << args2
@ -406,10 +410,12 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
} }
methods << method methods << method
// println('register method $name') // println('register method $name')
return_type_sym := p.table.get_type_symbol(method.return_type)
ts.register_method(table.Fn{ ts.register_method(table.Fn{
name: name name: name
args: args args: args
return_type: method.return_type return_type: method.return_type
return_type_source_name: return_type_sym.source_name
is_pub: true is_pub: true
}) })
} }

View File

@ -26,14 +26,15 @@ pub enum Language {
pub struct TypeSymbol { pub struct TypeSymbol {
pub: pub:
parent_idx int parent_idx int
pub mut: pub mut:
info TypeInfo info TypeInfo
kind Kind kind Kind
name string name string // the internal name of the type, i.e. `array_fixed_int_5`. See also .source_name below.
methods []Fn 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.
mod string methods []Fn
is_public bool mod string
is_public bool
} }
// max of 8 // max of 8
@ -433,116 +434,139 @@ pub fn (mut t Table) register_builtin_type_symbols() {
t.register_type_symbol(TypeSymbol{ t.register_type_symbol(TypeSymbol{
kind: .void kind: .void
name: 'void' name: 'void'
source_name: 'void'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .voidptr kind: .voidptr
name: 'voidptr' name: 'voidptr'
source_name: 'voidptr'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .byteptr kind: .byteptr
name: 'byteptr' name: 'byteptr'
source_name: 'byteptr'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .charptr kind: .charptr
name: 'charptr' name: 'charptr'
source_name: 'charptr'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .i8 kind: .i8
name: 'i8' name: 'i8'
source_name: 'i8'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .i16 kind: .i16
name: 'i16' name: 'i16'
source_name: 'i16'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .int kind: .int
name: 'int' name: 'int'
source_name: 'int'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .i64 kind: .i64
name: 'i64' name: 'i64'
source_name: 'i64'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .byte kind: .byte
name: 'byte' name: 'byte'
source_name: 'byte'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .u16 kind: .u16
name: 'u16' name: 'u16'
source_name: 'u16'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .u32 kind: .u32
name: 'u32' name: 'u32'
source_name: 'u32'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .u64 kind: .u64
name: 'u64' name: 'u64'
source_name: 'u64'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .f32 kind: .f32
name: 'f32' name: 'f32'
source_name: 'f32'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .f64 kind: .f64
name: 'f64' name: 'f64'
source_name: 'f64'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .char kind: .char
name: 'char' name: 'char'
source_name: 'char'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .bool kind: .bool
name: 'bool' name: 'bool'
source_name: 'bool'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .none_ kind: .none_
name: 'none' name: 'none'
source_name: 'none'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .string kind: .string
name: 'string' name: 'string'
source_name: 'string'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .ustring kind: .ustring
name: 'ustring' name: 'ustring'
source_name: 'ustring'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .array kind: .array
name: 'array' name: 'array'
source_name: 'array'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .map kind: .map
name: 'map' name: 'map'
source_name: 'map'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .chan kind: .chan
name: 'chan' name: 'chan'
source_name: 'chan'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .any kind: .any
name: 'any' name: 'any'
source_name: 'any'
mod: 'builtin' mod: 'builtin'
}) })
// t.register_type_symbol({ // t.register_type_symbol({
@ -554,16 +578,19 @@ pub fn (mut t Table) register_builtin_type_symbols() {
t.register_type_symbol({ t.register_type_symbol({
kind: .any_float kind: .any_float
name: 'any_float' name: 'any_float'
source_name: 'any_float'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .any_int kind: .any_int
name: 'any_int' name: 'any_int'
source_name: 'any_int'
mod: 'builtin' mod: 'builtin'
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .size_t kind: .size_t
name: 'size_t' name: 'size_t'
source_name: 'size_t'
mod: 'builtin' mod: 'builtin'
}) })
// TODO: remove. for v1 map compatibility // TODO: remove. for v1 map compatibility
@ -572,12 +599,14 @@ pub fn (mut t Table) register_builtin_type_symbols() {
t.register_type_symbol({ t.register_type_symbol({
kind: .alias kind: .alias
name: 'map_string' name: 'map_string'
source_name: 'map_string'
mod: 'builtin' mod: 'builtin'
parent_idx: map_string_string_idx parent_idx: map_string_string_idx
}) })
t.register_type_symbol({ t.register_type_symbol({
kind: .alias kind: .alias
name: 'map_int' name: 'map_int'
source_name: 'map_int'
mod: 'builtin' mod: 'builtin'
parent_idx: map_string_int_idx parent_idx: map_string_int_idx
}) })

View File

@ -22,29 +22,31 @@ pub mut:
pub struct Fn { pub struct Fn {
pub: pub:
args []Arg args []Arg
return_type Type return_type Type
is_variadic bool return_type_source_name string
language Language is_variadic bool
is_generic bool language Language
is_pub bool is_generic bool
is_deprecated bool is_pub bool
is_unsafe bool is_deprecated bool
is_placeholder bool is_unsafe bool
mod string is_placeholder bool
ctdefine string // compile time define. myflag, when [if myflag] tag mod string
attrs []Attr ctdefine string // compile time define. myflag, when [if myflag] tag
attrs []Attr
pub mut: pub mut:
name string name string
} }
pub struct Arg { pub struct Arg {
pub: pub:
pos token.Position pos token.Position
name string name string
is_mut bool is_mut bool
typ Type typ Type
is_hidden bool // interface first arg type_source_name string
is_hidden bool // interface first arg
} }
pub struct Var { pub struct Var {
@ -80,6 +82,22 @@ pub fn (f &Fn) signature() string {
return sig 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 { pub fn (f &Fn) is_same_method_as(func &Fn) bool {
if f.return_type != func.return_type { if f.return_type != func.return_type {
return false 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] [inline]
pub fn (t &Table) array_fixed_name(elem_type Type, size, nr_dims int) string { pub fn (t &Table) array_fixed_name(elem_type Type, size, nr_dims int) string {
elem_type_sym := t.get_type_symbol(elem_type) 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] [inline]
pub fn (t &Table) chan_name(elem_type Type) string { pub fn (t &Table) chan_name(elem_type Type) string {
elem_type_sym := t.get_type_symbol(elem_type) 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 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] [inline]
pub fn (t &Table) map_name(key_type, value_type Type) string { pub fn (t &Table) map_name(key_type, value_type Type) string {
key_type_sym := t.get_type_symbol(key_type) 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 // 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 { pub fn (mut t Table) find_or_register_chan(elem_type Type) int {
name := t.chan_name(elem_type) name := t.chan_name(elem_type)
source_name := t.chan_source_name(elem_type)
// existing // existing
existing_idx := t.type_idxs[name] existing_idx := t.type_idxs[name]
if existing_idx > 0 { 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 parent_idx: chan_type_idx
kind: .chan kind: .chan
name: name name: name
source_name: source_name
info: Chan{ info: Chan{
elem_type: elem_type 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 { pub fn (mut t Table) find_or_register_map(key_type, value_type Type) int {
name := t.map_name(key_type, value_type) name := t.map_name(key_type, value_type)
source_name := t.map_source_name(key_type, value_type)
// existing // existing
existing_idx := t.type_idxs[name] existing_idx := t.type_idxs[name]
if existing_idx > 0 { 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 parent_idx: map_type_idx
kind: .map kind: .map
name: name name: name
source_name: source_name
info: Map{ info: Map{
key_type: key_type key_type: key_type
value_type: value_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 { 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) name := t.array_name(elem_type, nr_dims)
source_name := t.array_source_name(elem_type)
// existing // existing
existing_idx := t.type_idxs[name] existing_idx := t.type_idxs[name]
if existing_idx > 0 { 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 parent_idx: array_type_idx
kind: .array kind: .array
name: name name: name
source_name: source_name
info: Array{ info: Array{
elem_type: elem_type elem_type: elem_type
nr_dims: nr_dims 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 { 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) name := t.array_fixed_name(elem_type, size, nr_dims)
source_name := t.array_fixed_source_name(elem_type, size)
// existing // existing
existing_idx := t.type_idxs[name] existing_idx := t.type_idxs[name]
if existing_idx > 0 { 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{ array_fixed_type := TypeSymbol{
kind: .array_fixed kind: .array_fixed
name: name name: name
source_name: source_name
info: ArrayFixed{ info: ArrayFixed{
elem_type: elem_type elem_type: elem_type
size: size 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 { pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int {
mut name := 'multi_return' 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) mr_type_sym := t.get_type_symbol(mr_typ)
name += '_$mr_type_sym.name' name += '_$mr_type_sym.name'
source_name += mr_type_sym.source_name
if i < mr_typs.len - 1 {
source_name += ', '
}
} }
source_name += ')'
// existing // existing
existing_idx := t.type_idxs[name] existing_idx := t.type_idxs[name]
if existing_idx > 0 { 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{ mr_type := TypeSymbol{
kind: .multi_return kind: .multi_return
name: name name: name
source_name: source_name
info: MultiReturn{ info: MultiReturn{
types: mr_typs 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 { 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 anon := f.name.len == 0 || is_anon
return t.register_type_symbol(TypeSymbol{ return t.register_type_symbol(TypeSymbol{
kind: .function kind: .function
name: name name: name
source_name: source_name
mod: mod mod: mod
info: FnType{ info: FnType{
is_anon: anon is_anon: anon
@ -457,6 +527,7 @@ pub fn (mut t Table) add_placeholder_type(name string) int {
ph_type := TypeSymbol{ ph_type := TypeSymbol{
kind: .placeholder kind: .placeholder
name: name name: name
source_name: name
} }
// println('added placeholder: $name - $ph_type.idx') // println('added placeholder: $name - $ph_type.idx')
return t.register_type_symbol(ph_type) return t.register_type_symbol(ph_type)

View File

@ -128,7 +128,7 @@ fn (mut ws Client) read_handshake_str() ?string {
break break
} }
} }
res := string(msg[..total_bytes_read]) res := msg[..total_bytes_read].bytestr()
return res return res
} }

View File

@ -183,7 +183,7 @@ pub fn (mut ws Client) listen() ? {
if ws.state !in [.closing, .closed] { if ws.state !in [.closing, .closed] {
// sending close back according to spec // sending close back according to spec
ws.debug_log('close with reason, code: $code, reason: $reason') 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)? ws.close(code, r)?
} }
unsafe { unsafe {

View File

@ -54,8 +54,9 @@ fn ws_test(uri string) ? {
ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? {
println('client got type: $msg.opcode payload:\n$msg.payload') println('client got type: $msg.opcode payload:\n$msg.payload')
if msg.opcode == .text_frame { if msg.opcode == .text_frame {
println('Message: ${string(msg.payload, msg.payload.len)}') smessage := msg.payload.bytestr()
assert string(msg.payload, msg.payload.len) == 'a' println('Message: $smessage')
assert smessage == 'a'
} else { } else {
println('Binary message: $msg') println('Binary message: $msg')
} }