[vala] girparser: Take in account base property for ConcreteAccessor



commit 9bcc61ce5536ed05bb59534ea8c0fd2e9a53aec0
Author: Luca Bruno <lucabru src gnome org>
Date:   Sat Dec 27 18:17:32 2014 +0100

    girparser: Take in account base property for ConcreteAccessor
    
    Property had NoAccessorMethod when the overridden
    interface property had ConcreteAccessor.
    Now we lookup the base interface property to fix ownership
    according to the base accessors and remove NoAccessorMethod.
    
    Fixes bug 742012

 tests/Makefile.am        |    1 +
 tests/gir/bug742012.test |   95 ++++++++++++++++++++++++++++++++++++++++++++++
 vala/valagirparser.vala  |   53 +++++++++++++++++++++++++
 3 files changed, 149 insertions(+), 0 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3dab72c..a9bd40f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -204,6 +204,7 @@ TESTS = \
        dbus/bug602003.test \
        gir/bug651773.test \
        gir/bug667751.test \
+       gir/bug742012.test \
        $(NULL)
 
 check-TESTS: $(TESTS)
diff --git a/tests/gir/bug742012.test b/tests/gir/bug742012.test
new file mode 100644
index 0000000..5ce77a6
--- /dev/null
+++ b/tests/gir/bug742012.test
@@ -0,0 +1,95 @@
+GIR
+
+Input:
+
+<class name="CertificateRenderer"
+       c:symbol-prefix="certificate_renderer"
+       c:type="GcrCertificateRenderer"
+       parent="GObject.Object"
+       glib:type-name="GcrCertificateRenderer"
+       glib:get-type="gcr_certificate_renderer_get_type"
+       glib:type-struct="CertificateRendererClass">
+  <implements name="Renderer"/>
+  <property name="attributes" writable="1" transfer-ownership="none">
+    <type name="GLib.List"/>
+  </property>
+  <field name="parent">
+    <type name="GObject.Object" c:type="GObject"/>
+  </field>
+  <field name="pv" readable="0" private="1">
+    <type name="CertificateRendererPrivate"
+          c:type="GcrCertificateRendererPrivate*"/>
+  </field>
+</class>
+<record name="CertificateRendererClass"
+        c:type="GcrCertificateRendererClass"
+        glib:is-gtype-struct-for="CertificateRenderer">
+  <field name="parent_class">
+    <type name="GObject.ObjectClass" c:type="GObjectClass"/>
+  </field>
+</record>
+<record name="CertificateRendererPrivate"
+        c:type="GcrCertificateRendererPrivate"
+        disguised="1">
+</record>
+
+<interface name="Renderer"
+           c:symbol-prefix="renderer"
+           c:type="GcrRenderer"
+           glib:type-name="GcrRenderer"
+           glib:get-type="gcr_renderer_get_type"
+           glib:type-struct="RendererIface">
+  <method name="get_attributes" c:identifier="gcr_renderer_get_attributes">
+    <return-value transfer-ownership="none">
+      <type name="GLib.List" c:type="GList*"/>
+    </return-value>
+    <parameters>
+      <instance-parameter name="self" transfer-ownership="none">
+        <type name="Renderer" c:type="GcrRenderer*"/>
+      </instance-parameter>
+    </parameters>
+  </method>
+  <method name="set_attributes" c:identifier="gcr_renderer_set_attributes">
+    <return-value transfer-ownership="none">
+      <type name="none" c:type="void"/>
+    </return-value>
+    <parameters>
+      <instance-parameter name="self" transfer-ownership="none">
+        <type name="Renderer" c:type="GcrRenderer*"/>
+      </instance-parameter>
+      <parameter name="attrs"
+                 transfer-ownership="none"
+                 nullable="1"
+                 allow-none="1">
+        <type name="GLib.List" c:type="GList*"/>
+      </parameter>
+    </parameters>
+  </method>
+  <property name="attributes" writable="1" transfer-ownership="none">
+    <type name="GLib.List"/>
+  </property>
+</interface>
+<record name="RendererIface"
+        c:type="GcrRendererIface"
+        glib:is-gtype-struct-for="Renderer">
+  <field name="parent">
+    <type name="GObject.TypeInterface" c:type="GTypeInterface"/>
+  </field>
+</record>
+
+Output:
+
+[CCode (cheader_filename = "test.h", cname = "GcrCertificateRenderer", type_id = 
"gcr_certificate_renderer_get_type ()")]
+public class CertificateRenderer : GLib.Object, Test.Renderer {
+       [CCode (has_construct_function = false)]
+       protected CertificateRenderer ();
+}
+[CCode (cheader_filename = "test.h", cname = "GcrRenderer", type_id = "gcr_renderer_get_type ()")]
+public interface Renderer : GLib.Object {
+       [CCode (cname = "gcr_renderer_get_attributes")]
+       public unowned GLib.List get_attributes ();
+       [CCode (cname = "gcr_renderer_set_attributes")]
+       public void set_attributes (GLib.List? attrs);
+       [NoAccessorMethod]
+       public abstract GLib.List attributes { owned get; set; }
+}
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 9d8ef15..46cdc77 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -1028,6 +1028,29 @@ public class Vala.GirParser : CodeVisitor {
                                        }
 
                                        if (prop.get_attribute ("NoAccessorMethod") != null) {
+                                               if (!prop.overrides && parent.symbol is Class) {
+                                                       // bug 742012
+                                                       // find base interface property with ConcreteAccessor 
and this overriding property with NoAccessorMethod
+                                                       var base_prop_node = parser.base_interface_property 
(this);
+                                                       if (base_prop_node != null) {
+                                                               base_prop_node.process (parser);
+                                                               
+                                                               var base_property = (Property) 
base_prop_node.symbol;
+                                                               if (base_property.get_attribute 
("ConcreteAccessor") != null) {
+                                                                       prop.set_attribute 
("NoAccessorMethod", false);
+                                                                       if (prop.get_accessor != null) {
+                                                                               
prop.get_accessor.value_type.value_owned = base_property.get_accessor.value_type.value_owned;
+                                                                       }
+                                                                       if (prop.set_accessor != null) {
+                                                                               
prop.set_accessor.value_type.value_owned = base_property.set_accessor.value_type.value_owned;
+                                                                       }
+                                                                       
+                                                               }
+                                                       }
+                                               }
+                                       }
+
+                                       if (prop.get_attribute ("NoAccessorMethod") != null) {
                                                // gobject defaults
                                                if (prop.get_accessor != null) {
                                                        prop.get_accessor.value_type.value_owned = true;
@@ -3915,4 +3938,34 @@ public class Vala.GirParser : CodeVisitor {
                }
                return true;
        }
+
+       /* Helper methods */
+
+       Node? base_interface_property (Node prop_node) {
+               var cl = prop_node.parent.symbol as Class;
+               if (cl == null) {
+                       return null;
+               }
+
+               foreach (DataType type in cl.get_base_types ()) {
+                       if (!(type is UnresolvedType)) {
+                               continue;
+                       }
+
+                       var base_node = resolve_node (prop_node.parent, ((UnresolvedType) 
type).unresolved_symbol);
+                       if (base_node != null && base_node.symbol is Interface) {
+                               var base_prop_node = base_node.lookup (prop_node.name);
+                               if (base_prop_node != null && base_prop_node.symbol is Property) {
+                                       var base_property = (Property) base_prop_node.symbol;
+                                       if (base_property.is_abstract || base_property.is_virtual) {
+                                               // found
+                                               return base_prop_node;
+                                       }
+                               }
+                       }
+               }
+
+               return null;
+       }
+
 }


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