diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 32a98c25e55529..d7d38fd355173c 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -80,6 +80,12 @@ pub fn (mut w Walker) mark_global_as_used(ckey string) { w.used_globals[ckey] = true gfield := w.all_globals[ckey] or { return } w.expr(gfield.expr) + if !gfield.has_expr && gfield.typ != 0 { + sym := w.table.sym(gfield.typ) + if sym.info is ast.Struct { + w.a_struct_info(sym.name, sym.info) + } + } } pub fn (mut w Walker) mark_root_fns(all_fn_root_names []string) { @@ -434,6 +440,9 @@ fn (mut w Walker) expr(node_ ast.Expr) { ast.MapInit { w.exprs(node.keys) w.exprs(node.vals) + if node.has_update_expr { + w.expr(node.update_expr) + } w.features.used_maps++ } ast.MatchExpr { @@ -489,9 +498,8 @@ fn (mut w Walker) expr(node_ ast.Expr) { return } sym := w.table.sym(node.typ) - if sym.kind == .struct { - info := sym.info as ast.Struct - w.a_struct_info(sym.name, info) + if sym.info is ast.Struct { + w.a_struct_info(sym.name, sym.info) } if node.has_update_expr { w.expr(node.update_expr) @@ -557,15 +565,40 @@ pub fn (mut w Walker) a_struct_info(sname string, info ast.Struct) { } if ifield.typ != 0 { fsym := w.table.sym(ifield.typ) - if fsym.kind == .map { - w.features.used_maps++ - } else if fsym.kind == .array { - w.features.used_arrays++ - } else if fsym.kind == .struct { - w.a_struct_info(fsym.name, fsym.struct_info()) + match fsym.info { + ast.Struct { + w.a_struct_info(fsym.name, fsym.info) + } + ast.Alias { + value_sym := w.table.final_sym(ifield.typ) + if value_sym.info is ast.Struct { + w.a_struct_info(value_sym.name, value_sym.info) + } + } + ast.Array, ast.ArrayFixed { + w.features.used_arrays++ + value_sym := w.table.final_sym(w.table.value_type(ifield.typ)) + if value_sym.info is ast.Struct { + w.a_struct_info(value_sym.name, value_sym.info) + } + } + ast.Map { + w.features.used_maps++ + value_sym := w.table.final_sym(w.table.value_type(ifield.typ)) + if value_sym.info is ast.Struct { + w.a_struct_info(value_sym.name, value_sym.info) + } + } + else {} } } } + for embed in info.embeds { + sym := w.table.final_sym(embed) + if sym.info is ast.Struct { + w.a_struct_info(sym.name, sym.info) + } + } } pub fn (mut w Walker) fn_decl(mut node ast.FnDecl) { @@ -595,10 +628,13 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { if node.is_method && node.left_type != 0 { left_sym := w.table.sym(node.left_type) if left_sym.info is ast.Aggregate { - for types in left_sym.info.types { - fn_name := '${types.idx()}.${node.name}' - if !w.used_fns[fn_name] { - w.mark_aggregate_call_used(fn_name, types) + for receiver_type in left_sym.info.types { + receiver_sym := w.table.sym(receiver_type) + if m := receiver_sym.find_method(node.name) { + fn_name := '${int(m.receiver_type)}.${node.name}' + if !w.used_fns[fn_name] { + w.fn_by_name(fn_name) + } } } } else if left_sym.info is ast.Interface { @@ -612,6 +648,13 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { w.fn_by_name(fn_embed) } } + } else if node.from_embed_types.len != 0 && !node.left_type.has_flag(.generic) { + _, embed_types := w.table.find_method_from_embeds(w.table.final_sym(node.left_type), + node.name) or { ast.Fn{}, []ast.Type{} } + if embed_types.len != 0 { + fn_embed := '${int(embed_types.last())}.${node.name}' + w.fn_by_name(fn_embed) + } } } w.expr(node.left) @@ -639,6 +682,8 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { if const_fn_name in w.all_consts { w.mark_const_as_used(const_fn_name) } + } else if node.is_fn_var { + w.mark_global_as_used(node.name) } w.mark_fn_as_used(fn_name) if node.is_method && node.receiver_type.has_flag(.generic) && node.receiver_concrete_type != 0 @@ -656,16 +701,6 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) { } } -// visit aggregate type method declaration -pub fn (mut w Walker) mark_aggregate_call_used(fn_name string, left_type ast.Type) { - if w.used_fns[fn_name] { - return - } - w.mark_fn_as_used(fn_name) - stmt := w.all_fns[fn_name] or { return } - w.stmts(stmt.stmts) -} - pub fn (mut w Walker) fn_by_name(fn_name string) { if w.used_fns[fn_name] { return