v: add support for T.unaliased_typ (#22546)

This commit is contained in:
Felipe Pena 2024-10-17 05:50:10 -03:00 committed by GitHub
parent e97036a25b
commit e4ffc7f224
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 53 additions and 1 deletions

View File

@ -279,6 +279,7 @@ pub enum GenericKindField {
unknown
name
typ
unaliased_typ
}
// `foo.bar`

View File

@ -1513,6 +1513,9 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
.name {
return ast.string_type
}
.unaliased_typ {
return ast.int_type
}
.typ {
return ast.int_type
}

View File

@ -3880,6 +3880,10 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
g.write(int(g.unwrap_generic(node.name_type)).str())
return
}
.unaliased_typ {
g.write(int(g.table.unaliased_type(g.unwrap_generic(node.name_type))).str())
return
}
.unknown {
// ast.TypeOf of `typeof(string).idx` etc
if node.field_name == 'name' {

View File

@ -473,6 +473,8 @@ fn (mut g Gen) get_expr_type(cond ast.Expr) ast.Type {
ast.SelectorExpr {
if cond.gkind_field == .typ {
return g.unwrap_generic(cond.name_type)
} else if cond.gkind_field == .unaliased_typ {
return g.table.unaliased_type(g.unwrap_generic(cond.name_type))
} else {
name := '${cond.expr}.${cond.field_name}'
if name in g.comptime.type_map {

View File

@ -3250,12 +3250,18 @@ fn (mut g JsGen) gen_selector_expr(it ast.SelectorExpr) {
}
.typ {
g.write('new int(')
g.write('${int(g.unwrap_generic(it.name_type))}')
g.write(')')
g.write(')')
return
}
.unaliased_typ {
g.write('new int(')
g.write('${int(g.table.unaliased_type(g.unwrap_generic(it.name_type)))}')
g.write(')')
g.write(')')
return
}
.unknown {
if node.field_name == 'name' {
g.type_name(it.name_type)

View File

@ -2936,6 +2936,7 @@ fn (mut p Parser) name_expr() ast.Expr {
fkind := match field {
'name' { ast.GenericKindField.name }
'typ' { ast.GenericKindField.typ }
'unaliased_typ' { ast.GenericKindField.unaliased_typ }
else { ast.GenericKindField.unknown }
}
pos.extend(p.tok.pos())

View File

@ -0,0 +1,35 @@
struct Struct {
a int
}
type StructAlias = Struct
fn test_main() {
mut a := StructAlias(Struct{})
assert alias_first(a) == 'alias'
assert struct_first(a) == 'struct'
}
fn alias_first[T](val T) string {
$if T is $alias {
return 'alias'
} $else $if T is $struct {
return 'struct'
} $else {
return 'else'
}
}
fn struct_first[T](val T) string {
$if T is $struct {
return 'struct'
} $else $if T is $alias {
$if T.unaliased_typ is $struct {
return 'struct'
} $else {
return 'alias'
}
} $else {
return 'else'
}
}