checker: remove redundant code of find field with embed (#12600)

pull/12611/head
yuyi 2021-11-29 03:31:19 +08:00 committed by GitHub
parent 87029e5707
commit 6d6a23a1c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 38 additions and 83 deletions

View File

@ -878,8 +878,6 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
mut inited_fields := []string{} mut inited_fields := []string{}
for i, mut field in node.fields { for i, mut field in node.fields {
mut field_info := ast.StructField{} mut field_info := ast.StructField{}
mut embed_type := ast.Type(0)
mut is_embed := false
mut field_name := '' mut field_name := ''
if node.is_short { if node.is_short {
if i >= info.fields.len { if i >= info.fields.len {
@ -893,27 +891,10 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
} else { } else {
field_name = field.name field_name = field.name
mut exists := true mut exists := true
field_info = info.find_field(field_name) or { field_info = c.table.find_field_with_embeds(type_sym, field_name) or {
exists = false exists = false
ast.StructField{} ast.StructField{}
} }
if !exists {
for embed in info.embeds {
embed_sym := c.table.get_type_symbol(embed)
if embed_sym.embed_name() == field_name {
exists = true
embed_type = embed
is_embed = true
break
}
embed_struct_info := embed_sym.info as ast.Struct
if embed_field_info := embed_struct_info.find_field(field_name) {
exists = true
field_info = embed_field_info
break
}
}
}
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.name`',
field.pos) field.pos)
@ -927,57 +908,43 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
} }
mut expr_type := ast.Type(0) mut expr_type := ast.Type(0)
mut expected_type := ast.Type(0) mut expected_type := ast.Type(0)
if is_embed { inited_fields << field_name
expected_type = embed_type field_type_sym := c.table.get_type_symbol(field_info.typ)
c.expected_type = expected_type expected_type = field_info.typ
expr_type = c.expr(field.expr) c.expected_type = expected_type
expr_type_sym := c.table.get_type_symbol(expr_type) expr_type = c.expr(field.expr)
if expr_type != ast.void_type && expr_type_sym.kind != .placeholder { if !field_info.typ.has_flag(.optional) {
c.check_expected(expr_type, embed_type) or { expr_type = c.check_expr_opt_call(field.expr, expr_type)
c.error('cannot assign to field `$field_info.name`: $err.msg',
field.pos)
}
}
node.fields[i].typ = expr_type
node.fields[i].expected_type = embed_type
} else {
inited_fields << field_name
field_type_sym := c.table.get_type_symbol(field_info.typ)
expected_type = field_info.typ
c.expected_type = expected_type
expr_type = c.expr(field.expr)
if !field_info.typ.has_flag(.optional) {
expr_type = c.check_expr_opt_call(field.expr, expr_type)
}
expr_type_sym := c.table.get_type_symbol(expr_type)
if field_type_sym.kind == .interface_ {
if c.type_implements(expr_type, field_info.typ, field.pos) {
if !expr_type.is_ptr() && !expr_type.is_pointer()
&& expr_type_sym.kind != .interface_ && !c.inside_unsafe {
c.mark_as_referenced(mut &field.expr, true)
}
}
} else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
c.check_expected(c.unwrap_generic(expr_type), c.unwrap_generic(field_info.typ)) or {
c.error('cannot assign to field `$field_info.name`: $err.msg',
field.pos)
}
}
if field_info.typ.has_flag(.shared_f) {
if !expr_type.has_flag(.shared_f) && expr_type.is_ptr() {
c.error('`shared` field must be initialized with `shared` or value',
field.pos)
}
} else {
if field_info.typ.is_ptr() && !expr_type.is_ptr() && !expr_type.is_pointer()
&& !expr_type.is_number() {
c.error('reference field must be initialized with reference',
field.pos)
}
}
node.fields[i].typ = expr_type
node.fields[i].expected_type = field_info.typ
} }
expr_type_sym := c.table.get_type_symbol(expr_type)
if field_type_sym.kind == .interface_ {
if c.type_implements(expr_type, field_info.typ, field.pos) {
if !expr_type.is_ptr() && !expr_type.is_pointer()
&& expr_type_sym.kind != .interface_ && !c.inside_unsafe {
c.mark_as_referenced(mut &field.expr, true)
}
}
} else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
c.check_expected(c.unwrap_generic(expr_type), c.unwrap_generic(field_info.typ)) or {
c.error('cannot assign to field `$field_info.name`: $err.msg',
field.pos)
}
}
if field_info.typ.has_flag(.shared_f) {
if !expr_type.has_flag(.shared_f) && expr_type.is_ptr() {
c.error('`shared` field must be initialized with `shared` or value',
field.pos)
}
} else {
if field_info.typ.is_ptr() && !expr_type.is_ptr() && !expr_type.is_pointer()
&& !expr_type.is_number() {
c.error('reference field must be initialized with reference',
field.pos)
}
}
node.fields[i].typ = expr_type
node.fields[i].expected_type = field_info.typ
if field_info.typ.has_flag(.optional) { if field_info.typ.has_flag(.optional) {
c.error('field `$field_info.name` is optional, but initialization of optional fields currently unsupported', c.error('field `$field_info.name` is optional, but initialization of optional fields currently unsupported',
field.pos) field.pos)
@ -1661,23 +1628,11 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
mut typ_sym := c.table.get_final_type_symbol(c.unwrap_generic(expr.expr_type)) mut typ_sym := c.table.get_final_type_symbol(c.unwrap_generic(expr.expr_type))
match typ_sym.kind { match typ_sym.kind {
.struct_ { .struct_ {
struct_info := typ_sym.info as ast.Struct
mut has_field := true mut has_field := true
mut field_info := struct_info.find_field(expr.field_name) or { mut field_info := c.table.find_field_with_embeds(typ_sym, expr.field_name) or {
has_field = false has_field = false
ast.StructField{} ast.StructField{}
} }
if !has_field {
for embed in struct_info.embeds {
embed_sym := c.table.get_type_symbol(embed)
embed_struct_info := embed_sym.info as ast.Struct
if embed_field_info := embed_struct_info.find_field(expr.field_name) {
has_field = true
field_info = embed_field_info
break
}
}
}
if !has_field { if !has_field {
type_str := c.table.type_to_str(expr.expr_type) type_str := c.table.type_to_str(expr.expr_type)
c.error('unknown field `${type_str}.$expr.field_name`', expr.pos) c.error('unknown field `${type_str}.$expr.field_name`', expr.pos)