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:
parent
811a3e1d38
commit
14519bbf5c
@ -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())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user