1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: clean up interface methods generation (#10400)

This commit is contained in:
Enzo 2021-06-09 21:44:18 +02:00 committed by GitHub
parent 811a3e1d38
commit 14519bbf5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6405,32 +6405,26 @@ fn (mut g Gen) interface_table() string {
interface_name := ityp.cname
// generate a struct that references interface methods
methods_struct_name := 'struct _${interface_name}_interface_methods'
mut methods_typ_def := strings.new_builder(100)
mut methods_struct_def := strings.new_builder(100)
methods_struct_def.writeln('$methods_struct_name {')
mut imethods := map[string]string{} // a map from speak -> _Speaker_speak_fn
mut methodidx := map[string]int{}
for k, method in inter_info.methods {
methodidx[method.name] = k
typ_name := '_${interface_name}_${method.name}_fn'
ret_styp := g.typ(method.return_type)
methods_typ_def.write_string('typedef $ret_styp (*$typ_name)(void* _')
methods_struct_def.write_string('\t$ret_styp (*_method_${c_name(method.name)})(void* _')
// the first param is the receiver, it's handled by `void*` above
for i in 1 .. method.params.len {
arg := method.params[i]
methods_typ_def.write_string(', ${g.typ(arg.typ)} $arg.name')
methods_struct_def.write_string(', ${g.typ(arg.typ)} $arg.name')
}
// TODO g.fn_args(method.args[1..], method.is_variadic)
methods_typ_def.writeln(');')
methods_struct_def.writeln('\t$typ_name _method_${c_name(method.name)};')
imethods[method.name] = typ_name
methods_struct_def.writeln(');')
}
methods_struct_def.writeln('};')
// generate an array of the interface methods for the structs using the interface
// as well as case functions from the struct to the interface
mut methods_struct := strings.new_builder(100)
//
mut staticprefix := 'static'
iname_table_length := inter_info.types.len
if iname_table_length == 0 {
// msvc can not process `static struct x[0] = {};`
@ -6467,7 +6461,7 @@ fn (mut g Gen) interface_table() string {
current_iinidx++
if ityp.name != 'vweb.DbInterface' { // TODO remove this
// eprintln('>>> current_iinidx: ${current_iinidx-iinidx_minimum_base} | interface_index_name: $interface_index_name')
sb.writeln('$staticprefix $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x);')
sb.writeln('static $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x);')
mut cast_struct := strings.new_builder(100)
cast_struct.writeln('($interface_name) {')
cast_struct.writeln('\t\t._$cctype = x,')
@ -6495,7 +6489,7 @@ fn (mut g Gen) interface_table() string {
cast_functions.writeln('
// Casting functions for converting "$cctype" to interface "$interface_name"
$staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x) {
static inline $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x) {
return $cast_struct_str;
}')
}
@ -6504,7 +6498,7 @@ $staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}(
methods_struct.writeln('\t{')
}
for _, method in st_sym.methods {
if method.name !in imethods {
if method.name !in methodidx {
// a method that is not part of the interface should be just skipped
continue
}
@ -6560,7 +6554,6 @@ $staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}(
sb.writeln('')
if inter_info.methods.len > 0 {
sb.writeln(methods_wrapper.str())
sb.writeln(methods_typ_def.str())
sb.writeln(methods_struct_def.str())
sb.writeln(methods_struct.str())
}