From ae1de88f1f60d90d1917ea41f0daabbb155848c1 Mon Sep 17 00:00:00 2001 From: Vincenzo Palazzo Date: Mon, 11 Apr 2022 01:06:23 +0200 Subject: [PATCH] checker: refactoring util fn inside utils utils.v file Signed-off-by: Vincenzo Palazzo --- vlib/v/checker/check_types.v | 30 +++++++++++++ vlib/v/checker/checker.v | 53 ----------------------- vlib/v/checker/utils.v | 83 ++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 53 deletions(-) create mode 100644 vlib/v/checker/utils.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 0ee6d63656..da7f67dab5 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -687,3 +687,33 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr c.need_recheck_generic_fns = true } } + +// generic_type_has_concrete_type make sure that the generics is declared with a type +// `Type` and not `Type`. +fn (mut c Checker) generic_type_has_declared_with_concrete_type(typ ast.Type) bool { + return c.concrete_type_in_generic_type(typ).len > 0 +} + +fn (mut c Checker) concrete_type_in_generic_type(typ ast.Type) []ast.Type { + if typ.has_flag(.generic) /*true*/ { + //println('Chekcing generics ${c.table.type_to_str(typ)}') + unwrap_typ := c.unwrap_generic(typ) + //println('---> Generic inside ${c.table.type_to_str(unwrap_typ)}') + unwrap_sym := c.table.sym(unwrap_typ) + match unwrap_sym.info { + ast.Struct, ast.SumType, ast.Interface { + //println('Concrete types ${unwrap_sym.info.concrete_types}') + return unwrap_sym.info.concrete_types + } + ast.Alias { + return c.concrete_type_in_generic_type(unwrap_sym.info.parent_type) + } + else { + //println(unwrap_sym.info) + //println('****** no match found') + } + } + } + return []ast.Type{} +} + diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index d0b032c45d..e9ed8e2dde 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2464,17 +2464,6 @@ fn (mut c Checker) stmts_ending_with_expression(stmts []ast.Stmt) { c.scope_returns = false } -pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type { - if typ.has_flag(.generic) { - if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names, - c.table.cur_concrete_types) - { - return t_typ - } - } - return typ -} - // TODO node must be mut pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type { c.expr_level++ @@ -4159,48 +4148,6 @@ fn (mut c Checker) trace(fbase string, message string) { } } -fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? { - if typ == 0 { - c.error('unknown type', pos) - return - } - sym := c.table.sym(typ) - match sym.kind { - .placeholder { - if sym.language == .v && !sym.name.starts_with('C.') { - c.error(util.new_suggestion(sym.name, c.table.known_type_names()).say('unknown type `$sym.name`'), - pos) - return - } - } - .int_literal, .float_literal { - // Separate error condition for `int_literal` and `float_literal` because `util.suggestion` may give different - // suggestions due to f32 comparision issue. - if !c.is_builtin_mod { - msg := if sym.kind == .int_literal { - 'unknown type `$sym.name`.\nDid you mean `int`?' - } else { - 'unknown type `$sym.name`.\nDid you mean `f64`?' - } - c.error(msg, pos) - return - } - } - .array { - c.ensure_type_exists((sym.info as ast.Array).elem_type, pos) ? - } - .array_fixed { - c.ensure_type_exists((sym.info as ast.ArrayFixed).elem_type, pos) ? - } - .map { - info := sym.info as ast.Map - c.ensure_type_exists(info.key_type, pos) ? - c.ensure_type_exists(info.value_type, pos) ? - } - else {} - } -} - pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) { mut pos := token.Pos{} match expr { diff --git a/vlib/v/checker/utils.v b/vlib/v/checker/utils.v new file mode 100644 index 0000000000..cbc09873db --- /dev/null +++ b/vlib/v/checker/utils.v @@ -0,0 +1,83 @@ +module checker + +import v.ast +import v.token +import v.util + +// unwrap_generic unwrap the concrete type. +fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type { + if typ.has_flag(.generic) { + if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names, + c.table.cur_concrete_types) + { + return t_typ + } + } + return typ +} + +// ensure_type_exists check if the type was found somewhere before. +fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? { + if typ == 0 { + c.error('unknown type', pos) + return + } + sym := c.table.sym(typ) + match sym.kind { + .placeholder { + if sym.language == .v && !sym.name.starts_with('C.') { + c.error(util.new_suggestion(sym.name, c.table.known_type_names()).say('unknown type `$sym.name`'), + pos) + return + } + } + .int_literal, .float_literal { + // Separate error condition for `int_literal` and `float_literal` because `util.suggestion` may give different + // suggestions due to f32 comparision issue. + if !c.is_builtin_mod { + msg := if sym.kind == .int_literal { + 'unknown type `$sym.name`.\nDid you mean `int`?' + } else { + 'unknown type `$sym.name`.\nDid you mean `f64`?' + } + c.error(msg, pos) + return + } + } + .array { + c.ensure_type_exists((sym.info as ast.Array).elem_type, pos) ? + } + .array_fixed { + c.ensure_type_exists((sym.info as ast.ArrayFixed).elem_type, pos) ? + } + .map { + info := sym.info as ast.Map + c.ensure_type_exists(info.key_type, pos) ? + c.ensure_type_exists(info.value_type, pos) ? + } + .struct_ { + concrete_typs := c.concrete_type_in_generic_type(typ) + if concrete_typs.len > 0 { + for concrete_typ in concrete_typs { + //println('From Generics type ${c.table.type_to_str(concrete_typ)}') + c.ensure_type_exists(concrete_typ, pos) ? + } + } + } + .alias { + info := sym.info as ast.Alias + //println('Base type ${c.table.type_to_str(typ)}') + //println('Parent type ${c.table.type_to_str(info.parent_type)}') + c.ensure_type_exists(info.parent_type, pos) ? + } + .sum_type { + info := sym.info as ast.SumType + //println('Sum type ${c.table.type_to_str(typ)}') + for variant_typ in info.variants { + //println('Variant type -> ${c.table.type_to_str(variant_typ)}') + c.ensure_type_exists(variant_typ, pos) ? + } + } + else {} + } +}