Skip to content

Commit

Permalink
comptime: implement field.is_enum (#16920)
Browse files Browse the repository at this point in the history
  • Loading branch information
Delta456 committed Jan 9, 2023
1 parent c2eb4d7 commit 413a8b5
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 2 deletions.
1 change: 1 addition & 0 deletions vlib/builtin/builtin.v
Expand Up @@ -125,6 +125,7 @@ pub:
is_array bool // `f []string` , TODO
is_map bool // `f map[string]int` , TODO
is_chan bool // `f chan int` , TODO
is_enum bool // `f Enum` where Enum is an enum
is_struct bool // `f Abc` where Abc is a struct , TODO
is_alias bool // `f MyInt` where `type MyInt = int`, TODO
//
Expand Down
3 changes: 2 additions & 1 deletion vlib/v/checker/comptime.v
Expand Up @@ -766,7 +766,7 @@ fn (mut c Checker) check_comptime_is_field_selector(node ast.SelectorExpr) bool
fn (mut c Checker) check_comptime_is_field_selector_bool(node ast.SelectorExpr) bool {
if c.check_comptime_is_field_selector(node) {
return node.field_name in ['is_mut', 'is_pub', 'is_shared', 'is_atomic', 'is_option',
'is_array', 'is_map', 'is_chan', 'is_struct', 'is_alias']
'is_array', 'is_map', 'is_chan', 'is_struct', 'is_alias', 'is_enum']
}
return false
}
Expand All @@ -787,6 +787,7 @@ fn (mut c Checker) get_comptime_selector_bool_field(field_name string) bool {
'is_chan' { return field_sym.kind == .chan }
'is_struct' { return field_sym.kind == .struct_ }
'is_alias' { return field_sym.kind == .alias }
'is_enum' { return field_sym.kind == .enum_ }
else { return false }
}
}
4 changes: 3 additions & 1 deletion vlib/v/gen/c/comptime.v
Expand Up @@ -42,6 +42,7 @@ fn (mut g Gen) get_comptime_selector_bool_field(field_name string) bool {
'is_chan' { return field_sym.kind == .chan }
'is_struct' { return field_sym.kind == .struct_ }
'is_alias' { return field_sym.kind == .alias }
'is_enum' { return field_sym.kind == .enum_ }
else { return false }
}
}
Expand Down Expand Up @@ -571,7 +572,7 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) (bool, bool) {
}
ast.SelectorExpr {
if g.inside_comptime_for_field && cond.expr is ast.Ident
&& (cond.expr as ast.Ident).name == g.comptime_for_field_var && cond.field_name in ['is_mut', 'is_pub', 'is_shared', 'is_atomic', 'is_option', 'is_array', 'is_map', 'is_chan', 'is_struct', 'is_alias'] {
&& (cond.expr as ast.Ident).name == g.comptime_for_field_var && cond.field_name in ['is_mut', 'is_pub', 'is_shared', 'is_atomic', 'is_option', 'is_array', 'is_map', 'is_chan', 'is_struct', 'is_alias', 'is_enum'] {
ret_bool := g.get_comptime_selector_bool_field(cond.field_name)
g.write(ret_bool.str())
return ret_bool, true
Expand Down Expand Up @@ -744,6 +745,7 @@ fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
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}.is_alias = ${field_sym.kind == .alias};')
g.writeln('\t${node.val_var}.is_enum = ${field_sym.kind == .enum_};')
//
g.writeln('\t${node.val_var}.indirections = ${field.typ.nr_muls()};')
//
Expand Down
17 changes: 17 additions & 0 deletions vlib/v/tests/comptime_for_in_fields_FieldData_test.v
Expand Up @@ -6,6 +6,12 @@ struct Abc {
name string
}

enum JobTitle {
manager
executive
worker
}

struct Complex {
s string
i int
Expand Down Expand Up @@ -35,6 +41,7 @@ struct Complex {
o_map_i ?map[int]int
o_my_struct ?Abc
o_my_struct_shared ?shared Abc
jobtitle_enum JobTitle
}

fn test_is_shared() {
Expand Down Expand Up @@ -117,6 +124,16 @@ fn test_is_alias() {
}
}

fn test_is_enum() {
$for f in Complex.fields {
if f.name.contains('_enum') {
assert f.is_enum, 'Complex.${f.name} should have f.is_enum set'
} else {
assert !f.is_enum, 'Complex.${f.name} should NOT have f.is_enum set'
}
}
}

fn test_indirections() {
$for f in Complex.fields {
if f.name.contains('pointer') || f.name in ['my_struct_shared', 'o_my_struct_shared'] {
Expand Down

0 comments on commit 413a8b5

Please sign in to comment.