checker: refactoring util fn inside utils utils.v file

Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
pull/14006/head
Vincenzo Palazzo 2022-04-11 01:06:23 +02:00
parent 11fc34c7d0
commit ae1de88f1f
No known key found for this signature in database
GPG Key ID: 8B6DC2B870B80D5F
3 changed files with 113 additions and 53 deletions

View File

@ -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 c.need_recheck_generic_fns = true
} }
} }
// generic_type_has_concrete_type make sure that the generics is declared with a type
// `Type<int>` and not `Type<T>`.
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{}
}

View File

@ -2464,17 +2464,6 @@ 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 {
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 // TODO node must be mut
pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type { pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
c.expr_level++ 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) { pub 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 {

View File

@ -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 {}
}
}