diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2017-03-12 20:32:26 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2017-03-16 12:52:21 +0100 |
commit | 744f48915e033740a08a08371a4a4524acc9a07f (patch) | |
tree | 66a4bec7a44e212fcba9a2f2f9ca491a394858f7 | |
parent | d6502649441b8403346b4d930e9715fae4a4b953 (diff) | |
download | vala-744f48915e033740a08a08371a4a4524acc9a07f.tar.gz |
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
-rw-r--r-- | codegen/valagsignalmodule.vala | 22 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/objects/bug758816.vala | 70 |
3 files changed, 91 insertions, 2 deletions
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala index 36bde0ae9..eaf02031a 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<Parameter> 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 { @@ -252,6 +262,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); } @@ -286,6 +298,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))); } @@ -365,6 +379,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 { @@ -392,6 +408,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 620e6ecb0..769e3373a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -174,6 +174,7 @@ TESTS = \ objects/bug702736.vala \ objects/bug702846.vala \ objects/bug751338.vala \ + objects/bug758816.vala \ objects/bug764481.vala \ objects/bug767092.test \ objects/bug768823.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 (); +} |