all: implement `type_name()` for interfaces too (#8767)

pull/8768/head
spaceface 2021-02-15 14:29:44 +01:00 committed by GitHub
parent 4e2418e9cf
commit e3649ec4d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 2 deletions

View File

@ -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>()

View File

@ -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')

View File

@ -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)
}

View File

@ -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{}