[vala/staging: 2/2] signalmodule: Handle nullable ValueTypes properly and treat them as pointer



commit deee669188b5e4042d2a11a9e6ec4ca4774b1293
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sun Mar 12 20:32:26 2017 +0100

    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

 codegen/valagsignalmodule.vala |   22 +++++++++++-
 tests/Makefile.am              |    1 +
 tests/objects/bug758816.vala   |   70 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 2 deletions(-)
---
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index 9eb567c..e7b876f 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.nullable && (return_type is ValueType)) {
+                       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 {
@@ -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 b1d3ea2..6a50505 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 0000000..2947d88
--- /dev/null
+++ b/tests/objects/bug758816.vala
@@ -0,0 +1,70 @@
+enum Bar {
+       FAIL,
+       FOO,
+       BAR,
+       BAZ
+}
+
+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 ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]