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
|
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())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user