Skip to content

Commit 6e670ec

Browse files
authored
v: support interface field compile time reflection (#17503)
1 parent d7a418f commit 6e670ec

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

vlib/v/checker/comptime.v

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,23 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
180180
c.error('unknown type `${sym.name}`', node.typ_pos)
181181
}
182182
if node.kind == .fields {
183-
if sym.kind == .struct_ {
184-
sym_info := sym.info as ast.Struct
183+
if sym.kind in [.struct_, .interface_] {
184+
mut fields := []ast.StructField{}
185+
match sym.info {
186+
ast.Struct {
187+
fields = sym.info.fields.clone()
188+
}
189+
ast.Interface {
190+
fields = sym.info.fields.clone()
191+
}
192+
else {
193+
c.error('comptime field lookup supports only structs and interfaces currently, and ${sym.name} is neither',
194+
node.typ_pos)
195+
return
196+
}
197+
}
185198
c.inside_comptime_for_field = true
186-
for field in sym_info.fields {
199+
for field in fields {
187200
c.comptime_for_field_value = field
188201
c.comptime_for_field_var = node.val_var
189202
c.comptime_fields_type[node.val_var] = node.typ

vlib/v/gen/c/comptime.v

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -763,12 +763,24 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
763763
}
764764
} else if node.kind == .fields {
765765
// TODO add fields
766-
if sym.kind == .struct_ {
767-
sym_info := sym.info as ast.Struct
768-
if sym_info.fields.len > 0 {
766+
if sym.kind in [.struct_, .interface_] {
767+
fields := match sym.info {
768+
ast.Struct {
769+
sym.info.fields
770+
}
771+
ast.Interface {
772+
sym.info.fields
773+
}
774+
else {
775+
g.error('comptime field lookup is supported only for structs and interfaces, and ${sym.name} is neither',
776+
node.pos)
777+
[]ast.StructField{len: 0}
778+
}
779+
}
780+
if fields.len > 0 {
769781
g.writeln('\tFieldData ${node.val_var} = {0};')
770782
}
771-
for field in sym_info.fields {
783+
for field in fields {
772784
g.push_existing_comptime_values()
773785
g.inside_comptime_for_field = true
774786
g.comptime_for_field_var = node.val_var
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
name
2+
age
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
interface User {
2+
name string
3+
age int
4+
}
5+
6+
fn main() {
7+
$for field in User.fields {
8+
println(field.name)
9+
}
10+
}

0 commit comments

Comments
 (0)