62 lines
1.7 KiB
V
62 lines
1.7 KiB
V
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
|
// Use of this source code is governed by an MIT license
|
|
// that can be found in the LICENSE file.
|
|
module c
|
|
|
|
import v.ast
|
|
|
|
fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
|
if typ.has_flag(.generic) {
|
|
/*
|
|
resolve_generic_to_concrete should not mutate the table.
|
|
It mutates if the generic type is for example []T and the
|
|
concrete type is an array type that has not been registered
|
|
yet. This should have already happened in the checker, since
|
|
it also calls resolve_generic_to_concrete. g.table is made
|
|
non-mut to make sure no one else can accidentally mutates the table.
|
|
*/
|
|
mut muttable := unsafe { &ast.Table(g.table) }
|
|
if t_typ := muttable.resolve_generic_to_concrete(typ, if g.cur_fn != 0 {
|
|
g.cur_fn.generic_names
|
|
} else {
|
|
[]string{}
|
|
}, g.cur_concrete_types)
|
|
{
|
|
return t_typ
|
|
}
|
|
}
|
|
return typ
|
|
}
|
|
|
|
struct Type {
|
|
// typ is the original type
|
|
typ ast.Type [required]
|
|
sym &ast.TypeSymbol [required]
|
|
// unaliased is `typ` once aliased have been resolved
|
|
// it may not contain informations such as flags and nr_muls
|
|
unaliased ast.Type [required]
|
|
unaliased_sym &ast.TypeSymbol [required]
|
|
}
|
|
|
|
// unwrap returns the following variants of a type:
|
|
// * generics unwrapped
|
|
// * alias unwrapped
|
|
fn (mut g Gen) unwrap(typ ast.Type) Type {
|
|
no_generic := g.unwrap_generic(typ)
|
|
no_generic_sym := g.table.get_type_symbol(no_generic)
|
|
if no_generic_sym.kind != .alias {
|
|
return Type{
|
|
typ: no_generic
|
|
sym: no_generic_sym
|
|
unaliased: no_generic
|
|
unaliased_sym: no_generic_sym
|
|
}
|
|
}
|
|
return Type{
|
|
typ: no_generic
|
|
sym: no_generic_sym
|
|
unaliased: no_generic_sym.parent_idx
|
|
unaliased_sym: g.table.get_type_symbol(no_generic_sym.parent_idx)
|
|
}
|
|
}
|