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

cgen: fill in the new FieldData fields, add tests (#16774)

This commit is contained in:
Delyan Angelov 2022-12-26 23:35:13 +02:00 committed by GitHub
parent 9b28a7aa96
commit 6b3f8f519d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 138 additions and 2 deletions

View File

@ -187,7 +187,7 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
unwrapped_expr_type := c.unwrap_generic(field.typ)
tsym := c.table.sym(unwrapped_expr_type)
c.table.dumps[int(unwrapped_expr_type.clear_flag(.optional).clear_flag(.result))] = tsym.cname
c.table.dumps[int(unwrapped_expr_type.clear_flag(.optional).clear_flag(.result).clear_flag(.atomic_f))] = tsym.cname
}
c.comptime_for_field_var = ''
c.inside_comptime_for_field = false

View File

@ -584,7 +584,7 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
'\t${node.val_var}.attrs = new_array_from_c_array(${attrs.len}, ${attrs.len}, sizeof(string), _MOV((string[${attrs.len}]){' +
attrs.join(', ') + '}));\n')
}
// field_sym := g.table.sym(field.typ)
field_sym := g.table.sym(field.typ)
// g.writeln('\t${node.val_var}.typ = _SLIT("$field_sym.name");')
styp := field.typ
unaliased_styp := g.table.unaliased_type(styp)
@ -593,7 +593,17 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
g.writeln('\t${node.val_var}.unaliased_typ = ${unaliased_styp.idx()};')
g.writeln('\t${node.val_var}.is_pub = ${field.is_pub};')
g.writeln('\t${node.val_var}.is_mut = ${field.is_mut};')
//
g.writeln('\t${node.val_var}.is_shared = ${field.typ.has_flag(.shared_f)};')
g.writeln('\t${node.val_var}.is_atomic = ${field.typ.has_flag(.atomic_f)};')
g.writeln('\t${node.val_var}.is_optional = ${field.typ.has_flag(.optional)};')
//
g.writeln('\t${node.val_var}.is_array = ${field_sym.kind in [.array, .array_fixed]};')
g.writeln('\t${node.val_var}.is_map = ${field_sym.kind == .map};')
g.writeln('\t${node.val_var}.is_chan = ${field_sym.kind == .chan};')
g.writeln('\t${node.val_var}.is_struct = ${field_sym.kind == .struct_};')
g.writeln('\t${node.val_var}.indirections = ${field.typ.nr_muls()};')
//
g.comptime_var_type_map['${node.val_var}.typ'] = styp
g.stmts(node.stmts)
i++

View File

@ -0,0 +1,126 @@
struct Abc {
x int
y int
name string
}
struct Complex {
s string
i int
ch_i chan int
atomic_i atomic int
//
pointer1_i &int = unsafe { nil }
pointer2_i &&int = unsafe { nil }
pointer3_i &&&int = unsafe { nil }
//
array_i []int
map_i map[int]int
my_struct Abc
my_struct_shared shared Abc
//
o_s ?string
o_i ?int
o_ch_i ?chan int = chan int{cap: 10}
// o_atomic_i ?atomic int // TODO: cgen error, but should be probably a checker one, since optional atomics do not make sense
o_pointer1_i ?&int = unsafe { nil }
o_pointer2_i ?&&int = unsafe { nil }
o_pointer3_i ?&&&int = unsafe { nil }
//
o_array_i ?[]int
o_map_i ?map[int]int
o_my_struct ?Abc
o_my_struct_shared ?shared Abc
}
fn test_is_shared() {
$for f in Complex.fields {
if f.name.contains('_shared') {
assert f.is_shared, 'Complex.${f.name} should have f.is_shared set'
} else {
assert !f.is_shared, 'Complex.${f.name} should NOT have f.is_shared set'
}
}
}
fn test_is_atomic() {
$for f in Complex.fields {
if f.name.contains('atomic_') {
assert f.is_atomic, 'StructWithAtomicFields.${f.name} should have f.is_atomic set'
} else {
assert !f.is_atomic, 'StructWithAtomicFields.${f.name} should NOT have f.is_atomic set'
}
}
}
fn test_is_optional() {
$for f in Complex.fields {
if f.name.starts_with('o_') {
assert f.is_optional, 'Complex.${f.name} should have f.is_optional set'
} else {
assert !f.is_optional, 'Complex.${f.name} should NOT have f.is_optional set'
}
}
}
fn test_is_array() {
$for f in Complex.fields {
if f.name.contains('array_') {
assert f.is_array, 'Complex.${f.name} should have f.is_array set'
} else {
assert !f.is_array, 'Complex.${f.name} should NOT have f.is_array set'
}
}
}
fn test_is_map() {
$for f in Complex.fields {
if f.name.contains('map_') {
assert f.is_map, 'Complex.${f.name} should have f.is_map set'
} else {
assert !f.is_map, 'Complex.${f.name} should NOT have f.is_map set'
}
}
}
fn test_is_chan() {
$for f in Complex.fields {
if f.name.contains('ch_') {
assert f.is_chan, 'Complex.${f.name} should have f.is_chan set'
} else {
assert !f.is_chan, 'Complex.${f.name} should NOT have f.is_chan set'
}
}
}
fn test_is_struct() {
$for f in Complex.fields {
if f.name.contains('_struct') {
assert f.is_struct, 'Complex.${f.name} should have f.is_struct set'
} else {
assert !f.is_struct, 'Complex.${f.name} should NOT have f.is_struct set'
}
}
}
fn test_indirections() {
$for f in Complex.fields {
if f.name.contains('pointer') || f.name in ['my_struct_shared', 'o_my_struct_shared'] {
assert f.indirections > 0, 'Complex.${f.name} should have f.indirections > 0'
} else {
assert !(f.indirections > 0), 'Complex.${f.name} should NOT have f.indirections > 0'
}
if f.name.contains('pointer1') {
assert f.indirections == 1
}
if f.name.contains('pointer2') {
assert f.indirections == 2
}
if f.name.contains('pointer3') {
assert f.indirections == 3
}
if f.name.contains('my_struct_shared') {
assert f.indirections == 1
}
}
}