From: Rico Tzschichholz Date: Sun, 12 Mar 2017 19:32:26 +0000 (+0100) Subject: signalmodule: Handle nullable ValueTypes properly and treat them as pointer X-Git-Tag: 0.36.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6e29bd10dd5c3cd1e222b78ce107d4921769452;p=thirdparty%2Fvala.git signalmodule: Handle nullable ValueTypes properly and treat them as pointer Nullable value-types are actually pointers to heap-allocated structures. Therefore a pointer-based marshaller is required for those types. https://bugzilla.gnome.org/show_bug.cgi?id=758816 --- diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala index 9eb567cd1..00c06c196 100644 --- a/codegen/valagsignalmodule.vala +++ b/codegen/valagsignalmodule.vala @@ -36,7 +36,11 @@ public class Vala.GSignalModule : GObjectModule { } } - ret = "%s_%s_".printf (prefix, get_ccode_marshaller_type_name (return_type)); + if (return_type is ValueType && return_type.nullable) { + ret = "%s_POINTER_".printf (prefix); + } else { + ret = "%s_%s_".printf (prefix, get_ccode_marshaller_type_name (return_type)); + } if (params == null || params.size == 0) { ret = ret + "_VOID"; @@ -58,6 +62,8 @@ public class Vala.GSignalModule : GObjectModule { return "const char*"; } else if (t.data_type is Class || t.data_type is Interface) { return "gpointer"; + } else if (t is ValueType && t.nullable) { + return "gpointer"; } else if (t.data_type is Struct) { var st = (Struct) t.data_type; if (st.is_simple_type ()) { @@ -87,7 +93,11 @@ public class Vala.GSignalModule : GObjectModule { private string get_marshaller_signature (List params, DataType return_type) { string signature; - signature = "%s:".printf (get_ccode_marshaller_type_name (return_type)); + if (return_type is ValueType && return_type.nullable) { + signature = "POINTER:"; + } else { + signature = "%s:".printf (get_ccode_marshaller_type_name (return_type)); + } if (params == null || params.size == 0) { signature = signature + "VOID"; } else { @@ -283,6 +293,8 @@ public class Vala.GSignalModule : GObjectModule { get_value_function = "g_value_get_pointer"; } else if (p.variable_type is ErrorType) { get_value_function = "g_value_get_pointer"; + } else if (p.variable_type is ValueType && p.variable_type.nullable) { + get_value_function = "g_value_get_pointer"; } else { get_value_function = get_ccode_get_value_function (p.variable_type.data_type); } @@ -319,6 +331,8 @@ public class Vala.GSignalModule : GObjectModule { set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_string")); } else if (return_type.data_type is Class || return_type.data_type is Interface) { set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_object")); + } else if (return_type is ValueType && return_type.nullable) { + set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer")); } else { set_fc = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_set_value_function (return_type.data_type))); } @@ -398,6 +412,8 @@ public class Vala.GSignalModule : GObjectModule { csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER")); } else if (sig.return_type is ErrorType) { csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER")); + } else if (sig.return_type is ValueType && sig.return_type.nullable) { + csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER")); } else if (sig.return_type.data_type == null) { csignew.add_argument (new CCodeConstant ("G_TYPE_NONE")); } else { @@ -427,6 +443,8 @@ public class Vala.GSignalModule : GObjectModule { csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER")); } else if (param.variable_type is ErrorType) { csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER")); + } else if (param.variable_type is ValueType && param.variable_type.nullable) { + csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER")); } else { csignew.add_argument (new CCodeConstant (get_ccode_type_id (param.variable_type.data_type))); } diff --git a/tests/Makefile.am b/tests/Makefile.am index b1d3ea299..6a50505bb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -206,6 +206,7 @@ TESTS = \ objects/bug702736.vala \ objects/bug702846.vala \ objects/bug751338.vala \ + objects/bug758816.vala \ objects/bug760031.test \ objects/bug764481.vala \ objects/bug767092.test \ diff --git a/tests/objects/bug758816.vala b/tests/objects/bug758816.vala new file mode 100644 index 000000000..733d004e1 --- /dev/null +++ b/tests/objects/bug758816.vala @@ -0,0 +1,70 @@ +enum Bar { + FAIL, + FOO, + BAR, + BAZ +} + +public struct Manam { + public int i; + public int j; +} + +class Foo : Object { + public signal Bar? bar (); + public signal Bar? bar2 (Bar? bar); + + public signal Manam? manam (); + public signal Manam? manam2 (Manam? manam); + + public void emit_bar () { + assert (bar () == Bar.FOO); + } + + public void emit_bar2 () { + assert (bar2 (Bar.BAZ) == Bar.BAZ); + } + + public void emit_manam () { + Manam? m = {23, 42}; + assert (manam () == m); + } + + public void emit_manam2 () { + Manam? m = {23, 42}; + assert (manam2 ({23, 42}) == m); + } +} + +Bar? callback_bar () { + return Bar.FOO; +} + +Bar? callback_bar2 (Bar? bar) { + assert (bar == Bar.BAZ); + return bar; +} + +Manam? callback_manam () { + return {23, 42}; +} + +Manam? callback_manam2 (Manam? manam) { + Manam? m = {23, 42}; + assert (manam == m); + return manam; +} + +void main () { + var foo = new Foo (); + + foo.bar.connect (callback_bar); + foo.emit_bar (); + foo.bar2.connect (callback_bar2); + foo.emit_bar2 (); + + foo.manam.connect (callback_manam); + foo.emit_manam (); + foo.manam2.connect (callback_manam2); + foo.emit_manam2 (); +}