mirror of
https://github.com/vlang/v.git
synced 2025-09-08 23:07:19 -04:00
checker: cleanup used_features logic (#23502)
This commit is contained in:
parent
496451ecbb
commit
1b9f15d60d
@ -10,7 +10,6 @@ import v.util
|
||||
@[heap; minify]
|
||||
pub struct UsedFeatures {
|
||||
pub mut:
|
||||
interfaces bool // interface
|
||||
dump bool // dump()
|
||||
index bool // string[0]
|
||||
range_index bool // string[0..1]
|
||||
|
@ -1392,9 +1392,8 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast.
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return_type ast.Type, expr ast.Expr) {
|
||||
if c.pref.skip_unused && !c.is_builtin_mod && node.kind != .absent && c.mod != 'strings' {
|
||||
c.table.used_features.option_or_result = true
|
||||
}
|
||||
c.markused_option_or_result(!c.is_builtin_mod && node.kind != .absent && c.mod != 'strings')
|
||||
|
||||
if node.kind == .propagate_option {
|
||||
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.option)
|
||||
&& !c.table.cur_fn.is_main && !c.table.cur_fn.is_test && !c.inside_const {
|
||||
@ -1794,16 +1793,12 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||
c.check_or_expr(node.or_block, unwrapped_typ, c.expected_or_type, node)
|
||||
c.expected_or_type = ast.void_type
|
||||
}
|
||||
if c.pref.skip_unused && node.or_block.kind != .absent
|
||||
&& !c.table.used_features.option_or_result {
|
||||
c.table.used_features.option_or_result = true
|
||||
}
|
||||
c.markused_option_or_result(node.or_block.kind != .absent
|
||||
&& !c.table.used_features.option_or_result)
|
||||
return field.typ
|
||||
}
|
||||
if mut method := c.table.sym(c.unwrap_generic(typ)).find_method_with_generic_parent(field_name) {
|
||||
if c.pref.skip_unused && typ.has_flag(.generic) {
|
||||
c.table.used_features.comptime_calls['${int(method.params[0].typ)}.${field_name}'] = true
|
||||
}
|
||||
c.markused_comptime_call(typ.has_flag(.generic), '${int(method.params[0].typ)}.${field_name}')
|
||||
if c.expected_type != 0 && c.expected_type != ast.none_type {
|
||||
fn_type := ast.new_type(c.table.find_or_register_fn_type(method, false, true))
|
||||
// if the expected type includes the receiver, don't hide it behind a closure
|
||||
@ -2383,15 +2378,7 @@ fn (mut c Checker) assert_stmt(mut node ast.AssertStmt) {
|
||||
cur_exp_typ := c.expected_type
|
||||
c.expected_type = ast.bool_type
|
||||
assert_type := c.check_expr_option_or_result_call(node.expr, c.expr(mut node.expr))
|
||||
if c.pref.skip_unused && !c.table.used_features.auto_str && !c.is_builtin_mod
|
||||
&& mut node.expr is ast.InfixExpr {
|
||||
if !c.table.sym(c.unwrap_generic(node.expr.left_type)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
}
|
||||
if !c.table.sym(c.unwrap_generic(node.expr.right_type)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
}
|
||||
}
|
||||
c.markused_assertstmt_auto_str(mut node)
|
||||
if assert_type != ast.bool_type_idx {
|
||||
atype_name := c.table.sym(assert_type).name
|
||||
c.error('assert can be used only with `bool` expressions, but found `${atype_name}` instead',
|
||||
@ -3051,17 +3038,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
|
||||
c.table.used_features.dump = true
|
||||
c.expected_type = ast.string_type
|
||||
node.expr_type = c.expr(mut node.expr)
|
||||
if c.pref.skip_unused && !c.is_builtin_mod {
|
||||
if !c.table.sym(c.unwrap_generic(node.expr_type)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
if node.expr_type.is_ptr() {
|
||||
c.table.used_features.auto_str_ptr = true
|
||||
}
|
||||
} else {
|
||||
c.table.used_features.print_types[node.expr_type.idx()] = true
|
||||
}
|
||||
c.table.used_features.print_types[ast.int_type_idx] = true
|
||||
}
|
||||
c.markused_dumpexpr(mut node)
|
||||
if c.comptime.inside_comptime_for && mut node.expr is ast.Ident {
|
||||
if node.expr.ct_expr {
|
||||
node.expr_type = c.type_resolver.get_type(node.expr as ast.Ident)
|
||||
@ -3284,10 +3261,7 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {
|
||||
ast.StructInit {
|
||||
if node.unresolved {
|
||||
mut expr_ := c.table.resolve_init(node, c.unwrap_generic(node.typ))
|
||||
if c.pref.skip_unused && c.table.used_features.used_maps == 0
|
||||
&& expr_ is ast.MapInit {
|
||||
c.table.used_features.used_maps++
|
||||
}
|
||||
c.markused_used_maps(c.table.used_features.used_maps == 0 && expr_ is ast.MapInit)
|
||||
return c.expr(mut expr_)
|
||||
}
|
||||
mut inited_fields := []string{}
|
||||
@ -3374,16 +3348,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
|
||||
to_type
|
||||
}
|
||||
final_to_is_ptr := to_type.is_ptr() || final_to_type.is_ptr()
|
||||
if c.pref.skip_unused && !c.is_builtin_mod {
|
||||
if c.table.used_features.used_maps == 0 && mut final_to_sym.info is ast.SumType {
|
||||
if final_to_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
|
||||
c.table.used_features.used_maps++
|
||||
}
|
||||
}
|
||||
if c.mod !in ['strings', 'math.bits'] && to_type.is_ptr() {
|
||||
c.table.used_features.cast_ptr = true
|
||||
}
|
||||
}
|
||||
c.markused_castexpr(mut node, to_type, mut final_to_sym)
|
||||
if to_type.has_flag(.result) {
|
||||
c.error('casting to Result type is forbidden', node.pos)
|
||||
}
|
||||
@ -4003,9 +3968,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
||||
c.error('`mut` is not allowed with `=` (use `:=` to declare a variable)',
|
||||
node.pos)
|
||||
}
|
||||
if c.pref.skip_unused && !c.is_builtin_mod && node.language == .v && node.name.contains('.') {
|
||||
c.table.used_features.external_types = true
|
||||
}
|
||||
c.markused_external_type(!c.is_builtin_mod && node.language == .v && node.name.contains('.'))
|
||||
if mut obj := node.scope.find(node.name) {
|
||||
match mut obj {
|
||||
ast.GlobalField {
|
||||
|
@ -133,32 +133,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||
// check each arg expression
|
||||
node.args[i].typ = c.expr(mut arg.expr)
|
||||
}
|
||||
if c.pref.skip_unused {
|
||||
c.table.used_features.comptime_calls['${int(c.unwrap_generic(c.comptime.comptime_for_method.receiver_type))}.${c.comptime.comptime_for_method.name}'] = true
|
||||
if c.inside_anon_fn {
|
||||
// $method passed to anon fn, mark all methods as used
|
||||
sym := c.table.sym(c.unwrap_generic(node.left_type))
|
||||
for m in sym.get_methods() {
|
||||
c.table.used_features.comptime_calls['${int(c.unwrap_generic(m.receiver_type))}.${m.name}'] = true
|
||||
if node.args.len > 0 && m.params.len > 0 {
|
||||
last_param := m.params.last().typ
|
||||
if (last_param.is_int() || last_param.is_bool())
|
||||
&& c.table.final_sym(node.args.last().typ).kind == .array {
|
||||
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m := c.comptime.comptime_for_method
|
||||
if node.args.len > 0 && m.params.len > 0 {
|
||||
last_param := m.params.last().typ
|
||||
if (last_param.is_int() || last_param.is_bool())
|
||||
&& c.table.final_sym(node.args.last().typ).kind == .array {
|
||||
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c.markused_comptimecall(mut node)
|
||||
c.stmts_ending_with_expression(mut node.or_block.stmts, c.expected_or_type)
|
||||
return c.type_resolver.get_type(node)
|
||||
}
|
||||
@ -223,9 +198,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||
c.error('could not find method `${method_name}`', node.method_pos)
|
||||
return ast.void_type
|
||||
}
|
||||
if c.pref.skip_unused {
|
||||
c.table.used_features.comptime_calls['${int(left_type)}.${method_name}'] = true
|
||||
}
|
||||
c.markused_comptime_call(true, '${int(left_type)}.${method_name}')
|
||||
node.result_type = f.return_type
|
||||
return f.return_type
|
||||
}
|
||||
@ -312,19 +285,7 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
|
||||
unwrapped_expr_type := c.unwrap_generic(field.typ)
|
||||
tsym := c.table.sym(unwrapped_expr_type)
|
||||
c.table.dumps[int(unwrapped_expr_type.clear_flags(.option, .result, .atomic_f))] = tsym.cname
|
||||
if c.pref.skip_unused {
|
||||
c.table.used_features.dump = true
|
||||
if c.table.used_features.used_maps == 0 {
|
||||
final_sym := c.table.final_sym(unwrapped_expr_type)
|
||||
if final_sym.info is ast.Map {
|
||||
c.table.used_features.used_maps++
|
||||
} else if final_sym.info is ast.SumType {
|
||||
if final_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
|
||||
c.table.used_features.used_maps++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
c.markused_comptimefor(mut node, unwrapped_expr_type)
|
||||
if tsym.kind == .array_fixed {
|
||||
info := tsym.info as ast.ArrayFixed
|
||||
if !info.is_fn_ret {
|
||||
|
@ -65,9 +65,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
|
||||
}
|
||||
}
|
||||
ast.Map {
|
||||
if c.pref.skip_unused && !c.is_builtin_mod {
|
||||
c.table.used_features.arr_map = true
|
||||
}
|
||||
c.markused_array_method(!c.is_builtin_mod, 'map')
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
@ -756,22 +756,10 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
|
||||
c.check_or_expr(node.or_block, typ, c.expected_or_type, node)
|
||||
c.inside_or_block_value = old_inside_or_block_value
|
||||
} else if node.or_block.kind == .propagate_option || node.or_block.kind == .propagate_result {
|
||||
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'strings' {
|
||||
c.table.used_features.option_or_result = true
|
||||
}
|
||||
c.markused_option_or_result(!c.is_builtin_mod && c.mod != 'strings')
|
||||
}
|
||||
c.expected_or_type = old_expected_or_type
|
||||
if c.pref.skip_unused && !c.is_builtin_mod && c.mod == 'main'
|
||||
&& !c.table.used_features.external_types {
|
||||
if node.is_method {
|
||||
if c.table.sym(node.left_type).is_builtin() {
|
||||
c.table.used_features.external_types = true
|
||||
}
|
||||
} else if node.name.contains('.') {
|
||||
c.table.used_features.external_types = true
|
||||
}
|
||||
}
|
||||
|
||||
c.markused_call_expr(mut node)
|
||||
if !c.inside_const && c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_main
|
||||
&& !c.table.cur_fn.is_test {
|
||||
// TODO: use just `if node.or_block.kind == .propagate_result && !c.table.cur_fn.return_type.has_flag(.result) {` after the deprecation for ?!Type
|
||||
@ -1422,20 +1410,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
|
||||
if node.args.len > 0 && fn_name in print_everything_fns {
|
||||
node.args[0].ct_expr = c.comptime.is_comptime(node.args[0].expr)
|
||||
c.builtin_args(mut node, fn_name, func)
|
||||
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'math.bits'
|
||||
&& node.args[0].expr !is ast.StringLiteral {
|
||||
if !c.table.sym(c.unwrap_generic(node.args[0].typ)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
} else {
|
||||
if node.args[0].typ.has_option_or_result() {
|
||||
c.table.used_features.option_or_result = true
|
||||
}
|
||||
c.table.used_features.print_types[node.args[0].typ.idx()] = true
|
||||
}
|
||||
if node.args[0].typ.is_ptr() {
|
||||
c.table.used_features.auto_str_ptr = true
|
||||
}
|
||||
}
|
||||
c.markused_fn_call(mut node)
|
||||
return func.return_type
|
||||
}
|
||||
// `return error(err)` -> `return err`
|
||||
@ -1980,15 +1955,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
continue_check = false
|
||||
return ast.void_type
|
||||
}
|
||||
if c.pref.skip_unused {
|
||||
if !left_type.has_flag(.generic) && mut left_expr is ast.Ident {
|
||||
if left_expr.obj is ast.Var && left_expr.obj.ct_type_var == .smartcast {
|
||||
c.table.used_features.comptime_calls['${int(left_type)}.${node.name}'] = true
|
||||
}
|
||||
} else if left_type.has_flag(.generic) {
|
||||
c.table.used_features.comptime_calls['${int(c.unwrap_generic(left_type))}.${node.name}'] = true
|
||||
}
|
||||
}
|
||||
c.markused_method_call(mut node, mut left_expr, left_type)
|
||||
c.expected_type = left_type
|
||||
mut is_generic := left_type.has_flag(.generic)
|
||||
node.left_type = left_type
|
||||
@ -2119,9 +2086,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||
if embed_types.len != 0 {
|
||||
is_method_from_embed = true
|
||||
node.from_embed_types = embed_types
|
||||
if c.pref.skip_unused && node.left_type.has_flag(.generic) {
|
||||
c.table.used_features.comptime_calls['${int(method.receiver_type)}.${method.name}'] = true
|
||||
}
|
||||
c.markused_comptime_call(node.left_type.has_flag(.generic), '${int(method.receiver_type)}.${method.name}')
|
||||
}
|
||||
}
|
||||
if final_left_sym.kind == .aggregate {
|
||||
@ -2816,9 +2781,7 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) !
|
||||
}
|
||||
if f.is_variadic {
|
||||
min_required_params--
|
||||
if c.pref.skip_unused && !c.is_builtin_mod {
|
||||
c.table.used_features.arr_init = true
|
||||
}
|
||||
c.markused_array_method(!c.is_builtin_mod, '')
|
||||
} else {
|
||||
has_decompose := node.args.any(it.expr is ast.ArrayDecompose)
|
||||
if has_decompose {
|
||||
@ -3437,17 +3400,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
||||
}
|
||||
node.return_type = ast.int_type
|
||||
} else if method_name in ['first', 'last', 'pop'] {
|
||||
if c.pref.skip_unused && !c.is_builtin_mod {
|
||||
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
|
||||
}
|
||||
}
|
||||
c.markused_array_method(!c.is_builtin_mod, method_name)
|
||||
if node.args.len != 0 {
|
||||
c.error('`.${method_name}()` does not have any arguments', arg0.pos)
|
||||
}
|
||||
@ -3459,9 +3412,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
|
||||
node.receiver_type = node.left_type
|
||||
}
|
||||
} else if method_name == 'delete' {
|
||||
if c.pref.skip_unused && !c.is_builtin_mod {
|
||||
c.table.used_features.arr_delete = true
|
||||
}
|
||||
c.markused_array_method(!c.is_builtin_mod, method_name)
|
||||
c.check_for_mut_receiver(mut node.left)
|
||||
unwrapped_left_sym := c.table.sym(unwrapped_left_type)
|
||||
if method := c.table.find_method(unwrapped_left_sym, method_name) {
|
||||
|
@ -57,10 +57,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
}
|
||||
// `arr << if n > 0 { 10 } else { 11 }` set the right c.expected_type
|
||||
if node.op == .left_shift && c.table.sym(left_type).kind == .array {
|
||||
if c.pref.skip_unused && !c.is_builtin_mod && c.mod != 'strings' {
|
||||
c.table.used_features.index = true
|
||||
c.table.used_features.arr_init = true
|
||||
}
|
||||
c.markused_infiexpr(!c.is_builtin_mod && c.mod != 'strings')
|
||||
if mut node.right is ast.IfExpr {
|
||||
if node.right.is_expr && node.right.branches.len > 0 {
|
||||
mut last_stmt := node.right.branches[0].stmts.last()
|
||||
|
@ -12,9 +12,6 @@ fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||
is_js := node.language == .js
|
||||
if mut decl_sym.info is ast.Interface {
|
||||
mut has_generic_types := false
|
||||
if c.pref.skip_unused && decl_sym.mod == 'main' {
|
||||
c.table.used_features.interfaces = true
|
||||
}
|
||||
if node.embeds.len > 0 {
|
||||
all_embeds := c.expand_iface_embeds(node, 0, node.embeds)
|
||||
// eprintln('> node.name: $node.name | node.embeds.len: $node.embeds.len | all_embeds: $all_embeds.len')
|
||||
|
@ -53,17 +53,7 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
|
||||
c.error('expression returning type `char` cannot be used in string interpolation directly, print its address or cast it to an integer instead',
|
||||
expr.pos())
|
||||
}
|
||||
if c.pref.skip_unused && !c.is_builtin_mod {
|
||||
if !c.table.sym(ftyp).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
} else {
|
||||
c.table.used_features.print_types[ftyp.idx()] = true
|
||||
}
|
||||
if ftyp.is_ptr() {
|
||||
c.table.used_features.auto_str_ptr = true
|
||||
}
|
||||
c.table.used_features.interpolation = true
|
||||
}
|
||||
c.markused_string_inter_lit(mut node, ftyp)
|
||||
c.fail_if_unreadable(expr, ftyp, 'interpolation object')
|
||||
node.expr_types << ftyp
|
||||
ftyp_sym := c.table.sym(ftyp)
|
||||
|
199
vlib/v/checker/used_features.v
Normal file
199
vlib/v/checker/used_features.v
Normal file
@ -0,0 +1,199 @@
|
||||
module checker
|
||||
|
||||
import v.ast
|
||||
|
||||
@[inline]
|
||||
fn (mut c Checker) markused_option_or_result(check bool) {
|
||||
if check {
|
||||
c.table.used_features.option_or_result = true
|
||||
}
|
||||
}
|
||||
|
||||
@[inline]
|
||||
fn (mut c Checker) markused_comptime_call(check bool, key string) {
|
||||
if check {
|
||||
c.table.used_features.comptime_calls[key] = true
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_assertstmt_auto_str(mut node ast.AssertStmt) {
|
||||
if !c.table.used_features.auto_str && !c.is_builtin_mod && mut node.expr is ast.InfixExpr {
|
||||
if !c.table.sym(c.unwrap_generic(node.expr.left_type)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
return
|
||||
}
|
||||
if !c.table.sym(c.unwrap_generic(node.expr.right_type)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_dumpexpr(mut node ast.DumpExpr) {
|
||||
if c.is_builtin_mod {
|
||||
return
|
||||
}
|
||||
if !c.table.sym(c.unwrap_generic(node.expr_type)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
if node.expr_type.is_ptr() {
|
||||
c.table.used_features.auto_str_ptr = true
|
||||
}
|
||||
} else {
|
||||
c.table.used_features.print_types[node.expr_type.idx()] = true
|
||||
}
|
||||
c.table.used_features.print_types[ast.int_type_idx] = true
|
||||
}
|
||||
|
||||
@[inline]
|
||||
fn (mut c Checker) markused_used_maps(check bool) {
|
||||
if check {
|
||||
c.table.used_features.used_maps++
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_castexpr(mut node ast.CastExpr, to_type ast.Type, mut final_to_sym ast.TypeSymbol) {
|
||||
if c.is_builtin_mod {
|
||||
return
|
||||
}
|
||||
if c.table.used_features.used_maps == 0 && mut final_to_sym.info is ast.SumType {
|
||||
if final_to_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
|
||||
c.table.used_features.used_maps++
|
||||
}
|
||||
}
|
||||
if c.mod !in ['strings', 'math.bits'] && to_type.is_ptr() {
|
||||
c.table.used_features.cast_ptr = true
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_external_type(check bool) {
|
||||
if check {
|
||||
c.table.used_features.external_types = true
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_comptimecall(mut node ast.ComptimeCall) {
|
||||
c.markused_comptime_call(true, '${int(c.unwrap_generic(c.comptime.comptime_for_method.receiver_type))}.${c.comptime.comptime_for_method.name}')
|
||||
if c.inside_anon_fn {
|
||||
// $method passed to anon fn, mark all methods as used
|
||||
sym := c.table.sym(c.unwrap_generic(node.left_type))
|
||||
for m in sym.get_methods() {
|
||||
c.table.used_features.comptime_calls['${int(c.unwrap_generic(m.receiver_type))}.${m.name}'] = true
|
||||
if node.args.len > 0 && m.params.len > 0 {
|
||||
last_param := m.params.last().typ
|
||||
if (last_param.is_int() || last_param.is_bool())
|
||||
&& c.table.final_sym(node.args.last().typ).kind == .array {
|
||||
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m := c.comptime.comptime_for_method
|
||||
if node.args.len > 0 && m.params.len > 0 {
|
||||
last_param := m.params.last().typ
|
||||
if (last_param.is_int() || last_param.is_bool())
|
||||
&& c.table.final_sym(node.args.last().typ).kind == .array {
|
||||
c.table.used_features.comptime_calls['${ast.string_type_idx}.${c.table.type_to_str(m.params.last().typ)}'] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_comptimefor(mut node ast.ComptimeFor, unwrapped_expr_type ast.Type) {
|
||||
c.table.used_features.dump = true
|
||||
if c.table.used_features.used_maps == 0 {
|
||||
final_sym := c.table.final_sym(unwrapped_expr_type)
|
||||
if final_sym.info is ast.Map {
|
||||
c.table.used_features.used_maps++
|
||||
} else if final_sym.info is ast.SumType {
|
||||
if final_sym.info.variants.any(c.table.final_sym(it).kind == .map) {
|
||||
c.table.used_features.used_maps++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_call_expr(mut node ast.CallExpr) {
|
||||
if !c.is_builtin_mod && c.mod == 'main' && !c.table.used_features.external_types {
|
||||
if node.is_method {
|
||||
if c.table.sym(node.left_type).is_builtin() {
|
||||
c.table.used_features.external_types = true
|
||||
}
|
||||
} else if node.name.contains('.') {
|
||||
c.table.used_features.external_types = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_fn_call(mut node ast.CallExpr) {
|
||||
if !c.is_builtin_mod && c.mod != 'math.bits' && node.args[0].expr !is ast.StringLiteral {
|
||||
if !c.table.sym(c.unwrap_generic(node.args[0].typ)).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
} else {
|
||||
if node.args[0].typ.has_option_or_result() {
|
||||
c.table.used_features.option_or_result = true
|
||||
}
|
||||
c.table.used_features.print_types[node.args[0].typ.idx()] = true
|
||||
}
|
||||
if node.args[0].typ.is_ptr() {
|
||||
c.table.used_features.auto_str_ptr = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_method_call(mut node ast.CallExpr, mut left_expr ast.Expr, left_type ast.Type) {
|
||||
if !left_type.has_flag(.generic) && mut left_expr is ast.Ident {
|
||||
if left_expr.obj is ast.Var && left_expr.obj.ct_type_var == .smartcast {
|
||||
c.table.used_features.comptime_calls['${int(left_type)}.${node.name}'] = true
|
||||
}
|
||||
} else if left_type.has_flag(.generic) {
|
||||
c.table.used_features.comptime_calls['${int(c.unwrap_generic(left_type))}.${node.name}'] = true
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_string_inter_lit(mut node ast.StringInterLiteral, ftyp ast.Type) {
|
||||
if c.is_builtin_mod {
|
||||
return
|
||||
}
|
||||
if !c.table.sym(ftyp).has_method('str') {
|
||||
c.table.used_features.auto_str = true
|
||||
} else {
|
||||
c.table.used_features.print_types[ftyp.idx()] = true
|
||||
}
|
||||
if ftyp.is_ptr() {
|
||||
c.table.used_features.auto_str_ptr = true
|
||||
}
|
||||
c.table.used_features.interpolation = true
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_infiexpr(check bool) {
|
||||
if check {
|
||||
c.table.used_features.index = true
|
||||
c.table.used_features.arr_init = true
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) markused_array_method(check bool, method_name string) {
|
||||
if !check {
|
||||
return
|
||||
}
|
||||
match method_name {
|
||||
'' { // array init
|
||||
c.table.used_features.arr_init = true
|
||||
}
|
||||
'first' {
|
||||
c.table.used_features.arr_first = true
|
||||
}
|
||||
'last' {
|
||||
c.table.used_features.arr_last = true
|
||||
}
|
||||
'pop' {
|
||||
c.table.used_features.arr_pop = true
|
||||
}
|
||||
'delete' {
|
||||
c.table.used_features.arr_delete = true
|
||||
}
|
||||
'map' {
|
||||
c.table.used_features.arr_map = true
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user