all: implement `type_name()` for interfaces too (#8767)
parent
4e2418e9cf
commit
e3649ec4d3
|
@ -1356,7 +1356,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
|||
c.error('optional type cannot be called directly', call_expr.left.position())
|
||||
return table.void_type
|
||||
}
|
||||
if left_type_sym.kind == .sum_type && method_name == 'type_name' {
|
||||
if left_type_sym.kind in [.sum_type, .interface_] && method_name == 'type_name' {
|
||||
return table.string_type
|
||||
}
|
||||
mut has_generic_generic := false // x.foo<T>() instead of x.foo<int>()
|
||||
|
|
|
@ -484,7 +484,7 @@ pub fn (mut g Gen) finish() {
|
|||
|
||||
pub fn (mut g Gen) write_typeof_functions() {
|
||||
g.writeln('')
|
||||
g.writeln('// >> typeof() support for sum types')
|
||||
g.writeln('// >> typeof() support for sum types / interfaces')
|
||||
for typ in g.table.types {
|
||||
if typ.kind == .sum_type {
|
||||
sum_info := typ.info as table.SumType
|
||||
|
@ -508,6 +508,15 @@ pub fn (mut g Gen) write_typeof_functions() {
|
|||
g.writeln('\t}')
|
||||
}
|
||||
g.writeln('}')
|
||||
} else if typ.kind == .interface_ {
|
||||
inter_info := typ.info as table.Interface
|
||||
g.writeln('static char * v_typeof_interface_${typ.cname}(int sidx) { /* $typ.name */ ')
|
||||
for t in inter_info.types {
|
||||
subtype := g.table.get_type_symbol(t)
|
||||
g.writeln('\tif (sidx == _${typ.cname}_${subtype.cname}_index) return "${util.strip_main_name(subtype.name)}";')
|
||||
}
|
||||
g.writeln('\treturn "unknown ${util.strip_main_name(typ.name)}";')
|
||||
g.writeln('}')
|
||||
}
|
||||
}
|
||||
g.writeln('// << typeof() support for sum types')
|
||||
|
|
|
@ -537,6 +537,12 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
|||
g.write(').typ ))')
|
||||
return
|
||||
}
|
||||
if left_sym.kind == .interface_ && node.name == 'type_name' {
|
||||
g.write('tos3( /* $left_sym.name */ v_typeof_interface_${typ_sym.cname}( (')
|
||||
g.expr(node.left)
|
||||
g.write(')._interface_idx ))')
|
||||
return
|
||||
}
|
||||
if node.name == 'str' {
|
||||
g.gen_str_for_type(node.receiver_type)
|
||||
}
|
||||
|
|
|
@ -475,6 +475,10 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
|||
method_start_pos := p.tok.position()
|
||||
line_nr := p.tok.line_nr
|
||||
name := p.check_name()
|
||||
if name == 'type_name' {
|
||||
p.error_with_pos('cannot override built-in method `type_name`', method_start_pos)
|
||||
return ast.InterfaceDecl{}
|
||||
}
|
||||
if ts.has_method(name) {
|
||||
p.error_with_pos('duplicate method `$name`', method_start_pos)
|
||||
return ast.InterfaceDecl{}
|
||||
|
|
Loading…
Reference in New Issue