cgen: fix typeof comptime selector (fix #12461) (#12463)

pull/12468/head
yuyi 2021-11-15 16:23:49 +08:00 committed by GitHub
parent e3d98b1b28
commit d8479f107f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 3 deletions

View File

@ -2968,7 +2968,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
scope: 0
}
left_sym := g.table.get_type_symbol(g.unwrap_generic(var_type))
if left is ast.Ident {
if mut left is ast.Ident {
ident = left
// id_info := ident.var_info()
// var_type = id_info.typ
@ -2984,7 +2984,16 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
var_type = var_type.set_flag(.atomic_f)
}
}
if left.obj is ast.Var {
if mut left.obj is ast.Var {
if val is ast.ComptimeSelector {
if val.field_expr is ast.SelectorExpr {
if val.field_expr.expr is ast.Ident {
key_str := '${val.field_expr.expr.name}.typ'
var_type = g.comptime_var_type_map[key_str] or { var_type }
left.obj.typ = var_type
}
}
}
is_auto_heap = left.obj.is_auto_heap
}
}
@ -4098,7 +4107,18 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
.unknown {
if node.field_name == 'name' {
// typeof(expr).name
g.type_name(node.name_type)
mut name_type := node.name_type
if node.expr is ast.TypeOf {
if node.expr.expr is ast.ComptimeSelector {
if node.expr.expr.field_expr is ast.SelectorExpr {
if node.expr.expr.field_expr.expr is ast.Ident {
key_str := '${node.expr.expr.field_expr.expr.name}.typ'
name_type = g.comptime_var_type_map[key_str] or { name_type }
}
}
}
}
g.type_name(name_type)
return
} else if node.field_name == 'idx' {
// typeof(expr).idx

View File

@ -819,6 +819,12 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
return
}
}
} else if node.left is ast.Ident && g.comptime_var_type_map.len > 0 {
if node.left.obj is ast.Var {
rec_type = node.left.obj.typ
g.gen_expr_to_string(node.left, rec_type)
return
}
}
g.get_str_fn(rec_type)
} else if node.name == 'free' {
@ -1130,6 +1136,10 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
typ = g.comptime_var_type_map[key_str] or { typ }
}
}
} else if expr is ast.Ident {
if expr.obj is ast.Var {
typ = expr.obj.typ
}
}
g.gen_expr_to_string(expr, typ)
g.write(')')

View File

@ -1,15 +1,36 @@
fn print_field_values<T>(s T) {
mut value_list := []string{}
mut value_type_list := []string{}
mut var_value_list := []string{}
$for field in T.fields {
println(s.$(field.name))
value_list << s.$(field.name).str()
println(typeof(s.$(field.name)).name)
value_type_list << typeof(s.$(field.name)).name
val := s.$(field.name)
println(val)
var_value_list << val.str()
}
assert value_list.len == 4
assert value_list[0] == 'Simon'
assert value_list[1] == 'simon1234'
assert value_list[2] == 'simon@gmail.com'
assert value_list[3] == '15'
assert value_type_list.len == 4
assert value_type_list[0] == 'string'
assert value_type_list[1] == 'string'
assert value_type_list[2] == 'string'
assert value_type_list[3] == 'int'
assert var_value_list.len == 4
assert var_value_list[0] == 'Simon'
assert var_value_list[1] == 'simon1234'
assert var_value_list[2] == 'simon@gmail.com'
assert var_value_list[3] == '15'
}
struct Foo {