Skip to content

v.checker #

Constants #

const array_builtin_methods = ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice', 'sort',
	'sorted', 'sorted_with_compare', 'contains', 'index', 'wait', 'any', 'all', 'first', 'last',
	'pop', 'delete']

array_builtin_methods contains a list of all methods on array, that return other typed arrays, i.e. that act as pseudogeneric methods, that need compiler support, so that the types of the results are properly checked. Note that methods that do not return anything, or that return known types, are not listed here, since they are just ordinary non generic methods.

const array_builtin_methods_chk = token.new_keywords_matcher_from_array_trie(array_builtin_methods)
const reserved_type_names = ['byte', 'bool', 'char', 'i8', 'i16', 'int', 'i64', 'u8', 'u16',
	'u32', 'u64', 'f32', 'f64', 'map', 'string', 'rune', 'usize', 'isize', 'voidptr', 'thread']

Todo: remove byte from this list when it is no longer supported

const reserved_type_names_chk = token.new_keywords_matcher_from_array_trie(reserved_type_names)
const vroot_is_deprecated_message = '@VROOT is deprecated, use @VMODROOT or @VEXEROOT instead'

fn new_checker #

fn new_checker(table &ast.Table, pref_ &pref.Preferences) &Checker

struct Checker #

@[heap]
@[minify]
struct Checker {
pub mut:
	pref &pref.Preferences = unsafe { nil } // Preferences shared from V struct
	//
	table &ast.Table = unsafe { nil }
	file  &ast.File  = unsafe { nil }
	//
	nr_errors     int
	nr_warnings   int
	nr_notices    int
	errors        []errors.Error
	warnings      []errors.Warning
	notices       []errors.Notice
	error_lines   map[string]bool // dedup errors
	warning_lines map[string]bool // dedup warns
	notice_lines  map[string]bool // dedup notices
	error_details []string
	should_abort  bool // when too many errors/warnings/notices are accumulated, .should_abort becomes true. It is checked in statement/expression loops, so the checker can return early, instead of wasting time.
	//
	expected_type              ast.Type
	expected_or_type           ast.Type        // fn() or { 'this type' } eg. string. expected or block type
	expected_expr_type         ast.Type        // if/match is_expr: expected_type
	mod                        string          // current module name
	const_var                  &ast.ConstField = unsafe { nil } // the current constant, when checking const declarations
	const_deps                 []string
	const_names                []string
	global_names               []string
	locked_names               []string // vars that are currently locked
	rlocked_names              []string // vars that are currently read-locked
	in_for_count               int      // if checker is currently in a for loop
	returns                    bool
	scope_returns              bool
	is_builtin_mod             bool // true inside the 'builtin', 'os' or 'strconv' modules; TODO: remove the need for special casing this
	is_just_builtin_mod        bool // true only inside 'builtin'
	is_generated               bool // true for `[generated] module xyz` .v files
	inside_unsafe              bool // true inside `unsafe {}` blocks
	inside_const               bool // true inside `const ( ... )` blocks
	inside_anon_fn             bool // true inside `fn() { ... }()`
	inside_lambda              bool // true inside `|...| ...`
	inside_ref_lit             bool // true inside `a := &something`
	inside_defer               bool // true inside `defer {}` blocks
	inside_return              bool // true inside `return ...` blocks
	inside_fn_arg              bool // `a`, `b` in `a.f(b)`
	inside_ct_attr             bool // true inside `[if expr]`
	inside_x_is_type           bool // true inside the Type expression of `if x is Type {`
	inside_generic_struct_init bool
	cur_struct_generic_types   []ast.Type
	cur_struct_concrete_types  []ast.Type
	skip_flags                 bool      // should `#flag` and `#include` be skipped
	fn_level                   int       // 0 for the top level, 1 for `fn abc() {}`, 2 for a nested fn, etc
	smartcast_mut_pos          token.Pos // match mut foo, if mut foo is Foo
	smartcast_cond_pos         token.Pos // match cond
	ct_cond_stack              []ast.Expr
	ct_user_defines            map[string]ComptimeBranchSkipState
	ct_system_defines          map[string]ComptimeBranchSkipState
mut:
	stmt_level int // the nesting level inside each stmts list;
	// .stmt_level is used to check for `evaluated but not used` ExprStmts like `1 << 1`
	// 1 for statements directly at each inner scope level;
	// increases for `x := if cond { statement_list1} else {statement_list2}`;
	// increases for `x := optfn() or { statement_list3 }`;
	// files                            []ast.File
	expr_level                       int // to avoid infinite recursion segfaults due to compiler bugs
	ensure_generic_type_level        int // to avoid infinite recursion segfaults in ensure_generic_type_specify_type_names
	cur_orm_ts                       ast.TypeSymbol
	cur_anon_fn                      &ast.AnonFn = unsafe { nil }
	vmod_file_content                string     // needed for @VMOD_FILE, contents of the file, *NOT its path**
	loop_label                       string     // set when inside a labelled for loop
	vweb_gen_types                   []ast.Type // vweb route checks
	timers                           &util.Timers = util.get_timers()
	comptime_info_stack              []comptime.ComptimeInfo // stores the values from the above on each $for loop, to make nesting them easier
	comptime                         comptime.ComptimeInfo
	fn_scope                         &ast.Scope = unsafe { nil }
	main_fn_decl_node                ast.FnDecl
	match_exhaustive_cutoff_limit    int = 10
	is_last_stmt                     bool
	prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then
	using_new_err_struct             bool
	need_recheck_generic_fns         bool // need recheck generic fns because there are cascaded nested generic fn
	inside_sql                       bool // to handle sql table fields pseudo variables
	inside_selector_expr             bool
	inside_interface_deref           bool
	inside_decl_rhs                  bool
	inside_if_guard                  bool // true inside the guard condition of `if x := opt() {}`
	inside_assign                    bool
	// doing_line_info                  int    // a quick single file run when called with v -line-info (contains line nr to inspect)
	// doing_line_path                  string // same, but stores the path being parsed
	is_index_assign   bool
	comptime_call_pos int // needed for correctly checking use before decl for templates
	goto_labels       map[string]ast.GotoLabel // to check for unused goto labels
	enum_data_type    ast.Type
	field_data_type   ast.Type
	variant_data_type ast.Type
	fn_return_type    ast.Type
	orm_table_fields  map[string][]ast.StructField // known table structs
	//
	v_current_commit_hash string // same as old C.V_CURRENT_COMMIT_HASH
}

fn (Checker) change_current_file #

fn (mut c Checker) change_current_file(file &ast.File)

fn (Checker) check #

fn (mut c Checker) check(mut ast_file ast.File)

fn (Checker) check2 #

fn (mut c Checker) check2(mut ast_file ast.File) []errors.Error

not used right now

fn (Checker) check_files #

fn (mut c Checker) check_files(ast_files []&ast.File)

fn (Checker) check_scope_vars #

fn (mut c Checker) check_scope_vars(sc &ast.Scope)

fn (Checker) expr #

fn (mut c Checker) expr(mut node ast.Expr) ast.Type

fn (Checker) lambda_expr #

fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) ast.Type

fn (Checker) lambda_expr_fix_type_of_param #

fn (mut c Checker) lambda_expr_fix_type_of_param(mut node ast.LambdaExpr, mut pident ast.Ident, ptype ast.Type)

fn (Checker) support_lambda_expr_in_sort #

fn (mut c Checker) support_lambda_expr_in_sort(param_type ast.Type, return_type ast.Type, mut expr ast.LambdaExpr)

fn (Checker) support_lambda_expr_one_param #

fn (mut c Checker) support_lambda_expr_one_param(param_type ast.Type, return_type ast.Type, mut expr ast.LambdaExpr)