checker,markused: fix detection of using array_last/array_pop/array_first in user code

This commit is contained in:
Delyan Angelov 2024-11-16 13:16:13 +02:00
parent 945de7e37e
commit 6e2f2cc35c
No known key found for this signature in database
GPG key ID: 66886C0F12D595ED
3 changed files with 29 additions and 4 deletions

View file

@ -21,6 +21,9 @@ pub mut:
auto_str bool // auto str fns auto_str bool // auto str fns
auto_str_ptr bool // auto str fns for ptr type auto_str_ptr bool // auto str fns for ptr type
arr_prepend bool // arr.prepend() arr_prepend bool // arr.prepend()
arr_first bool // arr.first()
arr_last bool // arr.last()
arr_pop bool // arr.pop()
option_or_result bool // has panic call option_or_result bool // has panic call
print_types map[int]bool // print() idx types print_types map[int]bool // print() idx types
} }

View file

@ -3548,6 +3548,17 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
} }
node.return_type = ast.int_type node.return_type = ast.int_type
} else if method_name in ['first', 'last', 'pop'] { } else if method_name in ['first', 'last', 'pop'] {
if c.pref.skip_unused {
if method_name == 'first' {
c.table.used_features.arr_first = true
}
if method_name == 'last' {
c.table.used_features.arr_last = true
}
if method_name == 'pop' {
c.table.used_features.arr_pop = true
}
}
if node.args.len != 0 { if node.args.len != 0 {
c.error('`.${method_name}()` does not have any arguments', node.args[0].pos) c.error('`.${method_name}()` does not have any arguments', node.args[0].pos)
} }

View file

@ -15,9 +15,10 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
} }
mut allow_noscan := true mut allow_noscan := true
// Functions that must be generated and can't be skipped // Functions that must be generated and can't be skipped
mut all_fn_root_names := if pref_.backend == .native { mut all_fn_root_names := []string{}
if pref_.backend == .native {
// Note: this is temporary, until the native backend supports more features! // Note: this is temporary, until the native backend supports more features!
['main.main'] all_fn_root_names << 'main.main'
} else { } else {
byteptr_idx_str := '${ast.byteptr_type_idx}' byteptr_idx_str := '${ast.byteptr_type_idx}'
charptr_idx_str := '${ast.charptr_type_idx}' charptr_idx_str := '${ast.charptr_type_idx}'
@ -138,7 +139,17 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
if table.used_features.arr_prepend { if table.used_features.arr_prepend {
core_fns << ref_array_idx_str + '.prepend_many' core_fns << ref_array_idx_str + '.prepend_many'
} }
if table.used_features.arr_pop {
core_fns << ref_array_idx_str + '.pop'
}
if table.used_features.arr_first {
core_fns << array_idx_str + '.first'
}
if table.used_features.arr_last {
core_fns << array_idx_str + '.last'
}
} else { } else {
// TODO: this *should not* depend on the used compiler, which is brittle, but only on info in the AST...
// hello world apps // hello world apps
if pref_.ccompiler_type == .tinyc { if pref_.ccompiler_type == .tinyc {
// unused on tcc // unused on tcc
@ -175,7 +186,7 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
if table.used_features.anon_fn { if table.used_features.anon_fn {
core_fns << 'memdup_uncollectable' core_fns << 'memdup_uncollectable'
} }
core_fns all_fn_root_names << core_fns
} }
if pref_.is_bare { if pref_.is_bare {
@ -349,9 +360,9 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a
} }
} }
handle_vweb(mut table, mut all_fn_root_names, 'veb.Result', 'veb.filter', 'veb.Context')
handle_vweb(mut table, mut all_fn_root_names, 'vweb.Result', 'vweb.filter', 'vweb.Context') handle_vweb(mut table, mut all_fn_root_names, 'vweb.Result', 'vweb.filter', 'vweb.Context')
handle_vweb(mut table, mut all_fn_root_names, 'x.vweb.Result', 'x.vweb.filter', 'x.vweb.Context') handle_vweb(mut table, mut all_fn_root_names, 'x.vweb.Result', 'x.vweb.filter', 'x.vweb.Context')
handle_vweb(mut table, mut all_fn_root_names, 'veb.Result', 'veb.filter', 'veb.Context')
// handle ORM drivers: // handle ORM drivers:
orm_connection_implementations := table.iface_types['orm.Connection'] or { []ast.Type{} } orm_connection_implementations := table.iface_types['orm.Connection'] or { []ast.Type{} }