Skip to content

Commit

Permalink
markused: fixing missing info tracking on walker for {...foo}, stru…
Browse files Browse the repository at this point in the history
…ct embeds, `map[k]Struct` and others (vlang#23008)
  • Loading branch information
felipensp authored Nov 30, 2024
1 parent a66c4c9 commit 602b097
Showing 1 changed file with 58 additions and 23 deletions.
81 changes: 58 additions & 23 deletions vlib/v/markused/walker.v
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 602b097

Please sign in to comment.