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