1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast: clean up ast.StructInit (#18518)

This commit is contained in:
yuyi 2023-06-22 21:41:08 +08:00 committed by GitHub
parent af4e113f6c
commit 22bd1b9d55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 125 additions and 124 deletions

View File

@ -1569,7 +1569,7 @@ fn (t Tree) struct_init(node ast.StructInit) &Node {
obj.add('pos', t.pos(node.pos)) obj.add('pos', t.pos(node.pos))
obj.add('name_pos', t.pos(node.name_pos)) obj.add('name_pos', t.pos(node.name_pos))
obj.add('update_expr_comments', t.array_node_comment(node.update_expr_comments)) obj.add('update_expr_comments', t.array_node_comment(node.update_expr_comments))
obj.add_terse('fields', t.array_node_struct_init_field(node.fields)) obj.add_terse('init_fields', t.array_node_struct_init_field(node.init_fields))
obj.add('pre_comments', t.array_node_comment(node.pre_comments)) obj.add('pre_comments', t.array_node_comment(node.pre_comments))
return obj return obj
} }

View File

@ -460,7 +460,7 @@ pub mut:
update_expr_comments []Comment update_expr_comments []Comment
is_update_embed bool is_update_embed bool
has_update_expr bool // has `...a` has_update_expr bool // has `...a`
fields []StructInitField init_fields []StructInitField
generic_types []Type generic_types []Type
} }
@ -2145,7 +2145,7 @@ pub fn (node Node) children() []Node {
return node.stmts.map(Node(it)) return node.stmts.map(Node(it))
} }
StructInit { StructInit {
return node.fields.map(Node(it)) return node.init_fields.map(Node(it))
} }
AnonFn { AnonFn {
children << Stmt(node.decl) children << Stmt(node.decl)

View File

@ -11,7 +11,7 @@ pub fn (t &Table) resolve_init(node StructInit, typ Type) Expr {
mut cap_expr := empty_expr mut cap_expr := empty_expr
mut default_expr := empty_expr mut default_expr := empty_expr
mut exprs := []Expr{} mut exprs := []Expr{}
for field in node.fields { for field in node.init_fields {
match field.name { match field.name {
'len' { 'len' {
has_len = true has_len = true
@ -48,7 +48,7 @@ pub fn (t &Table) resolve_init(node StructInit, typ Type) Expr {
Map { Map {
mut keys := []Expr{} mut keys := []Expr{}
mut vals := []Expr{} mut vals := []Expr{}
for field in node.fields { for field in node.init_fields {
keys << StringLiteral{ keys << StringLiteral{
val: field.name val: field.name
} }

View File

@ -2368,7 +2368,7 @@ pub fn (t &Table) dependent_names_in_expr(expr Expr) []string {
names << t.dependent_names_in_expr(expr.expr) names << t.dependent_names_in_expr(expr.expr)
} }
StructInit { StructInit {
for field in expr.fields { for field in expr.init_fields {
names << t.dependent_names_in_expr(field.expr) names << t.dependent_names_in_expr(field.expr)
} }
} }

View File

@ -694,7 +694,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
for ft in sym.info.fields { for ft in sym.info.fields {
field_sym := c.table.sym(ft.typ) field_sym := c.table.sym(ft.typ)
if field_sym.name == gt_name { if field_sym.name == gt_name {
for t in node.fields { for t in node.init_fields {
if ft.name == t.name && t.typ != 0 { if ft.name == t.name && t.typ != 0 {
concrete_types << ast.mktyp(t.typ) concrete_types << ast.mktyp(t.typ)
continue gname continue gname
@ -702,7 +702,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
} }
} }
if field_sym.info is ast.Array { if field_sym.info is ast.Array {
for t in node.fields { for t in node.init_fields {
if ft.name == t.name { if ft.name == t.name {
init_sym := c.table.sym(t.typ) init_sym := c.table.sym(t.typ)
if init_sym.info is ast.Array { if init_sym.info is ast.Array {
@ -730,7 +730,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
} }
} }
} else if field_sym.info is ast.ArrayFixed { } else if field_sym.info is ast.ArrayFixed {
for t in node.fields { for t in node.init_fields {
if ft.name == t.name { if ft.name == t.name {
init_sym := c.table.sym(t.typ) init_sym := c.table.sym(t.typ)
if init_sym.info is ast.ArrayFixed { if init_sym.info is ast.ArrayFixed {
@ -758,7 +758,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
} }
} }
} else if field_sym.info is ast.Map { } else if field_sym.info is ast.Map {
for t in node.fields { for t in node.init_fields {
if ft.name == t.name { if ft.name == t.name {
init_sym := c.table.sym(t.typ) init_sym := c.table.sym(t.typ)
if init_sym.info is ast.Map { if init_sym.info is ast.Map {
@ -786,7 +786,7 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit)
} }
} }
} else if field_sym.info is ast.FnType { } else if field_sym.info is ast.FnType {
for t in node.fields { for t in node.init_fields {
if ft.name == t.name { if ft.name == t.name {
init_sym := c.table.sym(t.typ) init_sym := c.table.sym(t.typ)
if init_sym.info is ast.FnType { if init_sym.info is ast.FnType {

View File

@ -4376,12 +4376,12 @@ fn (mut c Checker) error(message string, pos token.Pos) {
} }
fn (c &Checker) check_struct_signature_init_fields(from ast.Struct, to ast.Struct, node ast.StructInit) bool { fn (c &Checker) check_struct_signature_init_fields(from ast.Struct, to ast.Struct, node ast.StructInit) bool {
if node.fields.len == 0 { if node.init_fields.len == 0 {
return from.fields.len == to.fields.len return from.fields.len == to.fields.len
} }
mut count_not_in_from := 0 mut count_not_in_from := 0
for field in node.fields { for field in node.init_fields {
filtered := from.fields.filter(it.name == field.name) filtered := from.fields.filter(it.name == field.name)
if filtered.len != 1 { if filtered.len != 1 {
count_not_in_from++ count_not_in_from++

View File

@ -605,7 +605,7 @@ fn (_ &Checker) check_field_of_inserting_struct_is_uninitialized(node &ast.SqlSt
struct_scope := node.scope.find_var(node.object_var_name) or { return false } struct_scope := node.scope.find_var(node.object_var_name) or { return false }
if struct_scope.expr is ast.StructInit { if struct_scope.expr is ast.StructInit {
return struct_scope.expr.fields.filter(it.name == field_name).len == 0 return struct_scope.expr.init_fields.filter(it.name == field_name).len == 0
} }
return false return false

View File

@ -381,8 +381,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
c.error('cannot initialize enums', node.pos) c.error('cannot initialize enums', node.pos)
} }
} }
if type_sym.kind == .sum_type && node.fields.len == 1 { if type_sym.kind == .sum_type && node.init_fields.len == 1 {
sexpr := node.fields[0].expr.str() sexpr := node.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.name}(${sexpr})` not `${type_sym.name}{${sexpr}}`',
node.pos) node.pos)
} }
@ -420,16 +420,16 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
} }
.any { .any {
// `T{ foo: 22 }` // `T{ foo: 22 }`
for mut field in node.fields { for mut init_field in node.init_fields {
field.typ = c.expr(field.expr) init_field.typ = c.expr(init_field.expr)
field.expected_type = field.typ init_field.expected_type = init_field.typ
} }
sym := c.table.sym(c.unwrap_generic(node.typ)) sym := c.table.sym(c.unwrap_generic(node.typ))
if sym.kind == .struct_ { if sym.kind == .struct_ {
info := sym.info as ast.Struct info := sym.info as ast.Struct
if node.no_keys && node.fields.len != info.fields.len { if node.no_keys && node.init_fields.len != info.fields.len {
fname := if info.fields.len != 1 { 'fields' } else { 'field' } fname := if info.fields.len != 1 { 'fields' } else { 'field' }
c.error('initializing struct `${sym.name}` needs `${info.fields.len}` ${fname}, but got `${node.fields.len}`', c.error('initializing struct `${sym.name}` needs `${info.fields.len}` ${fname}, but got `${node.init_fields.len}`',
node.pos) node.pos)
} }
} }
@ -454,7 +454,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
} }
if node.no_keys { if node.no_keys {
exp_len := info.fields.len exp_len := info.fields.len
got_len := node.fields.len got_len := node.init_fields.len
if exp_len != got_len && !c.pref.translated { if exp_len != got_len && !c.pref.translated {
// XTODO remove !translated check // XTODO remove !translated check
amount := if exp_len < got_len { 'many' } else { 'few' } amount := if exp_len < got_len { 'many' } else { 'few' }
@ -467,7 +467,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
info_fields_sorted = info.fields.clone() info_fields_sorted = info.fields.clone()
info_fields_sorted.sort(a.i < b.i) info_fields_sorted.sort(a.i < b.i)
} }
for i, mut field in node.fields { for i, mut init_field in node.init_fields {
mut field_info := ast.StructField{} mut field_info := ast.StructField{}
mut field_name := '' mut field_name := ''
if node.no_keys { if node.no_keys {
@ -478,9 +478,9 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
} }
field_info = info_fields_sorted[i] field_info = info_fields_sorted[i]
field_name = field_info.name field_name = field_info.name
node.fields[i].name = field_name node.init_fields[i].name = field_name
} else { } else {
field_name = field.name field_name = init_field.name
mut exists := true mut exists := true
field_info = c.table.find_field_with_embeds(type_sym, field_name) or { field_info = c.table.find_field_with_embeds(type_sym, field_name) or {
exists = false exists = false
@ -488,13 +488,13 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
} }
if !exists { if !exists {
existing_fields := c.table.struct_fields(type_sym).map(it.name) existing_fields := c.table.struct_fields(type_sym).map(it.name)
c.error(util.new_suggestion(field.name, existing_fields).say('unknown field `${field.name}` in struct literal of type `${type_sym.name}`'), c.error(util.new_suggestion(init_field.name, existing_fields).say('unknown field `${init_field.name}` in struct literal of type `${type_sym.name}`'),
field.pos) init_field.pos)
continue continue
} }
if field_name in inited_fields { if field_name in inited_fields {
c.error('duplicate field name in struct literal: `${field_name}`', c.error('duplicate field name in struct literal: `${field_name}`',
field.pos) init_field.pos)
continue continue
} }
} }
@ -504,83 +504,84 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
exp_type = field_info.typ exp_type = field_info.typ
exp_type_sym := c.table.sym(exp_type) exp_type_sym := c.table.sym(exp_type)
c.expected_type = exp_type c.expected_type = exp_type
got_type = c.expr(field.expr) got_type = c.expr(init_field.expr)
got_type_sym := c.table.sym(got_type) got_type_sym := c.table.sym(got_type)
if got_type == ast.void_type { if got_type == ast.void_type {
c.error('`${field.expr}` (no value) used as value', field.pos) c.error('`${init_field.expr}` (no value) used as value', init_field.pos)
} }
if !exp_type.has_flag(.option) && !got_type.has_flag(.result) { if !exp_type.has_flag(.option) && !got_type.has_flag(.result) {
got_type = c.check_expr_opt_call(field.expr, got_type) got_type = c.check_expr_opt_call(init_field.expr, got_type)
if got_type.has_flag(.option) { if got_type.has_flag(.option) {
c.error('cannot assign an Option value to a non-option struct field', c.error('cannot assign an Option value to a non-option struct field',
field.pos) init_field.pos)
} }
} }
if exp_type_sym.kind == .voidptr && got_type_sym.kind == .struct_ if exp_type_sym.kind == .voidptr && got_type_sym.kind == .struct_
&& !got_type.is_ptr() { && !got_type.is_ptr() {
c.error('allocate on the heap for use in other functions', field.pos) c.error('allocate on the heap for use in other functions', init_field.pos)
} }
if exp_type_sym.kind == .interface_ { if exp_type_sym.kind == .interface_ {
if c.type_implements(got_type, exp_type, field.pos) { if c.type_implements(got_type, exp_type, init_field.pos) {
if !c.inside_unsafe && got_type_sym.kind != .interface_ if !c.inside_unsafe && got_type_sym.kind != .interface_
&& !got_type.is_any_kind_of_pointer() { && !got_type.is_any_kind_of_pointer() {
c.mark_as_referenced(mut &field.expr, true) c.mark_as_referenced(mut &init_field.expr, true)
} }
} }
} else if got_type != ast.void_type && got_type_sym.kind != .placeholder } else if got_type != ast.void_type && got_type_sym.kind != .placeholder
&& !exp_type.has_flag(.generic) { && !exp_type.has_flag(.generic) {
c.check_expected(c.unwrap_generic(got_type), c.unwrap_generic(exp_type)) or { c.check_expected(c.unwrap_generic(got_type), c.unwrap_generic(exp_type)) or {
c.error('cannot assign to field `${field_info.name}`: ${err.msg()}', c.error('cannot assign to field `${field_info.name}`: ${err.msg()}',
field.pos) init_field.pos)
} }
} }
if exp_type.has_flag(.shared_f) { if exp_type.has_flag(.shared_f) {
if !got_type.has_flag(.shared_f) && got_type.is_ptr() { if !got_type.has_flag(.shared_f) && got_type.is_ptr() {
c.error('`shared` field must be initialized with `shared` or value', c.error('`shared` field must be initialized with `shared` or value',
field.pos) init_field.pos)
} }
} else { } else {
if exp_type.is_ptr() && !got_type.is_any_kind_of_pointer() if exp_type.is_ptr() && !got_type.is_any_kind_of_pointer()
&& field.expr.str() != '0' && !exp_type.has_flag(.option) { && init_field.expr.str() != '0' && !exp_type.has_flag(.option) {
c.error('reference field must be initialized with reference', c.error('reference field must be initialized with reference',
field.pos) init_field.pos)
} else if exp_type.is_pointer() && !got_type.is_any_kind_of_pointer() } else if exp_type.is_pointer() && !got_type.is_any_kind_of_pointer()
&& !got_type.is_int() { && !got_type.is_int() {
got_typ_str := c.table.type_to_str(got_type) got_typ_str := c.table.type_to_str(got_type)
exp_typ_str := c.table.type_to_str(exp_type) exp_typ_str := c.table.type_to_str(exp_type)
c.error('cannot assign to field `${field_info.name}`: expected a pointer `${exp_typ_str}`, but got `${got_typ_str}`', c.error('cannot assign to field `${field_info.name}`: expected a pointer `${exp_typ_str}`, but got `${got_typ_str}`',
field.pos) init_field.pos)
} }
} }
node.fields[i].typ = got_type node.init_fields[i].typ = got_type
node.fields[i].expected_type = exp_type node.init_fields[i].expected_type = exp_type
if got_type.is_ptr() && exp_type.is_ptr() { if got_type.is_ptr() && exp_type.is_ptr() {
if mut field.expr is ast.Ident { if mut init_field.expr is ast.Ident {
c.fail_if_stack_struct_action_outside_unsafe(mut field.expr, 'assigned') c.fail_if_stack_struct_action_outside_unsafe(mut init_field.expr,
'assigned')
} }
} }
if field_info.typ in ast.unsigned_integer_type_idxs { if field_info.typ in ast.unsigned_integer_type_idxs {
if mut field.expr is ast.IntegerLiteral { if mut init_field.expr is ast.IntegerLiteral {
if field.expr.val[0] == `-` { if init_field.expr.val[0] == `-` {
c.error('cannot assign negative value to unsigned integer type', c.error('cannot assign negative value to unsigned integer type',
field.expr.pos) init_field.expr.pos)
} }
} }
} }
if exp_type_sym.kind == .struct_ && !(exp_type_sym.info as ast.Struct).is_anon if exp_type_sym.kind == .struct_ && !(exp_type_sym.info as ast.Struct).is_anon
&& mut field.expr is ast.StructInit { && mut init_field.expr is ast.StructInit {
if field.expr.is_anon { if init_field.expr.is_anon {
c.error('cannot assign anonymous `struct` to a typed `struct`', c.error('cannot assign anonymous `struct` to a typed `struct`',
field.expr.pos) init_field.expr.pos)
} }
} }
// all the fields of initialized embedded struct are ignored, they are considered initialized // all the fields of initialized embedded struct are ignored, they are considered initialized
sym := c.table.sym(field.typ) sym := c.table.sym(init_field.typ)
if field.name.len > 0 && field.name[0].is_capital() && sym.kind == .struct_ if init_field.name.len > 0 && init_field.name[0].is_capital()
&& sym.language == .v { && sym.kind == .struct_ && sym.language == .v {
struct_fields := c.table.struct_fields(sym) struct_fields := c.table.struct_fields(sym)
for struct_field in struct_fields { for struct_field in struct_fields {
inited_fields << struct_field.name inited_fields << struct_field.name
@ -666,7 +667,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
// Check for `[required]` struct attr // Check for `[required]` struct attr
if field.attrs.contains('required') && !node.no_keys && !node.has_update_expr { if field.attrs.contains('required') && !node.no_keys && !node.has_update_expr {
mut found := false mut found := false
for init_field in node.fields { for init_field in node.init_fields {
if field.name == init_field.name { if field.name == init_field.name {
found = true found = true
break break

View File

@ -767,7 +767,7 @@ fn expr_is_single_line(expr ast.Expr) bool {
} }
} }
ast.StructInit { ast.StructInit {
if !expr.no_keys && (expr.fields.len > 0 || expr.pre_comments.len > 0) { if !expr.no_keys && (expr.init_fields.len > 0 || expr.pre_comments.len > 0) {
return false return false
} }
} }

View File

@ -260,7 +260,7 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) {
if node.is_anon { if node.is_anon {
f.write('struct ') f.write('struct ')
} }
if node.fields.len == 0 && !node.has_update_expr { if node.init_fields.len == 0 && !node.has_update_expr {
// `Foo{}` on one line if there are no fields or comments // `Foo{}` on one line if there are no fields or comments
if node.pre_comments.len == 0 { if node.pre_comments.len == 0 {
f.write('${name}{}') f.write('${name}{}')
@ -279,9 +279,9 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) {
f.expr(node.update_expr) f.expr(node.update_expr)
f.write(', ') f.write(', ')
} }
for i, field in node.fields { for i, init_field in node.init_fields {
f.expr(field.expr) f.expr(init_field.expr)
if i < node.fields.len - 1 { if i < node.init_fields.len - 1 {
f.write(', ') f.write(', ')
} }
} }
@ -320,7 +320,7 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) {
f.write('...') f.write('...')
f.expr(node.update_expr) f.expr(node.update_expr)
if single_line_fields { if single_line_fields {
if node.fields.len > 0 { if node.init_fields.len > 0 {
f.write(', ') f.write(', ')
} }
} else { } else {
@ -328,21 +328,21 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) {
} }
f.comments(node.update_expr_comments, inline: true, has_nl: true, level: .keep) f.comments(node.update_expr_comments, inline: true, has_nl: true, level: .keep)
} }
for i, field in node.fields { for i, init_field in node.init_fields {
f.write('${field.name}: ') f.write('${init_field.name}: ')
f.expr(field.expr) f.expr(init_field.expr)
f.comments(field.comments, inline: true, has_nl: false, level: .indent) f.comments(init_field.comments, inline: true, has_nl: false, level: .indent)
if single_line_fields { if single_line_fields {
if i < node.fields.len - 1 { if i < node.init_fields.len - 1 {
f.write(', ') f.write(', ')
} }
} else { } else {
f.writeln('') f.writeln('')
} }
f.comments(field.next_comments, inline: false, has_nl: true, level: .keep) f.comments(init_field.next_comments, inline: false, has_nl: true, level: .keep)
if single_line_fields && (field.comments.len > 0 if single_line_fields && (init_field.comments.len > 0
|| field.next_comments.len > 0 || init_field.next_comments.len > 0
|| !expr_is_single_line(field.expr) || !expr_is_single_line(init_field.expr)
|| f.line_len > max_len.last()) { || f.line_len > max_len.last()) {
single_line_fields = false single_line_fields = false
f.out.go_back_to(fields_start) f.out.go_back_to(fields_start)

View File

@ -139,8 +139,8 @@ fn (mut g Gen) need_tmp_var_in_expr(expr ast.Expr) bool {
if g.need_tmp_var_in_expr(expr.update_expr) { if g.need_tmp_var_in_expr(expr.update_expr) {
return true return true
} }
for field in expr.fields { for init_field in expr.init_fields {
if g.need_tmp_var_in_expr(field.expr) { if g.need_tmp_var_in_expr(init_field.expr) {
return true return true
} }
} }

View File

@ -31,7 +31,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
} }
mut sym := g.table.final_sym(g.unwrap_generic(node.typ)) mut sym := g.table.final_sym(g.unwrap_generic(node.typ))
is_amp := g.is_amp is_amp := g.is_amp
is_multiline := node.fields.len > 5 is_multiline := node.init_fields.len > 5
g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly g.is_amp = false // reset the flag immediately so that other struct inits in this expr are handled correctly
if is_amp { if is_amp {
g.go_back(1) // delete the `&` already generated in `prefix_expr() g.go_back(1) // delete the `&` already generated in `prefix_expr()
@ -84,24 +84,24 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
// User set fields // User set fields
mut initialized := false mut initialized := false
mut old_is_shared := g.is_shared mut old_is_shared := g.is_shared
for i, field in node.fields { for i, init_field in node.init_fields {
if !field.typ.has_flag(.shared_f) { if !init_field.typ.has_flag(.shared_f) {
g.is_shared = false g.is_shared = false
} }
mut field_name := field.name mut field_name := init_field.name
if node.no_keys && sym.kind == .struct_ { if node.no_keys && sym.kind == .struct_ {
info := sym.info as ast.Struct info := sym.info as ast.Struct
if info.fields.len == node.fields.len { if info.fields.len == node.init_fields.len {
field_name = info.fields[i].name field_name = info.fields[i].name
} }
} }
inited_fields[field_name] = i inited_fields[field_name] = i
if sym.kind != .struct_ { if sym.kind != .struct_ {
if field.typ == 0 { if init_field.typ == 0 {
g.checker_bug('struct init, field.typ is 0', field.pos) g.checker_bug('struct init, field.typ is 0', init_field.pos)
} }
g.struct_init_field(field, sym.language) g.struct_init_field(init_field, sym.language)
if i != node.fields.len - 1 { if i != node.init_fields.len - 1 {
if is_multiline { if is_multiline {
g.writeln(',') g.writeln(',')
} else { } else {
@ -119,7 +119,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
if sym.kind == .struct_ { if sym.kind == .struct_ {
mut info := sym.info as ast.Struct mut info := sym.info as ast.Struct
nr_fields = info.fields.len nr_fields = info.fields.len
if info.is_union && node.fields.len > 1 { if info.is_union && node.init_fields.len > 1 {
verror('union must not have more than 1 initializer') verror('union must not have more than 1 initializer')
} }
if !info.is_union { if !info.is_union {
@ -127,7 +127,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
mut used_embed_fields := []string{} mut used_embed_fields := []string{}
init_field_names := info.fields.map(it.name) init_field_names := info.fields.map(it.name)
// fields that are initialized but belong to the embedding // fields that are initialized but belong to the embedding
init_fields_to_embed := node.fields.filter(it.name !in init_field_names) init_fields_to_embed := node.init_fields.filter(it.name !in init_field_names)
for embed in info.embeds { for embed in info.embeds {
embed_sym := g.table.sym(embed) embed_sym := g.table.sym(embed)
embed_name := embed_sym.embed_name() embed_name := embed_sym.embed_name()
@ -141,7 +141,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
...node ...node
typ: embed typ: embed
is_update_embed: true is_update_embed: true
fields: init_fields_to_embed init_fields: init_fields_to_embed
} }
inside_cast_in_heap := g.inside_cast_in_heap inside_cast_in_heap := g.inside_cast_in_heap
g.inside_cast_in_heap = 0 // prevent use of pointers in child structs g.inside_cast_in_heap = 0 // prevent use of pointers in child structs
@ -175,7 +175,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
} }
} }
if already_initalised_node_field_index := inited_fields[field.name] { if already_initalised_node_field_index := inited_fields[field.name] {
mut sfield := node.fields[already_initalised_node_field_index] mut sfield := node.init_fields[already_initalised_node_field_index]
if sfield.typ == 0 { if sfield.typ == 0 {
continue continue
} }
@ -214,7 +214,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
} }
if node.no_keys && sym.kind == .struct_ { if node.no_keys && sym.kind == .struct_ {
sym_info := sym.info as ast.Struct sym_info := sym.info as ast.Struct
if sym_info.fields.len == node.fields.len { if sym_info.fields.len == node.init_fields.len {
sfield.name = sym_info.fields[already_initalised_node_field_index].name sfield.name = sym_info.fields[already_initalised_node_field_index].name
} }
} }

View File

@ -681,7 +681,7 @@ fn expr_is_single_line(expr ast.Expr) bool {
} }
} }
ast.StructInit { ast.StructInit {
if !expr.no_keys && (expr.fields.len > 0 || expr.pre_comments.len > 0) { if !expr.no_keys && (expr.init_fields.len > 0 || expr.pre_comments.len > 0) {
return false return false
} }
} }

View File

@ -116,7 +116,7 @@ pub fn (mut f Gen) struct_init(node ast.StructInit) {
if name == 'void' { if name == 'void' {
name = '' name = ''
} }
if node.fields.len == 0 && !node.has_update_expr { if node.init_fields.len == 0 && !node.has_update_expr {
// `Foo{}` on one line if there are no fields or comments // `Foo{}` on one line if there are no fields or comments
if node.pre_comments.len == 0 { if node.pre_comments.len == 0 {
f.write('${name}{}') f.write('${name}{}')
@ -134,9 +134,9 @@ pub fn (mut f Gen) struct_init(node ast.StructInit) {
f.expr(node.update_expr) f.expr(node.update_expr)
f.write(', ') f.write(', ')
} }
for i, field in node.fields { for i, init_field in node.init_fields {
f.expr(field.expr) f.expr(init_field.expr)
if i < node.fields.len - 1 { if i < node.init_fields.len - 1 {
f.write(', ') f.write(', ')
} }
} }
@ -174,18 +174,18 @@ pub fn (mut f Gen) struct_init(node ast.StructInit) {
f.write('...') f.write('...')
f.expr(node.update_expr) f.expr(node.update_expr)
if single_line_fields { if single_line_fields {
if node.fields.len > 0 { if node.init_fields.len > 0 {
f.write(', ') f.write(', ')
} }
} else { } else {
f.writeln('') f.writeln('')
} }
} }
for i, field in node.fields { for i, init_field in node.init_fields {
f.write('${field.name}: ') f.write('${init_field.name}: ')
f.expr(field.expr) f.expr(init_field.expr)
if single_line_fields { if single_line_fields {
if i < node.fields.len - 1 { if i < node.init_fields.len - 1 {
f.write(', ') f.write(', ')
} }
} else { } else {

View File

@ -3419,22 +3419,22 @@ fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
if name.contains('<') { if name.contains('<') {
name = name[0..name.index('<') or { name.len }] name = name[0..name.index('<') or { name.len }]
} }
if it.fields.len == 0 && type_sym.kind != .interface_ { if it.init_fields.len == 0 && type_sym.kind != .interface_ {
if type_sym.kind == .struct_ && type_sym.language == .js { if type_sym.kind == .struct_ && type_sym.language == .js {
g.write('{}') g.write('{}')
} else { } else {
g.write('new ${g.js_name(name)}({})') g.write('new ${g.js_name(name)}({})')
} }
} else if it.fields.len == 0 && type_sym.kind == .interface_ { } else if it.init_fields.len == 0 && type_sym.kind == .interface_ {
g.write('new ${g.js_name(name)}()') // JS interfaces can be instantiated with default ctor g.write('new ${g.js_name(name)}()') // JS interfaces can be instantiated with default ctor
} else if type_sym.kind == .interface_ && it.fields.len != 0 { } else if type_sym.kind == .interface_ && it.init_fields.len != 0 {
g.writeln('(function () {') g.writeln('(function () {')
g.inc_indent() g.inc_indent()
g.writeln('let tmp = new ${g.js_name(name)}()') g.writeln('let tmp = new ${g.js_name(name)}()')
for field in it.fields { for init_field in it.init_fields {
g.write('tmp.${field.name} = ') g.write('tmp.${init_field.name} = ')
g.expr(field.expr) g.expr(init_field.expr)
g.writeln(';') g.writeln(';')
} }
g.writeln('return tmp') g.writeln('return tmp')
@ -3443,12 +3443,12 @@ fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
} else if type_sym.kind == .struct_ && type_sym.language == .js { } else if type_sym.kind == .struct_ && type_sym.language == .js {
g.writeln('{') g.writeln('{')
g.inc_indent() g.inc_indent()
for i, field in it.fields { for i, init_field in it.init_fields {
if field.name.len != 0 { if init_field.name.len != 0 {
g.write('${field.name}: ') g.write('${init_field.name}: ')
} }
g.expr(field.expr) g.expr(init_field.expr)
if i < it.fields.len - 1 { if i < it.init_fields.len - 1 {
g.write(',') g.write(',')
} }
g.writeln('') g.writeln('')
@ -3462,10 +3462,10 @@ fn (mut g JsGen) gen_struct_init(it ast.StructInit) {
tmp := g.new_tmp_var() tmp := g.new_tmp_var()
g.writeln('let ${tmp} = new ${g.js_name(name)}({});') g.writeln('let ${tmp} = new ${g.js_name(name)}({});')
for field in it.fields { for init_field in it.init_fields {
if field.name.len != 0 { if init_field.name.len != 0 {
g.write('${tmp}.${field.name} = ') g.write('${tmp}.${init_field.name} = ')
g.expr(field.expr) g.expr(init_field.expr)
} }
g.write(';') g.write(';')

View File

@ -3539,7 +3539,7 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
match ts.info { match ts.info {
ast.Struct { ast.Struct {
for i, f in ts.info.fields { for i, f in ts.info.fields {
if f.has_default_expr && !init.fields.map(it.name).contains(f.name) { if f.has_default_expr && !init.init_fields.map(it.name).contains(f.name) {
offset := c.g.structs[var.typ.idx()].offsets[i] offset := c.g.structs[var.typ.idx()].offsets[i]
c.g.expr(f.default_expr) c.g.expr(f.default_expr)
// TODO expr not on rax // TODO expr not on rax
@ -3549,7 +3549,7 @@ fn (mut c Amd64) init_struct(var Var, init ast.StructInit) {
} }
else {} else {}
} }
for f in init.fields { for f in init.init_fields {
field := ts.find_field(f.name) or { field := ts.find_field(f.name) or {
c.g.n_error('Could not find field `${f.name}` on init') c.g.n_error('Could not find field `${f.name}` on init')
} }

View File

@ -579,7 +579,7 @@ fn (mut g Gen) init_struct(var Var, init ast.StructInit) binaryen.Expression {
ts := g.table.sym(var.ast_typ) ts := g.table.sym(var.ast_typ)
match ts.info { match ts.info {
ast.Struct { ast.Struct {
if init.fields.len == 0 && !(ts.info.fields.any(it.has_default_expr)) { if init.init_fields.len == 0 && !(ts.info.fields.any(it.has_default_expr)) {
// Struct definition contains no default initialisers // Struct definition contains no default initialisers
// AND struct init contains no set values. // AND struct init contains no set values.
return g.mknblock('STRUCTINIT(ZERO)', [ return g.mknblock('STRUCTINIT(ZERO)', [
@ -588,7 +588,7 @@ fn (mut g Gen) init_struct(var Var, init ast.StructInit) binaryen.Expression {
} }
for i, f in ts.info.fields { for i, f in ts.info.fields {
field_to_be_set := init.fields.map(it.name).contains(f.name) field_to_be_set := init.init_fields.map(it.name).contains(f.name)
fts := g.table.sym(f.typ) fts := g.table.sym(f.typ)
if !field_to_be_set { if !field_to_be_set {
g.get_type_size_align(var.ast_typ) g.get_type_size_align(var.ast_typ)
@ -613,7 +613,7 @@ fn (mut g Gen) init_struct(var Var, init ast.StructInit) binaryen.Expression {
else {} else {}
} }
for f in init.fields { for f in init.init_fields {
field := ts.find_field(f.name) or { field := ts.find_field(f.name) or {
g.w_error('could not find field `${f.name}` on init') g.w_error('could not find field `${f.name}` on init')
} }

View File

@ -415,7 +415,7 @@ fn (mut w Walker) expr(node_ ast.Expr) {
if node.has_update_expr { if node.has_update_expr {
w.expr(node.update_expr) w.expr(node.update_expr)
} }
for sif in node.fields { for sif in node.init_fields {
w.expr(sif.expr) w.expr(sif.expr)
} }
} }

View File

@ -119,8 +119,8 @@ fn (mut p Parser) check_undefined_variables(names []string, val ast.Expr) ! {
} }
} }
ast.StructInit { ast.StructInit {
for field in val.fields { for init_field in val.init_fields {
p.check_undefined_variables(names, field.expr)! p.check_undefined_variables(names, init_field.expr)!
} }
} }
ast.UnsafeExpr { ast.UnsafeExpr {

View File

@ -407,7 +407,7 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
p.check(.lcbr) p.check(.lcbr)
} }
pre_comments := p.eat_comments() pre_comments := p.eat_comments()
mut fields := []ast.StructInitField{} mut init_fields := []ast.StructInitField{}
mut i := 0 mut i := 0
no_keys := p.peek_tok.kind != .colon && p.tok.kind != .rcbr && p.tok.kind != .ellipsis // `Vec{a,b,c} no_keys := p.peek_tok.kind != .colon && p.tok.kind != .rcbr && p.tok.kind != .ellipsis // `Vec{a,b,c}
saved_is_amp := p.is_amp saved_is_amp := p.is_amp
@ -423,7 +423,7 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
mut first_field_pos := token.Pos{} mut first_field_pos := token.Pos{}
mut comments := []ast.Comment{} mut comments := []ast.Comment{}
mut nline_comments := []ast.Comment{} mut nline_comments := []ast.Comment{}
is_update_expr := fields.len == 0 && p.tok.kind == .ellipsis is_update_expr := init_fields.len == 0 && p.tok.kind == .ellipsis
if no_keys { if no_keys {
// name will be set later in checker // name will be set later in checker
expr = p.expr(0) expr = p.expr(0)
@ -463,7 +463,7 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
comments << p.eat_comments(same_line: true) comments << p.eat_comments(same_line: true)
nline_comments << p.eat_comments() nline_comments << p.eat_comments()
if !is_update_expr { if !is_update_expr {
fields << ast.StructInitField{ init_fields << ast.StructInitField{
name: field_name name: field_name
expr: expr expr: expr
pos: field_pos pos: field_pos
@ -482,7 +482,7 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
unresolved: typ.has_flag(.generic) unresolved: typ.has_flag(.generic)
typ_str: typ_str typ_str: typ_str
typ: typ typ: typ
fields: fields init_fields: init_fields
update_expr: update_expr update_expr: update_expr
update_expr_pos: update_expr_pos update_expr_pos: update_expr_pos
update_expr_comments: update_expr_comments update_expr_comments: update_expr_comments

View File

@ -659,8 +659,8 @@ pub fn (mut t Transformer) expr(mut node ast.Expr) ast.Expr {
} }
ast.StructInit { ast.StructInit {
node.update_expr = t.expr(mut node.update_expr) node.update_expr = t.expr(mut node.update_expr)
for mut field in node.fields { for mut init_field in node.init_fields {
field.expr = t.expr(mut field.expr) init_field.expr = t.expr(mut init_field.expr)
} }
} }
ast.UnsafeExpr { ast.UnsafeExpr {