170 lines
3.8 KiB
V
170 lines
3.8 KiB
V
module checker
|
|
|
|
import v.ast
|
|
import v.table
|
|
import v.util
|
|
import v.checker.mark_used_walker
|
|
|
|
// mark_used walks the AST, starting at main() and marks all used fns transitively
|
|
fn (mut c Checker) mark_used(ast_files []ast.File) {
|
|
util.timing_start(@METHOD)
|
|
util.timing_start('all_fn_and_const')
|
|
mut all_fns := map[string]ast.FnDecl{}
|
|
mut all_consts := map[string]ast.ConstField{}
|
|
for i in 0 .. ast_files.len {
|
|
file := unsafe { &ast_files[i] }
|
|
for node in file.stmts {
|
|
match node {
|
|
ast.FnDecl {
|
|
fkey := if node.is_method {
|
|
'${int(node.receiver.typ)}.$node.name'
|
|
} else {
|
|
node.name
|
|
}
|
|
all_fns[fkey] = node
|
|
}
|
|
ast.ConstDecl {
|
|
for cfield in node.fields {
|
|
ckey := cfield.name
|
|
all_consts[ckey] = cfield
|
|
}
|
|
}
|
|
else {}
|
|
}
|
|
}
|
|
}
|
|
util.timing_measure('all_fn_and_const')
|
|
|
|
mut all_fn_root_names := [
|
|
'main.main',
|
|
'__new_array',
|
|
'__new_array_with_default',
|
|
'new_array_from_c_array',
|
|
'memdup',
|
|
'vstrlen',
|
|
'tos',
|
|
'tos2',
|
|
'tos3',
|
|
'isnil',
|
|
/* utf8_str_visible_length is used by c/str.v */
|
|
'utf8_str_visible_length',
|
|
'builtin_init',
|
|
/* byteptr and charptr */
|
|
'3.vstring',
|
|
'3.vstring_with_len',
|
|
'4.vstring',
|
|
'4.vstring_with_len',
|
|
/* string. methods */
|
|
'18.add',
|
|
'18.trim_space',
|
|
'18.replace',
|
|
'18.clone',
|
|
'18.trim',
|
|
'18.substr',
|
|
'18.at',
|
|
'18.index_kmp',
|
|
/* string. ==, !=, etc... */
|
|
'18.eq',
|
|
'18.ne',
|
|
'18.lt',
|
|
'18.gt',
|
|
'18.le',
|
|
'18.ge',
|
|
/* ustring. ==, !=, etc... */
|
|
'19.eq',
|
|
'19.ne',
|
|
'19.lt',
|
|
'19.gt',
|
|
'19.le',
|
|
'19.ge',
|
|
'19.add',
|
|
/* other array methods */
|
|
'21.get',
|
|
'21.set',
|
|
'21.get_unsafe',
|
|
'21.set_unsafe',
|
|
'21.slice',
|
|
'21.slice2',
|
|
'59.get',
|
|
'59.set',
|
|
'65557.push',
|
|
'65557.set',
|
|
'65557.set_unsafe',
|
|
/* TODO: process the _vinit const initializations automatically too */
|
|
'os.getwd',
|
|
'os.init_os_args',
|
|
]
|
|
|
|
// implicit string builders are generated in auto_eq_methods.v
|
|
mut sb_mut_type := ''
|
|
if sbfn := c.table.find_fn('strings.new_builder') {
|
|
sb_mut_type = sbfn.return_type.set_nr_muls(1).str() + '.'
|
|
}
|
|
|
|
for k, _ in all_fns {
|
|
if k.ends_with('.init') {
|
|
all_fn_root_names << k
|
|
}
|
|
if k.ends_with('.free') {
|
|
all_fn_root_names << k
|
|
}
|
|
if c.pref.is_test && (k.starts_with('test_') || k.contains('.test_')) {
|
|
all_fn_root_names << k
|
|
}
|
|
if sb_mut_type != '' && k.starts_with(sb_mut_type) {
|
|
all_fn_root_names << k
|
|
}
|
|
}
|
|
if c.pref.is_debug {
|
|
all_fn_root_names << 'panic_debug'
|
|
}
|
|
if c.pref.is_test {
|
|
all_fn_root_names << 'main.cb_assertion_ok'
|
|
all_fn_root_names << 'main.cb_assertion_failed'
|
|
if benched_tests_sym := c.table.find_type('main.BenchedTests') {
|
|
bts_type := benched_tests_sym.methods[0].params[0].typ
|
|
all_fn_root_names << '${bts_type}.testing_step_start'
|
|
all_fn_root_names << '${bts_type}.testing_step_end'
|
|
all_fn_root_names << '${bts_type}.end_testing'
|
|
all_fn_root_names << 'main.start_testing'
|
|
}
|
|
}
|
|
|
|
mut walker := mark_used_walker.Walker{
|
|
table: c.table
|
|
files: ast_files
|
|
all_fns: all_fns
|
|
all_consts: all_consts
|
|
}
|
|
// println( all_fns.keys() )
|
|
walker.mark_root_fns(all_fn_root_names)
|
|
|
|
if walker.n_asserts > 0 {
|
|
walker.fn_decl(mut all_fns['__print_assert_failure'])
|
|
}
|
|
if walker.n_maps > 0 {
|
|
for k, mut mfn in all_fns {
|
|
if k == 'new_map_2' || k.starts_with('map_') || k.ends_with('set_1')
|
|
|| k.ends_with('exists_1') || k.ends_with('get_1') {
|
|
walker.fn_decl(mut mfn)
|
|
}
|
|
}
|
|
}
|
|
|
|
$if trace_skip_unused_fn_names ? {
|
|
for key, _ in walker.used_fns {
|
|
println('> used fn key: $key')
|
|
}
|
|
}
|
|
|
|
c.table.used_fns = walker.used_fns
|
|
c.table.used_consts = walker.used_consts
|
|
|
|
$if trace_skip_unused ? {
|
|
eprintln('>> c.table.used_fns: $c.table.used_fns.keys()')
|
|
eprintln('>> c.table.used_consts: $c.table.used_consts.keys()')
|
|
eprintln('>> walker.n_maps: $walker.n_maps')
|
|
}
|
|
util.timing_measure(@METHOD)
|
|
}
|