@@ -937,6 +937,9 @@ pub fn (mut t Table) register_sym(sym TypeSymbol) int {
937937 ...sym
938938 }
939939 t.type_symbols[idx].idx = idx
940+ if t.type_symbols[idx].ngname == '' {
941+ t.type_symbols[idx].ngname = strip_generic_params (sym.name)
942+ }
940943 t.type_idxs[sym_name] = idx
941944 return idx
942945}
@@ -960,6 +963,11 @@ pub fn (t &Table) known_type(name string) bool {
960963 return t.type_idxs[name] != 0 || t.parsing_type == name || name in ['i32' , 'byte' ]
961964}
962965
966+ @[inline]
967+ pub fn strip_generic_params (name string ) string {
968+ return name.all_before ('[' )
969+ }
970+
963971// start_parsing_type open the scope during the parsing of a type
964972// where the type name must include the module prefix
965973pub fn (mut t Table) start_parsing_type (type_name string ) {
@@ -1178,6 +1186,7 @@ pub fn (mut t Table) find_or_register_chan(elem_type Type, is_mut bool) int {
11781186 kind: .chan
11791187 name: name
11801188 cname: cname
1189+ ngname: strip_generic_params (name)
11811190 info: Chan{
11821191 elem_type: elem_type
11831192 is_mut: is_mut
@@ -1199,6 +1208,7 @@ pub fn (mut t Table) find_or_register_map(key_type Type, value_type Type) int {
11991208 kind: .map
12001209 name: name
12011210 cname: cname
1211+ ngname: strip_generic_params (name)
12021212 info: Map{
12031213 key_type: key_type
12041214 value_type: value_type
@@ -1220,6 +1230,7 @@ pub fn (mut t Table) find_or_register_thread(return_type Type) int {
12201230 kind: .thread
12211231 name: name
12221232 cname: cname
1233+ ngname: strip_generic_params (name)
12231234 info: Thread{
12241235 return_type: return_type
12251236 }
@@ -1242,6 +1253,7 @@ pub fn (mut t Table) find_or_register_promise(return_type Type) int {
12421253 kind: .struct
12431254 name: name
12441255 cname: cname
1256+ ngname: strip_generic_params (name)
12451257 info: Struct{
12461258 concrete_types: [return_type, t.type_idxs['JS.Any' ]]
12471259 }
@@ -1265,6 +1277,7 @@ pub fn (mut t Table) find_or_register_array(elem_type Type) int {
12651277 kind: .array
12661278 name: name
12671279 cname: cname
1280+ ngname: strip_generic_params (name)
12681281 info: Array{
12691282 nr_dims: 1
12701283 elem_type: elem_type
@@ -1292,10 +1305,11 @@ pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int, size
12921305 cname := prefix + t.array_fixed_cname (elem_type, size)
12931306 // register
12941307 array_fixed_type := TypeSymbol{
1295- kind: .array_fixed
1296- name: name
1297- cname: cname
1298- info: ArrayFixed{
1308+ kind: .array_fixed
1309+ name: name
1310+ cname: cname
1311+ ngname: strip_generic_params (name)
1312+ info: ArrayFixed{
12991313 elem_type: elem_type
13001314 size: size
13011315 size_expr: size_expr
@@ -1328,10 +1342,11 @@ pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int {
13281342 return existing_idx
13291343 }
13301344 multireg_sym := TypeSymbol{
1331- kind: .multi_return
1332- name: name
1333- cname: cname
1334- info: MultiReturn{
1345+ kind: .multi_return
1346+ name: name
1347+ cname: cname
1348+ ngname: strip_generic_params (name)
1349+ info: MultiReturn{
13351350 types: mr_typs
13361351 }
13371352 }
@@ -1354,18 +1369,57 @@ pub fn (mut t Table) find_or_register_fn_type(f Fn, is_anon bool, has_decl bool)
13541369 return existing_idx
13551370 }
13561371 return t.register_sym (
1357- kind: .function
1358- name: name
1359- cname: cname
1360- mod: f.mod
1361- info: FnType{
1372+ kind: .function
1373+ name: name
1374+ cname: cname
1375+ ngname: strip_generic_params (name)
1376+ mod: f.mod
1377+ info: FnType{
13621378 is_anon: anon
13631379 has_decl: has_decl
13641380 func: f
13651381 }
13661382 )
13671383}
13681384
1385+ pub fn (mut t Table) find_or_register_generic_inst (parent_typ Type, concrete_types []Type) int {
1386+ parent_sym := t.sym (parent_typ)
1387+ if parent_sym.info ! is Struct {
1388+ return 0
1389+ }
1390+ struct_info := parent_sym.info as Struct
1391+ if struct_info.generic_types.len == 0 || concrete_types.len != struct_info.generic_types.len {
1392+ return 0
1393+ }
1394+ mut inst_name := parent_sym.ngname + '['
1395+ mut inst_cname := parent_sym.cname + '_T_'
1396+ for i, ct in concrete_types {
1397+ ct_sym := t.sym (ct)
1398+ inst_name + = ct_sym.name
1399+ inst_cname + = ct_sym.cname
1400+ if i < concrete_types.len - 1 {
1401+ inst_name + = ', '
1402+ inst_cname + = '_T_'
1403+ }
1404+ }
1405+ inst_name + = ']'
1406+ existing_idx := t.type_idxs[inst_name]
1407+ if existing_idx > 0 {
1408+ return existing_idx
1409+ }
1410+ return t.register_sym (
1411+ kind: .generic_inst
1412+ name: inst_name
1413+ cname: inst_cname
1414+ ngname: parent_sym.ngname
1415+ mod: parent_sym.mod
1416+ info: GenericInst{
1417+ parent_idx: parent_typ.idx ()
1418+ concrete_types: concrete_types
1419+ }
1420+ )
1421+ }
1422+
13691423pub fn (mut t Table) add_placeholder_type (name string , cname string , language Language) int {
13701424 mut modname := ''
13711425 if name.contains ('.' ) {
@@ -1375,6 +1429,7 @@ pub fn (mut t Table) add_placeholder_type(name string, cname string, language La
13751429 kind: .placeholder
13761430 name: name
13771431 cname: util.no_dots (cname).replace_each (['&' , '' ])
1432+ ngname: strip_generic_params (name)
13781433 language: language
13791434 mod: modname
13801435 is_pub: true
@@ -1893,7 +1948,7 @@ pub fn (mut t Table) convert_generic_type(generic_type Type, generic_names []str
18931948 if sym.info.is_generic {
18941949 mut nrt := '${sym.name} ['
18951950 mut rnrt := '${sym.rname} ['
1896- mut cnrt := '${sym.cname} [ '
1951+ mut cnrt := '${sym.cname} _T_ '
18971952 mut t_generic_names := generic_names.clone ()
18981953 mut t_to_types := to_types.clone ()
18991954 if sym.generic_types.len > 0 && sym.generic_types.len == sym.info.generic_types.len
@@ -1930,15 +1985,14 @@ pub fn (mut t Table) convert_generic_type(generic_type Type, generic_names []str
19301985 if i != sym.info.generic_types.len - 1 {
19311986 nrt + = ', '
19321987 rnrt + = ', '
1933- cnrt + = ', '
1988+ cnrt + = '_ '
19341989 }
19351990 } else {
19361991 return none
19371992 }
19381993 }
19391994 nrt + = ']'
19401995 rnrt + = ']'
1941- cnrt + = ']'
19421996 mut idx := t.type_idxs[nrt]
19431997 if idx == 0 {
19441998 idx = t.type_idxs[rnrt]
0 commit comments