Skip to content

Commit

Permalink
checker, cgen: fix @[if xyz?] fn init() {}, add tests (#20096)
Browse files Browse the repository at this point in the history
  • Loading branch information
spytheman committed Dec 5, 2023
1 parent 4b31092 commit dbdd96f
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 20 deletions.
25 changes: 14 additions & 11 deletions vlib/v/checker/fn.v
Expand Up @@ -413,20 +413,23 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
}
node.source_file = c.file

if node.name in c.table.fns && node.name != 'main.main' {
mut dep_names := []string{}
for stmt in node.stmts {
dnames := c.table.dependent_names_in_stmt(stmt)
for dname in dnames {
if dname in dep_names {
continue
if node.name in c.table.fns {
if node.name != 'main.main' {
mut dep_names := []string{}
for stmt in node.stmts {
dnames := c.table.dependent_names_in_stmt(stmt)
for dname in dnames {
if dname in dep_names {
continue
}
dep_names << dname
}
dep_names << dname
}
if dep_names.len > 0 {
c.table.fns[node.name].dep_names = dep_names
}
}
if dep_names.len > 0 {
c.table.fns[node.name].dep_names = dep_names
}
c.table.fns[node.name].source_fn = voidptr(node)
}

// vweb checks
Expand Down
27 changes: 18 additions & 9 deletions vlib/v/gen/c/cgen.v
Expand Up @@ -5869,14 +5869,14 @@ fn (mut g Gen) write_init_function() {
// ignore v.reflection already initialized above
continue
}
mut is_empty := true
mut const_section_header_shown := false
// write globals and consts init later
for var_name in g.sorted_global_const_names {
if var := g.global_const_defs[var_name] {
if var.mod == mod_name && var.init.len > 0 {
if is_empty {
is_empty = false
g.writeln('\t// Initializations for module ${mod_name}')
if !const_section_header_shown {
g.writeln('\t// Initializations of consts for module ${mod_name}')
const_section_header_shown = true
}
g.writeln(var.init)
}
Expand All @@ -5885,12 +5885,21 @@ fn (mut g Gen) write_init_function() {
init_fn_name := '${mod_name}.init'
if initfn := g.table.find_fn(init_fn_name) {
if initfn.return_type == ast.void_type && initfn.params.len == 0 {
if is_empty {
g.writeln('\t// Initializations for module ${mod_name}')
mut should_be_skipped := false
if initfn.source_fn != unsafe { nil } {
fndecl := unsafe { &ast.FnDecl(initfn.source_fn) }
if fndecl.should_be_skipped {
should_be_skipped = fndecl.should_be_skipped
}
}
if should_be_skipped {
g.writeln('\t// Skipping fn init() for module ${mod_name}')
} else {
g.writeln('\t// Calling fn init() for module ${mod_name}')
mod_c_name := util.no_dots(mod_name)
init_fn_c_name := '${mod_c_name}__init'
g.writeln('\t${init_fn_c_name}();')
}
mod_c_name := util.no_dots(mod_name)
init_fn_c_name := '${mod_c_name}__init'
g.writeln('\t${init_fn_c_name}();')
}
}
cleanup_fn_name := '${mod_name}.cleanup'
Expand Down
@@ -0,0 +1,2 @@
// Calling fn init() for module main
main__init();
2 changes: 2 additions & 0 deletions vlib/v/gen/c/testdata/init_fn_with_if_attr_defined.out
@@ -0,0 +1,2 @@
hi from init
hi from main
10 changes: 10 additions & 0 deletions vlib/v/gen/c/testdata/init_fn_with_if_attr_defined.vv
@@ -0,0 +1,10 @@
// vtest vflags: -d init_on

@[if init_on ?]
fn init() {
println('hi from init')
}

fn main() {
println('hi from main')
}
@@ -0,0 +1 @@
// Skipping fn init() for module main
1 change: 1 addition & 0 deletions vlib/v/gen/c/testdata/init_fn_with_if_attr_not_defined.out
@@ -0,0 +1 @@
hi from main
10 changes: 10 additions & 0 deletions vlib/v/gen/c/testdata/init_fn_with_if_attr_not_defined.vv
@@ -0,0 +1,10 @@
// vtest vflags: -d init_is_not_defined

@[if init_on ?]
fn init() {
println('hi from init')
}

fn main() {
println('hi from main')
}

0 comments on commit dbdd96f

Please sign in to comment.