[vala/staging] codegen: Support gobject property of delegates not carrying their target



commit 2e6f652e868aa3c3f6be53f6cafd484ffb39b4bd
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Wed Oct 2 15:01:07 2019 +0200

    codegen: Support gobject property of delegates not carrying their target
    
    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         | 14 ++++-----
 codegen/valaccodememberaccessmodule.vala |  9 +++++-
 codegen/valagtypemodule.vala             |  4 +--
 tests/Makefile.am                        |  1 +
 tests/objects/property-delegate.vala     | 54 ++++++++++++++++++++++++++++++++
 vala/valapropertyaccessor.vala           |  1 +
 vala/valasemanticanalyzer.vala           |  2 ++
 7 files changed, 75 insertions(+), 10 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index c110716fb..1349a20aa 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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));
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 8dc720aa5..4c0c9f009 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -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"));
+                                                       }
                                                }
                                        }
                                }
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 7f05bfd7c..4eb7878a1 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -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"));
                        }
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f6b4c42a4..d0e75c29b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 000000000..9ea6cb177
--- /dev/null
+++ b/tests/objects/property-delegate.vala
@@ -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");
+       }
+}
diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala
index 553777afb..18ea71466 100644
--- a/vala/valapropertyaccessor.vala
+++ b/vala/valapropertyaccessor.vala
@@ -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
diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala
index f9eae2b07..5ffef23e9 100644
--- a/vala/valasemanticanalyzer.vala
+++ b/vala/valasemanticanalyzer.vala
@@ -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;
                        }


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