mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
v: support interface field compile time reflection (#17503)
This commit is contained in:
parent
d7a418fbb5
commit
6e670ec908
@ -180,10 +180,23 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
|
|||||||
c.error('unknown type `${sym.name}`', node.typ_pos)
|
c.error('unknown type `${sym.name}`', node.typ_pos)
|
||||||
}
|
}
|
||||||
if node.kind == .fields {
|
if node.kind == .fields {
|
||||||
if sym.kind == .struct_ {
|
if sym.kind in [.struct_, .interface_] {
|
||||||
sym_info := sym.info as ast.Struct
|
mut fields := []ast.StructField{}
|
||||||
|
match sym.info {
|
||||||
|
ast.Struct {
|
||||||
|
fields = sym.info.fields.clone()
|
||||||
|
}
|
||||||
|
ast.Interface {
|
||||||
|
fields = sym.info.fields.clone()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c.error('comptime field lookup supports only structs and interfaces currently, and ${sym.name} is neither',
|
||||||
|
node.typ_pos)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
c.inside_comptime_for_field = true
|
c.inside_comptime_for_field = true
|
||||||
for field in sym_info.fields {
|
for field in fields {
|
||||||
c.comptime_for_field_value = field
|
c.comptime_for_field_value = field
|
||||||
c.comptime_for_field_var = node.val_var
|
c.comptime_for_field_var = node.val_var
|
||||||
c.comptime_fields_type[node.val_var] = node.typ
|
c.comptime_fields_type[node.val_var] = node.typ
|
||||||
|
@ -763,12 +763,24 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
|
|||||||
}
|
}
|
||||||
} else if node.kind == .fields {
|
} else if node.kind == .fields {
|
||||||
// TODO add fields
|
// TODO add fields
|
||||||
if sym.kind == .struct_ {
|
if sym.kind in [.struct_, .interface_] {
|
||||||
sym_info := sym.info as ast.Struct
|
fields := match sym.info {
|
||||||
if sym_info.fields.len > 0 {
|
ast.Struct {
|
||||||
|
sym.info.fields
|
||||||
|
}
|
||||||
|
ast.Interface {
|
||||||
|
sym.info.fields
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
g.error('comptime field lookup is supported only for structs and interfaces, and ${sym.name} is neither',
|
||||||
|
node.pos)
|
||||||
|
[]ast.StructField{len: 0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fields.len > 0 {
|
||||||
g.writeln('\tFieldData ${node.val_var} = {0};')
|
g.writeln('\tFieldData ${node.val_var} = {0};')
|
||||||
}
|
}
|
||||||
for field in sym_info.fields {
|
for field in fields {
|
||||||
g.push_existing_comptime_values()
|
g.push_existing_comptime_values()
|
||||||
g.inside_comptime_for_field = true
|
g.inside_comptime_for_field = true
|
||||||
g.comptime_for_field_var = node.val_var
|
g.comptime_for_field_var = node.val_var
|
||||||
|
2
vlib/v/gen/c/testdata/comptime_interface_field.out
vendored
Normal file
2
vlib/v/gen/c/testdata/comptime_interface_field.out
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
name
|
||||||
|
age
|
10
vlib/v/gen/c/testdata/comptime_interface_field.vv
vendored
Normal file
10
vlib/v/gen/c/testdata/comptime_interface_field.vv
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
interface User {
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
$for field in User.fields {
|
||||||
|
println(field.name)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user