mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: minor cleanup in checker module (remove pub from most of checker's methods) (#16505)
This commit is contained in:
parent
7d57559b70
commit
27cdf5ae0e
@ -6,7 +6,7 @@ import v.ast
|
|||||||
import v.pref
|
import v.pref
|
||||||
|
|
||||||
// TODO 600 line function
|
// TODO 600 line function
|
||||||
pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
c.expected_type = ast.none_type // TODO a hack to make `x := if ... work`
|
c.expected_type = ast.none_type // TODO a hack to make `x := if ... work`
|
||||||
defer {
|
defer {
|
||||||
c.expected_type = ast.void_type
|
c.expected_type = ast.void_type
|
||||||
|
@ -6,7 +6,7 @@ module checker
|
|||||||
import v.ast
|
import v.ast
|
||||||
|
|
||||||
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
|
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
|
||||||
pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
|
fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
|
||||||
if got == expected {
|
if got == expected {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ fn (c Checker) check_multiple_ptr_match(got ast.Type, expected ast.Type, param a
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language, arg ast.CallArg) ? {
|
fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language, arg ast.CallArg) ? {
|
||||||
if got == 0 {
|
if got == 0 {
|
||||||
return error('unexpected 0 type')
|
return error('unexpected 0 type')
|
||||||
}
|
}
|
||||||
@ -298,7 +298,7 @@ fn (c Checker) check_same_module(got ast.Type, expected ast.Type) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool {
|
fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool {
|
||||||
unalias_got, unalias_expected := c.table.unalias_num_type(got), c.table.unalias_num_type(expected)
|
unalias_got, unalias_expected := c.table.unalias_num_type(got), c.table.unalias_num_type(expected)
|
||||||
if unalias_got.idx() == unalias_expected.idx() {
|
if unalias_got.idx() == unalias_expected.idx() {
|
||||||
// this is returning true even if one type is a ptr
|
// this is returning true even if one type is a ptr
|
||||||
@ -371,7 +371,7 @@ pub fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) check_matching_function_symbols(got_type_sym &ast.TypeSymbol, exp_type_sym &ast.TypeSymbol) bool {
|
fn (mut c Checker) check_matching_function_symbols(got_type_sym &ast.TypeSymbol, exp_type_sym &ast.TypeSymbol) bool {
|
||||||
if c.pref.translated {
|
if c.pref.translated {
|
||||||
// TODO too open
|
// TODO too open
|
||||||
return true
|
return true
|
||||||
@ -538,14 +538,14 @@ fn (mut c Checker) check_shift(mut node ast.InfixExpr, left_type_ ast.Type, righ
|
|||||||
return left_type
|
return left_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) promote_keeping_aliases(left_type ast.Type, right_type ast.Type, left_kind ast.Kind, right_kind ast.Kind) ast.Type {
|
fn (mut c Checker) promote_keeping_aliases(left_type ast.Type, right_type ast.Type, left_kind ast.Kind, right_kind ast.Kind) ast.Type {
|
||||||
if left_type == right_type && left_kind == .alias && right_kind == .alias {
|
if left_type == right_type && left_kind == .alias && right_kind == .alias {
|
||||||
return left_type
|
return left_type
|
||||||
}
|
}
|
||||||
return c.promote(left_type, right_type)
|
return c.promote(left_type, right_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) promote(left_type ast.Type, right_type ast.Type) ast.Type {
|
fn (mut c Checker) promote(left_type ast.Type, right_type ast.Type) ast.Type {
|
||||||
if left_type.is_any_kind_of_pointer() {
|
if left_type.is_any_kind_of_pointer() {
|
||||||
if right_type.is_int() || c.pref.translated {
|
if right_type.is_int() || c.pref.translated {
|
||||||
return left_type
|
return left_type
|
||||||
@ -614,7 +614,7 @@ fn (c &Checker) promote_num(left_type ast.Type, right_type ast.Type) ast.Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) check_expected(got ast.Type, expected ast.Type) ! {
|
fn (mut c Checker) check_expected(got ast.Type, expected ast.Type) ! {
|
||||||
if !c.check_types(got, expected) {
|
if !c.check_types(got, expected) {
|
||||||
return error(c.expected_msg(got, expected))
|
return error(c.expected_msg(got, expected))
|
||||||
}
|
}
|
||||||
@ -626,7 +626,7 @@ fn (c &Checker) expected_msg(got ast.Type, expected ast.Type) string {
|
|||||||
return 'expected `${exps}`, not `${gots}`'
|
return 'expected `${exps}`, not `${gots}`'
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) symmetric_check(left ast.Type, right ast.Type) bool {
|
fn (mut c Checker) symmetric_check(left ast.Type, right ast.Type) bool {
|
||||||
// allow direct int-literal assignment for pointers for now
|
// allow direct int-literal assignment for pointers for now
|
||||||
// maybe in the future optionals should be used for that
|
// maybe in the future optionals should be used for that
|
||||||
if right.is_ptr() || right.is_pointer() {
|
if right.is_ptr() || right.is_pointer() {
|
||||||
@ -759,7 +759,7 @@ fn (mut c Checker) infer_generic_struct_init_concrete_types(typ ast.Type, node a
|
|||||||
return concrete_types
|
return concrete_types
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
|
fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
|
||||||
mut inferred_types := []ast.Type{}
|
mut inferred_types := []ast.Type{}
|
||||||
for gi, gt_name in func.generic_names {
|
for gi, gt_name in func.generic_names {
|
||||||
// skip known types
|
// skip known types
|
||||||
|
@ -417,7 +417,7 @@ fn (mut c Checker) check_valid_pascal_case(name string, identifier string, pos t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
||||||
match node {
|
match node {
|
||||||
ast.AliasTypeDecl { c.alias_type_decl(node) }
|
ast.AliasTypeDecl { c.alias_type_decl(node) }
|
||||||
ast.FnTypeDecl { c.fn_type_decl(node) }
|
ast.FnTypeDecl { c.fn_type_decl(node) }
|
||||||
@ -425,7 +425,7 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
|
fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
|
||||||
// TODO Remove when `u8` isn't an alias in builtin anymore
|
// TODO Remove when `u8` isn't an alias in builtin anymore
|
||||||
if c.file.mod.name != 'builtin' {
|
if c.file.mod.name != 'builtin' {
|
||||||
c.check_valid_pascal_case(node.name, 'type alias', node.pos)
|
c.check_valid_pascal_case(node.name, 'type alias', node.pos)
|
||||||
@ -457,7 +457,7 @@ pub fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) {
|
fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) {
|
||||||
c.check_valid_pascal_case(node.name, 'fn type', node.pos)
|
c.check_valid_pascal_case(node.name, 'fn type', node.pos)
|
||||||
typ_sym := c.table.sym(node.typ)
|
typ_sym := c.table.sym(node.typ)
|
||||||
fn_typ_info := typ_sym.info as ast.FnType
|
fn_typ_info := typ_sym.info as ast.FnType
|
||||||
@ -476,7 +476,7 @@ pub fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
|
fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
|
||||||
c.check_valid_pascal_case(node.name, 'sum type', node.pos)
|
c.check_valid_pascal_case(node.name, 'sum type', node.pos)
|
||||||
mut names_used := []string{}
|
mut names_used := []string{}
|
||||||
for variant in node.variants {
|
for variant in node.variants {
|
||||||
@ -535,7 +535,7 @@ pub fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) expand_iface_embeds(idecl &ast.InterfaceDecl, level int, iface_embeds []ast.InterfaceEmbedding) []ast.InterfaceEmbedding {
|
fn (mut c Checker) expand_iface_embeds(idecl &ast.InterfaceDecl, level int, iface_embeds []ast.InterfaceEmbedding) []ast.InterfaceEmbedding {
|
||||||
// eprintln('> expand_iface_embeds: idecl.name: $idecl.name | level: $level | iface_embeds.len: $iface_embeds.len')
|
// eprintln('> expand_iface_embeds: idecl.name: $idecl.name | level: $level | iface_embeds.len: $iface_embeds.len')
|
||||||
if level > checker.iface_level_cutoff_limit {
|
if level > checker.iface_level_cutoff_limit {
|
||||||
c.error('too many interface embedding levels: ${level}, for interface `${idecl.name}`',
|
c.error('too many interface embedding levels: ${level}, for interface `${idecl.name}`',
|
||||||
@ -919,7 +919,7 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return the actual type of the expression, once the optional is handled
|
// return the actual type of the expression, once the optional is handled
|
||||||
pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Type {
|
fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Type {
|
||||||
if expr is ast.CallExpr {
|
if expr is ast.CallExpr {
|
||||||
if expr.return_type.has_flag(.optional) || expr.return_type.has_flag(.result) {
|
if expr.return_type.has_flag(.optional) || expr.return_type.has_flag(.result) {
|
||||||
return_modifier_kind := if expr.return_type.has_flag(.optional) {
|
return_modifier_kind := if expr.return_type.has_flag(.optional) {
|
||||||
@ -987,7 +987,7 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast
|
|||||||
return ret_type
|
return ret_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return_type ast.Type) {
|
fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return_type ast.Type) {
|
||||||
if node.kind == .propagate_option {
|
if node.kind == .propagate_option {
|
||||||
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.optional)
|
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.optional)
|
||||||
&& !c.table.cur_fn.is_main && !c.table.cur_fn.is_test && !c.inside_const {
|
&& !c.table.cur_fn.is_main && !c.table.cur_fn.is_test && !c.inside_const {
|
||||||
@ -1122,7 +1122,7 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
prevent_sum_type_unwrapping_once := c.prevent_sum_type_unwrapping_once
|
prevent_sum_type_unwrapping_once := c.prevent_sum_type_unwrapping_once
|
||||||
c.prevent_sum_type_unwrapping_once = false
|
c.prevent_sum_type_unwrapping_once = false
|
||||||
|
|
||||||
@ -1380,7 +1380,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) const_decl(mut node ast.ConstDecl) {
|
fn (mut c Checker) const_decl(mut node ast.ConstDecl) {
|
||||||
if node.fields.len == 0 {
|
if node.fields.len == 0 {
|
||||||
c.warn('const block must have at least 1 declaration', node.pos)
|
c.warn('const block must have at least 1 declaration', node.pos)
|
||||||
}
|
}
|
||||||
@ -1443,7 +1443,7 @@ pub fn (mut c Checker) const_decl(mut node ast.ConstDecl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) enum_decl(mut node ast.EnumDecl) {
|
fn (mut c Checker) enum_decl(mut node ast.EnumDecl) {
|
||||||
c.check_valid_pascal_case(node.name, 'enum name', node.pos)
|
c.check_valid_pascal_case(node.name, 'enum name', node.pos)
|
||||||
mut useen := []u64{}
|
mut useen := []u64{}
|
||||||
mut iseen := []i64{}
|
mut iseen := []i64{}
|
||||||
@ -2204,7 +2204,7 @@ fn (mut c Checker) stmts_ending_with_expression(stmts []ast.Stmt) {
|
|||||||
c.scope_returns = false
|
c.scope_returns = false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
||||||
if typ.has_flag(.generic) && c.table.cur_fn != unsafe { nil } {
|
if typ.has_flag(.generic) && c.table.cur_fn != unsafe { nil } {
|
||||||
if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names,
|
if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names,
|
||||||
c.table.cur_concrete_types)
|
c.table.cur_concrete_types)
|
||||||
@ -2566,7 +2566,7 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
|
|||||||
// return ast.void_type
|
// return ast.void_type
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
|
fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
|
||||||
// Given: `Outside( Inside(xyz) )`,
|
// Given: `Outside( Inside(xyz) )`,
|
||||||
// node.expr_type: `Inside`
|
// node.expr_type: `Inside`
|
||||||
// node.typ: `Outside`
|
// node.typ: `Outside`
|
||||||
@ -2932,7 +2932,7 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type {
|
|||||||
return ast.string_type
|
return ast.string_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
||||||
// TODO: move this
|
// TODO: move this
|
||||||
if c.const_deps.len > 0 {
|
if c.const_deps.len > 0 {
|
||||||
mut name := node.name
|
mut name := node.name
|
||||||
@ -3175,7 +3175,7 @@ pub fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
|||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) concat_expr(mut node ast.ConcatExpr) ast.Type {
|
fn (mut c Checker) concat_expr(mut node ast.ConcatExpr) ast.Type {
|
||||||
mut mr_types := []ast.Type{}
|
mut mr_types := []ast.Type{}
|
||||||
for expr in node.vals {
|
for expr in node.vals {
|
||||||
mr_types << c.expr(expr)
|
mr_types << c.expr(expr)
|
||||||
@ -3278,7 +3278,7 @@ fn (mut c Checker) smartcast(expr_ ast.Expr, cur_type ast.Type, to_type_ ast.Typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
|
fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
|
||||||
node.is_expr = c.expected_type != ast.void_type
|
node.is_expr = c.expected_type != ast.void_type
|
||||||
node.expected_type = c.expected_type
|
node.expected_type = c.expected_type
|
||||||
for branch in node.branches {
|
for branch in node.branches {
|
||||||
@ -3336,7 +3336,7 @@ pub fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
|
|||||||
return ast.bool_type
|
return ast.bool_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
|
fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
|
||||||
expected_type := c.expected_type
|
expected_type := c.expected_type
|
||||||
if c.rlocked_names.len > 0 || c.locked_names.len > 0 {
|
if c.rlocked_names.len > 0 || c.locked_names.len > 0 {
|
||||||
c.error('nested `lock`/`rlock` not allowed', node.pos)
|
c.error('nested `lock`/`rlock` not allowed', node.pos)
|
||||||
@ -3379,7 +3379,7 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
|
|||||||
return ret_type
|
return ret_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) ast.Type {
|
fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) ast.Type {
|
||||||
c.inside_unsafe = true
|
c.inside_unsafe = true
|
||||||
t := c.expr(node.expr)
|
t := c.expr(node.expr)
|
||||||
c.inside_unsafe = false
|
c.inside_unsafe = false
|
||||||
@ -3439,7 +3439,7 @@ fn (c &Checker) has_return(stmts []ast.Stmt) ?bool {
|
|||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
|
fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
|
||||||
typ := c.unwrap_generic(c.expr(node.expr))
|
typ := c.unwrap_generic(c.expr(node.expr))
|
||||||
typ_sym := c.table.sym(typ)
|
typ_sym := c.table.sym(typ)
|
||||||
is_non_void_pointer := (typ.is_ptr() || typ.is_pointer()) && typ_sym.kind != .voidptr
|
is_non_void_pointer := (typ.is_ptr() || typ.is_pointer()) && typ_sym.kind != .voidptr
|
||||||
@ -3456,7 +3456,7 @@ pub fn (mut c Checker) postfix_expr(mut node ast.PostfixExpr) ast.Type {
|
|||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) mark_as_referenced(mut node ast.Expr, as_interface bool) {
|
fn (mut c Checker) mark_as_referenced(mut node ast.Expr, as_interface bool) {
|
||||||
match mut node {
|
match mut node {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
if mut node.obj is ast.Var {
|
if mut node.obj is ast.Var {
|
||||||
@ -3509,7 +3509,7 @@ pub fn (mut c Checker) mark_as_referenced(mut node ast.Expr, as_interface bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) get_base_name(node &ast.Expr) string {
|
fn (mut c Checker) get_base_name(node &ast.Expr) string {
|
||||||
match node {
|
match node {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
return node.name
|
return node.name
|
||||||
@ -3526,7 +3526,7 @@ pub fn (mut c Checker) get_base_name(node &ast.Expr) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
|
fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
|
||||||
old_inside_ref_lit := c.inside_ref_lit
|
old_inside_ref_lit := c.inside_ref_lit
|
||||||
c.inside_ref_lit = c.inside_ref_lit || node.op == .amp
|
c.inside_ref_lit = c.inside_ref_lit || node.op == .amp
|
||||||
right_type := c.expr(node.right)
|
right_type := c.expr(node.right)
|
||||||
@ -3688,7 +3688,7 @@ fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_ty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||||
mut typ := c.expr(node.left)
|
mut typ := c.expr(node.left)
|
||||||
if typ == 0 {
|
if typ == 0 {
|
||||||
c.error('unknown type for expression `${node.left}`', node.pos)
|
c.error('unknown type for expression `${node.left}`', node.pos)
|
||||||
@ -3807,7 +3807,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
|||||||
// `.green` or `Color.green`
|
// `.green` or `Color.green`
|
||||||
// If a short form is used, `expected_type` needs to be an enum
|
// If a short form is used, `expected_type` needs to be an enum
|
||||||
// with this value.
|
// with this value.
|
||||||
pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
||||||
mut typ_idx := if node.enum_name == '' {
|
mut typ_idx := if node.enum_name == '' {
|
||||||
// Get the type of the enum without enum name by looking at the expected type.
|
// Get the type of the enum without enum name by looking at the expected type.
|
||||||
// e.g. `set_color(.green)`, V knows that `Green` is the expected type.
|
// e.g. `set_color(.green)`, V knows that `Green` is the expected type.
|
||||||
@ -3875,7 +3875,7 @@ pub fn (mut c Checker) enum_val(mut node ast.EnumVal) ast.Type {
|
|||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) chan_init(mut node ast.ChanInit) ast.Type {
|
fn (mut c Checker) chan_init(mut node ast.ChanInit) ast.Type {
|
||||||
if node.typ != 0 {
|
if node.typ != 0 {
|
||||||
info := c.table.sym(node.typ).chan_info()
|
info := c.table.sym(node.typ).chan_info()
|
||||||
node.elem_type = info.elem_type
|
node.elem_type = info.elem_type
|
||||||
@ -3895,7 +3895,7 @@ pub fn (mut c Checker) chan_init(mut node ast.ChanInit) ast.Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) offset_of(node ast.OffsetOf) ast.Type {
|
fn (mut c Checker) offset_of(node ast.OffsetOf) ast.Type {
|
||||||
sym := c.table.final_sym(node.struct_type)
|
sym := c.table.final_sym(node.struct_type)
|
||||||
if sym.kind != .struct_ {
|
if sym.kind != .struct_ {
|
||||||
c.error('first argument of __offsetof must be struct', node.pos)
|
c.error('first argument of __offsetof must be struct', node.pos)
|
||||||
@ -3907,7 +3907,7 @@ pub fn (mut c Checker) offset_of(node ast.OffsetOf) ast.Type {
|
|||||||
return ast.u32_type
|
return ast.u32_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) check_dup_keys(node &ast.MapInit, i int) {
|
fn (mut c Checker) check_dup_keys(node &ast.MapInit, i int) {
|
||||||
key_i := node.keys[i]
|
key_i := node.keys[i]
|
||||||
if key_i is ast.StringLiteral {
|
if key_i is ast.StringLiteral {
|
||||||
for j in 0 .. i {
|
for j in 0 .. i {
|
||||||
@ -3931,30 +3931,30 @@ pub fn (mut c Checker) check_dup_keys(node &ast.MapInit, i int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// call this *before* calling error or warn
|
// call this *before* calling error or warn
|
||||||
pub fn (mut c Checker) add_error_detail(s string) {
|
fn (mut c Checker) add_error_detail(s string) {
|
||||||
c.error_details << s
|
c.error_details << s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) add_error_detail_with_pos(msg string, pos token.Pos) {
|
fn (mut c Checker) add_error_detail_with_pos(msg string, pos token.Pos) {
|
||||||
c.add_error_detail(util.formatted_error('details:', msg, c.file.path, pos))
|
c.add_error_detail(util.formatted_error('details:', msg, c.file.path, pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) add_instruction_for_optional_type() {
|
fn (mut c Checker) add_instruction_for_optional_type() {
|
||||||
c.add_error_detail_with_pos('prepend ? before the declaration of the return type of `${c.table.cur_fn.name}`',
|
c.add_error_detail_with_pos('prepend ? before the declaration of the return type of `${c.table.cur_fn.name}`',
|
||||||
c.table.cur_fn.return_type_pos)
|
c.table.cur_fn.return_type_pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) add_instruction_for_result_type() {
|
fn (mut c Checker) add_instruction_for_result_type() {
|
||||||
c.add_error_detail_with_pos('prepend ! before the declaration of the return type of `${c.table.cur_fn.name}`',
|
c.add_error_detail_with_pos('prepend ! before the declaration of the return type of `${c.table.cur_fn.name}`',
|
||||||
c.table.cur_fn.return_type_pos)
|
c.table.cur_fn.return_type_pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) warn(s string, pos token.Pos) {
|
fn (mut c Checker) warn(s string, pos token.Pos) {
|
||||||
allow_warnings := !(c.pref.is_prod || c.pref.warns_are_errors) // allow warnings only in dev builds
|
allow_warnings := !(c.pref.is_prod || c.pref.warns_are_errors) // allow warnings only in dev builds
|
||||||
c.warn_or_error(s, pos, allow_warnings)
|
c.warn_or_error(s, pos, allow_warnings)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) error(message string, pos token.Pos) {
|
fn (mut c Checker) error(message string, pos token.Pos) {
|
||||||
$if checker_exit_on_first_error ? {
|
$if checker_exit_on_first_error ? {
|
||||||
eprintln('\n\n>> checker error: ${message}, pos: ${pos}')
|
eprintln('\n\n>> checker error: ${message}, pos: ${pos}')
|
||||||
print_backtrace()
|
print_backtrace()
|
||||||
@ -4000,7 +4000,7 @@ fn (c &Checker) check_struct_signature(from ast.Struct, to ast.Struct) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) note(message string, pos token.Pos) {
|
fn (mut c Checker) note(message string, pos token.Pos) {
|
||||||
if c.pref.message_limit >= 0 && c.nr_notices >= c.pref.message_limit {
|
if c.pref.message_limit >= 0 && c.nr_notices >= c.pref.message_limit {
|
||||||
c.should_abort = true
|
c.should_abort = true
|
||||||
return
|
return
|
||||||
@ -4168,7 +4168,7 @@ fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) {
|
fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) {
|
||||||
mut pos := token.Pos{}
|
mut pos := token.Pos{}
|
||||||
match expr {
|
match expr {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
@ -4233,7 +4233,7 @@ fn (mut c Checker) goto_label(node ast.GotoLabel) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) goto_stmt(node ast.GotoStmt) {
|
fn (mut c Checker) goto_stmt(node ast.GotoStmt) {
|
||||||
if c.inside_defer {
|
if c.inside_defer {
|
||||||
c.error('goto is not allowed in defer statements', node.pos)
|
c.error('goto is not allowed in defer statements', node.pos)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ module checker
|
|||||||
import v.ast
|
import v.ast
|
||||||
import v.token
|
import v.token
|
||||||
|
|
||||||
pub fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
|
fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
|
||||||
mut elem_type := ast.void_type
|
mut elem_type := ast.void_type
|
||||||
// `x := []string{}` (the type was set in the parser)
|
// `x := []string{}` (the type was set in the parser)
|
||||||
// TODO type is not set for fixed arrays
|
// TODO type is not set for fixed arrays
|
||||||
@ -269,14 +269,14 @@ fn (mut c Checker) check_array_init_para_type(para string, expr ast.Expr, pos to
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) ensure_sumtype_array_has_default_value(node ast.ArrayInit) {
|
fn (mut c Checker) ensure_sumtype_array_has_default_value(node ast.ArrayInit) {
|
||||||
sym := c.table.sym(node.elem_type)
|
sym := c.table.sym(node.elem_type)
|
||||||
if sym.kind == .sum_type && !node.has_default {
|
if sym.kind == .sum_type && !node.has_default {
|
||||||
c.error('cannot initialize sum type array without default value', node.pos)
|
c.error('cannot initialize sum type array without default value', node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
|
fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
|
||||||
// `map = {}`
|
// `map = {}`
|
||||||
if node.keys.len == 0 && node.vals.len == 0 && node.typ == 0 {
|
if node.keys.len == 0 && node.vals.len == 0 && node.typ == 0 {
|
||||||
sym := c.table.sym(c.expected_type)
|
sym := c.table.sym(c.expected_type)
|
||||||
|
@ -445,7 +445,7 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type {
|
|||||||
return node.typ
|
return node.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
|
fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
|
||||||
// Check whether the inner function definition is before the call
|
// Check whether the inner function definition is before the call
|
||||||
if var := node.scope.find_var(node.name) {
|
if var := node.scope.find_var(node.name) {
|
||||||
if var.expr is ast.AnonFn && var.pos.pos > node.pos.pos {
|
if var.expr is ast.AnonFn && var.pos.pos > node.pos.pos {
|
||||||
@ -514,7 +514,7 @@ pub fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
|
|||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) builtin_args(mut node ast.CallExpr, fn_name string, func ast.Fn) {
|
fn (mut c Checker) builtin_args(mut node ast.CallExpr, fn_name string, func ast.Fn) {
|
||||||
c.inside_println_arg = true
|
c.inside_println_arg = true
|
||||||
c.expected_type = ast.string_type
|
c.expected_type = ast.string_type
|
||||||
node.args[0].typ = c.expr(node.args[0].expr)
|
node.args[0].typ = c.expr(node.args[0].expr)
|
||||||
@ -546,7 +546,7 @@ pub fn (mut c Checker) builtin_args(mut node ast.CallExpr, fn_name string, func
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.Type {
|
fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.Type {
|
||||||
fn_name := node.name
|
fn_name := node.name
|
||||||
if fn_name == 'main' {
|
if fn_name == 'main' {
|
||||||
c.error('the `main` function cannot be called in the program', node.pos)
|
c.error('the `main` function cannot be called in the program', node.pos)
|
||||||
@ -1287,7 +1287,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
|||||||
return func.return_type
|
return func.return_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
||||||
left_type := c.expr(node.left)
|
left_type := c.expr(node.left)
|
||||||
if left_type == ast.void_type {
|
if left_type == ast.void_type {
|
||||||
c.error('cannot call a method using an invalid expression', node.pos)
|
c.error('cannot call a method using an invalid expression', node.pos)
|
||||||
@ -1991,7 +1991,7 @@ fn (mut c Checker) post_process_generic_fns() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) ! {
|
fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) ! {
|
||||||
nr_args := node.args.len
|
nr_args := node.args.len
|
||||||
nr_params := if node.is_method && f.params.len > 0 { f.params.len - 1 } else { f.params.len }
|
nr_params := if node.is_method && f.params.len > 0 { f.params.len - 1 } else { f.params.len }
|
||||||
mut min_required_params := f.params.len
|
mut min_required_params := f.params.len
|
||||||
|
@ -6,7 +6,7 @@ import v.ast
|
|||||||
import v.pref
|
import v.pref
|
||||||
import v.token
|
import v.token
|
||||||
|
|
||||||
pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
||||||
if_kind := if node.is_comptime { '\$if' } else { 'if' }
|
if_kind := if node.is_comptime { '\$if' } else { 'if' }
|
||||||
mut node_is_expr := false
|
mut node_is_expr := false
|
||||||
if node.branches.len > 0 && node.has_else {
|
if node.branches.len > 0 && node.has_else {
|
||||||
|
@ -4,7 +4,7 @@ import v.ast
|
|||||||
import v.pref
|
import v.pref
|
||||||
import v.token
|
import v.token
|
||||||
|
|
||||||
pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||||
former_expected_type := c.expected_type
|
former_expected_type := c.expected_type
|
||||||
defer {
|
defer {
|
||||||
c.expected_type = former_expected_type
|
c.expected_type = former_expected_type
|
||||||
@ -715,7 +715,7 @@ fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) invalid_operator_error(op token.Kind, left_type ast.Type, right_type ast.Type, pos token.Pos) {
|
fn (mut c Checker) invalid_operator_error(op token.Kind, left_type ast.Type, right_type ast.Type, pos token.Pos) {
|
||||||
left_name := c.table.type_to_str(left_type)
|
left_name := c.table.type_to_str(left_type)
|
||||||
right_name := c.table.type_to_str(right_type)
|
right_name := c.table.type_to_str(right_type)
|
||||||
c.error('invalid operator `${op}` to `${left_name}` and `${right_name}`', pos)
|
c.error('invalid operator `${op}` to `${left_name}` and `${right_name}`', pos)
|
||||||
|
@ -6,7 +6,7 @@ module checker
|
|||||||
import v.ast
|
import v.ast
|
||||||
import v.token
|
import v.token
|
||||||
|
|
||||||
pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||||
c.check_valid_pascal_case(node.name, 'interface name', node.pos)
|
c.check_valid_pascal_case(node.name, 'interface name', node.pos)
|
||||||
mut decl_sym := c.table.sym(node.typ)
|
mut decl_sym := c.table.sym(node.typ)
|
||||||
is_js := node.language == .js
|
is_js := node.language == .js
|
||||||
|
@ -6,7 +6,7 @@ import v.util
|
|||||||
import v.token
|
import v.token
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
||||||
node.is_expr = c.expected_type != ast.void_type
|
node.is_expr = c.expected_type != ast.void_type
|
||||||
node.expected_type = c.expected_type
|
node.expected_type = c.expected_type
|
||||||
if mut node.cond is ast.ParExpr && !c.pref.translated && !c.file.is_translated {
|
if mut node.cond is ast.ParExpr && !c.pref.translated && !c.file.is_translated {
|
||||||
|
@ -6,7 +6,7 @@ import v.ast
|
|||||||
import v.pref
|
import v.pref
|
||||||
|
|
||||||
// TODO: non deferred
|
// TODO: non deferred
|
||||||
pub fn (mut c Checker) return_stmt(mut node ast.Return) {
|
fn (mut c Checker) return_stmt(mut node ast.Return) {
|
||||||
if c.table.cur_fn == unsafe { nil } {
|
if c.table.cur_fn == unsafe { nil } {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) find_unreachable_statements_after_noreturn_calls(stmts []ast.Stmt) {
|
fn (mut c Checker) find_unreachable_statements_after_noreturn_calls(stmts []ast.Stmt) {
|
||||||
mut prev_stmt_was_noreturn_call := false
|
mut prev_stmt_was_noreturn_call := false
|
||||||
for stmt in stmts {
|
for stmt in stmts {
|
||||||
if stmt is ast.ExprStmt {
|
if stmt is ast.ExprStmt {
|
||||||
|
@ -6,7 +6,7 @@ module checker
|
|||||||
import v.ast
|
import v.ast
|
||||||
import v.token
|
import v.token
|
||||||
|
|
||||||
pub fn (mut c Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 {
|
fn (mut c Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 {
|
||||||
if ftyp.has_flag(.optional) || ftyp.has_flag(.result) {
|
if ftyp.has_flag(.optional) || ftyp.has_flag(.result) {
|
||||||
return `s`
|
return `s`
|
||||||
} else if typ.is_float() {
|
} else if typ.is_float() {
|
||||||
@ -40,7 +40,7 @@ pub fn (mut c Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
|
fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
|
||||||
inside_println_arg_save := c.inside_println_arg
|
inside_println_arg_save := c.inside_println_arg
|
||||||
c.inside_println_arg = true
|
c.inside_println_arg = true
|
||||||
for i, expr in node.exprs {
|
for i, expr in node.exprs {
|
||||||
@ -115,7 +115,7 @@ const unicode_lit_overflow_message = 'unicode character exceeds max allowed valu
|
|||||||
|
|
||||||
// unicode character literals are limited to a maximum value of 0x10ffff
|
// unicode character literals are limited to a maximum value of 0x10ffff
|
||||||
// https://stackoverflow.com/questions/52203351/why-unicode-is-restricted-to-0x10ffff
|
// https://stackoverflow.com/questions/52203351/why-unicode-is-restricted-to-0x10ffff
|
||||||
pub fn (mut c Checker) string_lit(mut node ast.StringLiteral) ast.Type {
|
fn (mut c Checker) string_lit(mut node ast.StringLiteral) ast.Type {
|
||||||
mut idx := 0
|
mut idx := 0
|
||||||
for idx < node.val.len {
|
for idx < node.val.len {
|
||||||
match node.val[idx] {
|
match node.val[idx] {
|
||||||
@ -165,7 +165,7 @@ pub fn (mut c Checker) string_lit(mut node ast.StringLiteral) ast.Type {
|
|||||||
return ast.string_type
|
return ast.string_type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) int_lit(mut node ast.IntegerLiteral) ast.Type {
|
fn (mut c Checker) int_lit(mut node ast.IntegerLiteral) ast.Type {
|
||||||
if node.val.len < 17 {
|
if node.val.len < 17 {
|
||||||
// can not be a too large number, no need for more expensive checks
|
// can not be a too large number, no need for more expensive checks
|
||||||
return ast.int_literal_type
|
return ast.int_literal_type
|
||||||
|
@ -5,7 +5,7 @@ module checker
|
|||||||
import v.ast
|
import v.ast
|
||||||
import v.util
|
import v.util
|
||||||
|
|
||||||
pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
||||||
mut struct_sym, struct_typ_idx := c.table.find_sym_and_type_idx(node.name)
|
mut struct_sym, struct_typ_idx := c.table.find_sym_and_type_idx(node.name)
|
||||||
mut has_generic_types := false
|
mut has_generic_types := false
|
||||||
if mut struct_sym.info is ast.Struct {
|
if mut struct_sym.info is ast.Struct {
|
||||||
@ -231,7 +231,7 @@ fn minify_sort_fn(a &ast.StructField, b &ast.StructField) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
||||||
if node.typ == ast.void_type {
|
if node.typ == ast.void_type {
|
||||||
// short syntax `foo(key:val, key2:val2)`
|
// short syntax `foo(key:val, key2:val2)`
|
||||||
if c.expected_type == ast.void_type {
|
if c.expected_type == ast.void_type {
|
||||||
|
Loading…
Reference in New Issue
Block a user