1
0
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:
ChAoS_UnItY 2023-03-07 14:52:40 +08:00 committed by GitHub
parent d7a418fbb5
commit 6e670ec908
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 7 deletions

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
name
age

View File

@ -0,0 +1,10 @@
interface User {
name string
age int
}
fn main() {
$for field in User.fields {
println(field.name)
}
}