v.ast: cleanup Table.resolve_generic_to_concrete/3 (#10559)

pull/10566/head
yuyi 2021-06-24 23:21:18 +08:00 committed by GitHub
parent e2f7fd16c2
commit e3ea5c1e17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 101 additions and 79 deletions

View File

@ -1142,99 +1142,121 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
} }
typ := concrete_types[index] typ := concrete_types[index]
return typ.derive(generic_type).clear_flag(.generic) return typ.derive(generic_type).clear_flag(.generic)
} else if sym.kind == .array { }
mut elem_type := (sym.info as Array).elem_type match mut sym.info {
mut elem_sym := t.get_type_symbol(elem_type) Array {
mut dims := 1 mut elem_type := sym.info.elem_type
for mut elem_sym.info is Array { mut elem_sym := t.get_type_symbol(elem_type)
elem_type = elem_sym.info.elem_type mut dims := 1
elem_sym = t.get_type_symbol(elem_type) for mut elem_sym.info is Array {
dims++ info := elem_sym.info as Array
} elem_type = info.elem_type
if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) { elem_sym = t.get_type_symbol(elem_type)
idx := t.find_or_register_array_with_dims(typ, dims) dims++
return new_type(idx).derive(generic_type).clear_flag(.generic) }
} if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) {
} else if sym.kind == .array_fixed { idx := t.find_or_register_array_with_dims(typ, dims)
info := sym.info as ArrayFixed return new_type(idx).derive(generic_type).clear_flag(.generic)
if typ := t.resolve_generic_to_concrete(info.elem_type, generic_names, concrete_types) {
idx := t.find_or_register_array_fixed(typ, info.size, None{})
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
} else if mut sym.info is Chan {
if typ := t.resolve_generic_to_concrete(sym.info.elem_type, generic_names, concrete_types) {
idx := t.find_or_register_chan(typ, typ.nr_muls() > 0)
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
} else if mut sym.info is MultiReturn {
mut types := []Type{}
mut type_changed := false
for ret_type in sym.info.types {
if typ := t.resolve_generic_to_concrete(ret_type, generic_names, concrete_types) {
types << typ
type_changed = true
} else {
types << ret_type
} }
} }
if type_changed { ArrayFixed {
idx := t.find_or_register_multi_return(types) if typ := t.resolve_generic_to_concrete(sym.info.elem_type, generic_names,
return new_type(idx).derive(generic_type).clear_flag(.generic) concrete_types)
{
idx := t.find_or_register_array_fixed(typ, sym.info.size, None{})
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
} }
} else if mut sym.info is Map { Chan {
mut type_changed := false if typ := t.resolve_generic_to_concrete(sym.info.elem_type, generic_names,
mut unwrapped_key_type := sym.info.key_type concrete_types)
mut unwrapped_value_type := sym.info.value_type {
if typ := t.resolve_generic_to_concrete(sym.info.key_type, generic_names, concrete_types) { idx := t.find_or_register_chan(typ, typ.nr_muls() > 0)
unwrapped_key_type = typ return new_type(idx).derive(generic_type).clear_flag(.generic)
type_changed = true }
} }
if typ := t.resolve_generic_to_concrete(sym.info.value_type, generic_names, concrete_types) { FnType {
unwrapped_value_type = typ mut func := sym.info.func
type_changed = true if func.return_type.has_flag(.generic) {
} if typ := t.resolve_generic_to_concrete(func.return_type, generic_names,
if type_changed {
idx := t.find_or_register_map(unwrapped_key_type, unwrapped_value_type)
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
} else if mut sym.info is Struct {
if sym.info.is_generic {
mut nrt := '$sym.name<'
for i in 0 .. sym.info.generic_types.len {
if ct := t.resolve_generic_to_concrete(sym.info.generic_types[i], generic_names,
concrete_types) concrete_types)
{ {
gts := t.get_type_symbol(ct) func.return_type = typ
nrt += gts.name }
if i != sym.info.generic_types.len - 1 { }
nrt += ',' func.params = func.params.clone()
for mut param in func.params {
if param.typ.has_flag(.generic) {
if typ := t.resolve_generic_to_concrete(param.typ, generic_names,
concrete_types)
{
param.typ = typ
} }
} }
} }
nrt += '>' idx := t.find_or_register_fn_type('', func, true, false)
mut idx := t.type_idxs[nrt]
if idx == 0 {
idx = t.add_placeholder_type(nrt, .v)
}
return new_type(idx).derive(generic_type).clear_flag(.generic) return new_type(idx).derive(generic_type).clear_flag(.generic)
} }
} else if mut sym.info is FnType { MultiReturn {
mut func := sym.info.func mut types := []Type{}
if func.return_type.has_flag(.generic) { mut type_changed := false
if typ := t.resolve_generic_to_concrete(func.return_type, generic_names, concrete_types) { for ret_type in sym.info.types {
func.return_type = typ if typ := t.resolve_generic_to_concrete(ret_type, generic_names, concrete_types) {
} types << typ
} type_changed = true
func.params = func.params.clone() } else {
for mut param in func.params { types << ret_type
if param.typ.has_flag(.generic) {
if typ := t.resolve_generic_to_concrete(param.typ, generic_names, concrete_types) {
param.typ = typ
} }
} }
if type_changed {
idx := t.find_or_register_multi_return(types)
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
} }
idx := t.find_or_register_fn_type('', func, true, false) Map {
return new_type(idx).derive(generic_type).clear_flag(.generic) mut type_changed := false
mut unwrapped_key_type := sym.info.key_type
mut unwrapped_value_type := sym.info.value_type
if typ := t.resolve_generic_to_concrete(sym.info.key_type, generic_names,
concrete_types)
{
unwrapped_key_type = typ
type_changed = true
}
if typ := t.resolve_generic_to_concrete(sym.info.value_type, generic_names,
concrete_types)
{
unwrapped_value_type = typ
type_changed = true
}
if type_changed {
idx := t.find_or_register_map(unwrapped_key_type, unwrapped_value_type)
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
}
Struct {
if sym.info.is_generic {
mut nrt := '$sym.name<'
for i in 0 .. sym.info.generic_types.len {
if ct := t.resolve_generic_to_concrete(sym.info.generic_types[i],
generic_names, concrete_types)
{
gts := t.get_type_symbol(ct)
nrt += gts.name
if i != sym.info.generic_types.len - 1 {
nrt += ','
}
}
}
nrt += '>'
mut idx := t.type_idxs[nrt]
if idx == 0 {
idx = t.add_placeholder_type(nrt, .v)
}
return new_type(idx).derive(generic_type).clear_flag(.generic)
}
}
else {}
} }
return none return none
} }