mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
ast, parser: fix wrong type name of nested generics (#16749)
This commit is contained in:
parent
e9cad6f09d
commit
0128d2dd1c
@ -1154,6 +1154,37 @@ pub fn (t &Table) clean_generics_type_str(typ Type) string {
|
|||||||
return result.all_before('[')
|
return result.all_before('[')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn strip_extra_struct_types(name string) string {
|
||||||
|
mut start := 0
|
||||||
|
mut is_start := false
|
||||||
|
mut nested_count := 0
|
||||||
|
mut strips := []string{}
|
||||||
|
|
||||||
|
for i, ch in name {
|
||||||
|
if ch == `<` {
|
||||||
|
if is_start {
|
||||||
|
nested_count++
|
||||||
|
} else {
|
||||||
|
is_start = true
|
||||||
|
start = i
|
||||||
|
}
|
||||||
|
} else if ch == `>` {
|
||||||
|
if nested_count > 0 {
|
||||||
|
nested_count--
|
||||||
|
} else {
|
||||||
|
strips << name.substr(start, i + 1)
|
||||||
|
strips << ''
|
||||||
|
is_start = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strips.len > 0 {
|
||||||
|
return name.replace_each(strips)
|
||||||
|
} else {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// import_aliases is a map of imported symbol aliases 'module.Type' => 'Type'
|
// import_aliases is a map of imported symbol aliases 'module.Type' => 'Type'
|
||||||
pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string]string) string {
|
pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string]string) string {
|
||||||
cache_key := (u64(import_aliases.len) << 32) | u64(typ)
|
cache_key := (u64(import_aliases.len) << 32) | u64(typ)
|
||||||
@ -1280,6 +1311,7 @@ pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string]
|
|||||||
import_aliases))
|
import_aliases))
|
||||||
res = '${variant_names.join('|')}'
|
res = '${variant_names.join('|')}'
|
||||||
} else {
|
} else {
|
||||||
|
res = strip_extra_struct_types(res)
|
||||||
res = t.shorten_user_defined_typenames(res, import_aliases)
|
res = t.shorten_user_defined_typenames(res, import_aliases)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1363,6 +1395,7 @@ fn (t Table) shorten_user_defined_typenames(originalname string, import_aliases
|
|||||||
}
|
}
|
||||||
// types defined by the user
|
// types defined by the user
|
||||||
// mod.submod.submod2.Type => submod2.Type
|
// mod.submod.submod2.Type => submod2.Type
|
||||||
|
if res.count('[') < 2 {
|
||||||
mut parts := res.split('.')
|
mut parts := res.split('.')
|
||||||
if parts.len > 1 {
|
if parts.len > 1 {
|
||||||
ind := parts.len - 2
|
ind := parts.len - 2
|
||||||
@ -1379,6 +1412,7 @@ fn (t Table) shorten_user_defined_typenames(originalname string, import_aliases
|
|||||||
res = parts[0]
|
res = parts[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,14 +654,14 @@ pub fn (mut p Parser) find_type_or_add_placeholder(name string, language ast.Lan
|
|||||||
if p.struct_init_generic_types.len > 0 && sym.info.generic_types.len > 0
|
if p.struct_init_generic_types.len > 0 && sym.info.generic_types.len > 0
|
||||||
&& p.struct_init_generic_types != sym.info.generic_types {
|
&& p.struct_init_generic_types != sym.info.generic_types {
|
||||||
generic_names := p.struct_init_generic_types.map(p.table.sym(it).name)
|
generic_names := p.struct_init_generic_types.map(p.table.sym(it).name)
|
||||||
mut sym_name := sym.name + '['
|
mut sym_name := sym.name + '<'
|
||||||
for i, gt in generic_names {
|
for i, gt in generic_names {
|
||||||
sym_name += gt
|
sym_name += gt
|
||||||
if i != generic_names.len - 1 {
|
if i != generic_names.len - 1 {
|
||||||
sym_name += ','
|
sym_name += ','
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sym_name += ']'
|
sym_name += '>'
|
||||||
existing_idx := p.table.type_idxs[sym_name]
|
existing_idx := p.table.type_idxs[sym_name]
|
||||||
if existing_idx > 0 {
|
if existing_idx > 0 {
|
||||||
idx = existing_idx
|
idx = existing_idx
|
||||||
|
@ -80,4 +80,15 @@ fn test_generics_struct_init_with_inconsistent_generic_types() {
|
|||||||
assert ry2[1].b.a.b == 'four'
|
assert ry2[1].b.a.b == 'four'
|
||||||
assert ry2[1].b.b.a == 'four'
|
assert ry2[1].b.b.a == 'four'
|
||||||
assert ry2[1].b.b.b == 4
|
assert ry2[1].b.b.b == 4
|
||||||
|
|
||||||
|
zx1 := []Tuple2[int, Tuple2[string, int]]{}
|
||||||
|
println(typeof(zx1).name)
|
||||||
|
println(typeof(rx1).name)
|
||||||
|
zx2 := []Tuple2[int, Tuple2[Tuple2[string, int], Tuple2[int, string]]]{}
|
||||||
|
println(typeof(zx2).name)
|
||||||
|
println(typeof(rx2).name)
|
||||||
|
assert typeof(zx1).name == '[]Tuple2[int, Tuple2[string, int]]'
|
||||||
|
assert typeof(zx2).name == '[]Tuple2[int, Tuple2[Tuple2[string, int], Tuple2[int, string]]]'
|
||||||
|
assert typeof(zx1).name == typeof(rx1).name
|
||||||
|
assert typeof(zx2).name == typeof(rx2).name
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user