]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Support gobject property of delegates not carrying their target
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 2 Oct 2019 13:01:07 +0000 (15:01 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 3 Oct 2019 13:14:33 +0000 (15:14 +0200)
Properly evaluate given delegate_target attribute on properties to create
the expected API.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/856

codegen/valaccodebasemodule.vala
codegen/valaccodememberaccessmodule.vala
codegen/valagtypemodule.vala
tests/Makefile.am
tests/objects/property-delegate.vala [new file with mode: 0644]
vala/valapropertyaccessor.vala
vala/valasemanticanalyzer.vala

index c110716fb726dd74a57fc92857a4d3b51a0c7269..1349a20aa076cd28f931e27ca20b38c0b36829e5 100644 (file)
@@ -1592,7 +1592,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*" : length_ctype));
                        }
-               } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
+               } else if ((acc.value_type is DelegateType) && get_ccode_delegate_target (prop) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
                        function.add_parameter (new CCodeParameter (get_delegate_target_cname (acc.readable ? "result" : "value"), acc.readable ? get_ccode_name (delegate_target_type) + "*" : get_ccode_name (delegate_target_type)));
                        if (!acc.readable && acc.value_type.value_owned) {
                                function.add_parameter (new CCodeParameter (get_delegate_target_destroy_notify_cname ("value"), get_ccode_name (delegate_target_destroy_type)));
@@ -1686,7 +1686,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*": length_ctype));
                                }
-                       } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
+                       } else if ((acc.value_type is DelegateType) && get_ccode_delegate_target (prop) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
                                function.add_parameter (new CCodeParameter (get_delegate_target_cname (acc.readable ? "result" : "value"), acc.readable ? get_ccode_name (delegate_target_type) + "*" : get_ccode_name (delegate_target_type)));
                                if (!acc.readable && acc.value_type.value_owned) {
                                        function.add_parameter (new CCodeParameter (get_delegate_target_destroy_notify_cname ("value"), get_ccode_name (delegate_target_destroy_type)));
@@ -1741,7 +1741,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                        var len_expr = new CCodeIdentifier (get_array_length_cname ("result", dim));
                                                        vcall.add_argument (len_expr);
                                                }
-                                       } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
+                                       } else if ((acc.value_type is DelegateType) && get_ccode_delegate_target (prop) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
                                                vcall.add_argument (new CCodeIdentifier (get_delegate_target_cname ("result")));
                                        }
 
@@ -1759,7 +1759,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                var len_expr = new CCodeIdentifier (get_array_length_cname ("value", dim));
                                                vcall.add_argument (len_expr);
                                        }
-                               } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
+                               } else if ((acc.value_type is DelegateType) && get_ccode_delegate_target (prop) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
                                        vcall.add_argument (new CCodeIdentifier (get_delegate_target_cname ("value")));
                                        if (!acc.readable && acc.value_type.value_owned) {
                                                vcall.add_argument (new CCodeIdentifier (get_delegate_target_destroy_notify_cname ("value")));
@@ -1810,7 +1810,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        function.add_parameter (new CCodeParameter (get_array_length_cname (acc.readable ? "result" : "value", dim), acc.readable ? length_ctype + "*" : length_ctype));
                                }
-                       } else if ((acc.value_type is DelegateType) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
+                       } else if ((acc.value_type is DelegateType) && get_ccode_delegate_target (prop) && ((DelegateType) acc.value_type).delegate_symbol.has_target) {
                                function.add_parameter (new CCodeParameter (get_delegate_target_cname (acc.readable ? "result" : "value"), acc.readable ? get_ccode_name (delegate_target_type) + "*" : get_ccode_name (delegate_target_type)));
                                if (!acc.readable && acc.value_type.value_owned) {
                                        function.add_parameter (new CCodeParameter (get_delegate_target_destroy_notify_cname ("value"), get_ccode_name (delegate_target_destroy_type)));
@@ -3870,7 +3870,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        }
 
                        stmt.return_expression.target_value = temp_value;
-               } else if ((current_method != null || current_property_accessor != null) && current_return_type is DelegateType) {
+               } else if ((current_method != null || (current_property_accessor != null && get_ccode_delegate_target (current_property_accessor.prop))) && current_return_type is DelegateType) {
                        var delegate_type = (DelegateType) current_return_type;
                        if (delegate_type.delegate_symbol.has_target) {
                                var temp_value = store_temp_value (stmt.return_expression.target_value, stmt);
@@ -6116,7 +6116,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        }
                } else if (prop.property_type is DelegateType) {
                        var delegate_type = (DelegateType) prop.property_type;
-                       if (delegate_type.delegate_symbol.has_target) {
+                       if (get_ccode_delegate_target (prop) && delegate_type.delegate_symbol.has_target) {
                                ccall.add_argument (get_delegate_target_cvalue (value));
                                if (base_property.set_accessor.value_type.value_owned) {
                                        ccall.add_argument (get_delegate_target_destroy_notify_cvalue (value));
index 8dc720aa5d001ba9b22ff04b8a06eadcf426feb7..4c0c9f009b1ab11303d8152dcda904d014216b28 100644 (file)
@@ -282,8 +282,15 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                                }
                                        } else {
                                                delegate_type = prop.property_type as DelegateType;
-                                               if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
+                                               if (delegate_type != null && get_ccode_delegate_target (prop) && delegate_type.delegate_symbol.has_target) {
                                                        ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_delegate_target_cvalue (temp_value)));
+                                               } else {
+                                                       if (temp_value.delegate_target_cvalue != null) {
+                                                               ccode.add_assignment (temp_value.delegate_target_cvalue, new CCodeConstant ("NULL"));
+                                                       }
+                                                       if (temp_value.delegate_target_destroy_notify_cvalue != null) {
+                                                               ccode.add_assignment (temp_value.delegate_target_destroy_notify_cvalue, new CCodeConstant ("NULL"));
+                                                       }
                                                }
                                        }
                                }
index 7f05bfd7c56132b0561b8526ba7375b8eaf6d07b..4eb7878a12c9dc530e9583392c1e8f41ef9d32ea 100644 (file)
@@ -353,7 +353,7 @@ public class Vala.GTypeModule : GErrorModule {
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname ("result", dim), length_ctype));
                                }
-                       } else if ((prop.property_type is DelegateType) && ((DelegateType) prop.property_type).delegate_symbol.has_target) {
+                       } else if ((prop.property_type is DelegateType) && get_ccode_delegate_target (prop) && ((DelegateType) prop.property_type).delegate_symbol.has_target) {
                                vdeclarator.add_parameter (new CCodeParameter (get_delegate_target_cname ("result"), "gpointer*"));
                        }
 
@@ -384,7 +384,7 @@ public class Vala.GTypeModule : GErrorModule {
                                for (int dim = 1; dim <= array_type.rank; dim++) {
                                        vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname ("value", dim), length_ctype));
                                }
-                       } else if ((prop.property_type is DelegateType) && ((DelegateType) prop.property_type).delegate_symbol.has_target) {
+                       } else if ((prop.property_type is DelegateType) && get_ccode_delegate_target (prop) && ((DelegateType) prop.property_type).delegate_symbol.has_target) {
                                vdeclarator.add_parameter (new CCodeParameter (get_delegate_target_cname ("value"), "gpointer"));
                        }
 
index f6b4c42a40c402c0237f21c795dbc14bec0a6ad7..d0e75c29b92f5c85927d6a72b909c8791ac67d47 100644 (file)
@@ -330,6 +330,7 @@ TESTS = \
        objects/property-read-only-write.test \
        objects/property-construct-only-write.test \
        objects/property-construct-only-write-foreign.test \
+       objects/property-delegate.vala \
        objects/property-gboxed-nullable.vala \
        objects/property-real-struct-no-accessor.test \
        objects/property-simple-type-struct-nullable.vala \
diff --git a/tests/objects/property-delegate.vala b/tests/objects/property-delegate.vala
new file mode 100644 (file)
index 0000000..9ea6cb1
--- /dev/null
@@ -0,0 +1,54 @@
+public delegate unowned string Manam ();
+
+public class Foo {
+       public Manam deleg { get; set; }
+
+       public virtual Manam deleg_v { get; set; }
+
+       [CCode (delegate_target = false)]
+       public Manam deleg_no_target { get; set; }
+
+       [CCode (delegate_target = false)]
+       public virtual Manam deleg_no_target_v { get; set; }
+}
+
+public class Bar : Object {
+       [CCode (delegate_target = false)]
+       public Manam deleg { get; set; }
+
+       [CCode (delegate_target = false)]
+       public virtual Manam deleg_v { get; set; }
+}
+
+unowned string manam () {
+       return "manam";
+}
+
+void main () {
+       {
+               var foo = new Foo ();
+
+               foo.deleg = (Manam) manam;
+               assert (foo.deleg () == "manam");
+               foo.deleg_v = (Manam) manam;
+               assert (foo.deleg_v () == "manam");
+
+               foo.deleg_no_target = (Manam) manam;
+               assert (foo.deleg_no_target () == "manam");
+               foo.deleg_no_target_v = (Manam) manam;
+               assert (foo.deleg_no_target_v () == "manam");
+       }
+       {
+               var bar = new Bar ();
+               bar.deleg = (Manam) manam;
+               assert (bar.deleg () == "manam");
+               bar.deleg_v = (Manam) manam;
+               assert (bar.deleg_v () == "manam");
+
+               Manam func;
+               bar.get ("deleg", out func);
+               assert (func () == "manam");
+               bar.get ("deleg-v", out func);
+               assert (func () == "manam");
+       }
+}
index 553777afb421fa420e4487127a2ef7eeded59b84..18ea71466f803646e4d1036b4ebd394d696f0c85 100644 (file)
@@ -159,6 +159,7 @@ public class Vala.PropertyAccessor : Subroutine {
                        // Inherit important atttributes
                        value_parameter.copy_attribute_bool (prop, "CCode", "array_length");
                        value_parameter.copy_attribute_bool (prop, "CCode", "array_null_terminated");
+                       value_parameter.copy_attribute_bool (prop, "CCode", "delegate_target");
                }
 
                if (context.profile == Profile.GOBJECT
index f9eae2b07aa3304010a647eb46686d9d565d5094..5ffef23e9f20cc4bab21499e03228073421471e0 100644 (file)
@@ -435,6 +435,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        if (prop.property_type is ArrayType && (!prop.get_attribute_bool ("CCode", "array_length", true)
                            && prop.get_attribute_bool ("CCode", "array_null_terminated", false))) {
                                // null-terminated arrays without length are allowed
+                       } else if (prop.property_type is DelegateType && !prop.get_attribute_bool ("CCode", "delegate_target", true)) {
+                               // delegates omitting their target are allowed
                        } else {
                                return false;
                        }