markused: fixing missing info tracking on walker for {...foo}, struct embeds, map[k]Struct and others (#23008)

This commit is contained in:
Felipe Pena 2024-11-30 03:42:46 -03:00 committed by GitHub
parent a66c4c9340
commit 602b097db5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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,13 +565,38 @@ 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)
}
}
}
@ -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}'
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.mark_aggregate_call_used(fn_name, types)
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