checker: refactoring util fn inside utils utils.v file
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>pull/14006/head
parent
11fc34c7d0
commit
ae1de88f1f
|
@ -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<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{}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue