]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
girparser: Take in account base property for ConcreteAccessor
authorLuca Bruno <lucabru@src.gnome.org>
Sat, 27 Dec 2014 17:17:32 +0000 (18:17 +0100)
committerEvan Nemerson <evan@nemerson.com>
Sun, 28 Dec 2014 18:35:57 +0000 (10:35 -0800)
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
tests/gir/bug742012.test [new file with mode: 0644]
vala/valagirparser.vala

index 3dab72c1e692a8f01c52a00cee5c7b2b3512b823..a9bd40fe1371da6ef0e617aed68b9f803d412491 100644 (file)
@@ -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 (file)
index 0000000..5ce77a6
--- /dev/null
@@ -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; }
+}
index 9d8ef159c32b12390c2da223e4fae32ae928e5ad..46cdc779186a6fba8b251a6843233a908ca897e6 100644 (file)
@@ -1027,6 +1027,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) {
@@ -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;
+       }
+
 }