]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Allow specialization of generic properties
authorLuca Bruno <lucabru@src.gnome.org>
Tue, 24 Jan 2012 13:29:44 +0000 (14:29 +0100)
committerLuca Bruno <lucabru@src.gnome.org>
Tue, 24 Jan 2012 13:29:44 +0000 (14:29 +0100)
Fixes bug 667668.

tests/Makefile.am
tests/objects/bug667668.vala [new file with mode: 0644]
vala/valaproperty.vala

index 931db331573046b8f8f92a23be5d64f0b28296bb..119f1f836dcca4ba1f2db0c31f9bfb132a62eff4 100644 (file)
@@ -123,6 +123,7 @@ TESTS = \
        objects/bug654702.vala \
        objects/bug663134.vala \
        objects/bug664529.vala \
+       objects/bug667668.vala \
        errors/errors.vala \
        errors/bug567181.vala \
        errors/bug579101.vala \
diff --git a/tests/objects/bug667668.vala b/tests/objects/bug667668.vala
new file mode 100644 (file)
index 0000000..8f760c7
--- /dev/null
@@ -0,0 +1,13 @@
+public abstract class Foo<G> : Object {
+       public abstract G foo { get; set; }
+}
+
+public class Bar : Foo<string> {
+       public override string foo { get; set; }
+}
+
+void main () {
+       var bar = new Bar ();
+       bar.foo = "foo";
+       assert (bar.foo == "foo");
+}
index 7816020f7fed4618cdaa9404fa987aad2a1e313b..1502758791d82a31991423f04a01db92cc9bb216 100644 (file)
@@ -189,28 +189,34 @@ public class Vala.Property : Symbol, Lockable {
        }
        
        /**
-        * Checks whether the accessors and type of the specified property
-        * matches this property.
+        * Checks whether the accessors of this property are compatible
+        * with the specified base property.
         *
-        * @param prop a property
-        * @return     true if the specified property is compatible to this
-        *             property
+        * @param base_property a property
+        * @param invalid_match error string about which check failed
+        * @return true if the specified property is compatible to this property
         */
-       public bool equals (Property prop2) {
-               if ((get_accessor == null && prop2.get_accessor != null) ||
-                   (get_accessor != null && prop2.get_accessor == null)) {
+       public bool compatible (Property base_property, out string? invalid_match) {
+               if ((get_accessor == null && base_property.get_accessor != null) ||
+                   (get_accessor != null && base_property.get_accessor == null)) {
+                       invalid_match = "incompatible get accessor";
                        return false;
                }
 
-               if ((set_accessor == null && prop2.set_accessor != null) ||
-                   (set_accessor != null && prop2.set_accessor == null)) {
+               if ((set_accessor == null && base_property.set_accessor != null) ||
+                   (set_accessor != null && base_property.set_accessor == null)) {
+                       invalid_match = "incompatible set accessor";
                        return false;
                }
 
+               var object_type = CodeContext.get().analyzer.get_data_type_for_symbol ((TypeSymbol) parent_symbol);
+
                if (get_accessor != null) {
                        // check accessor value_type instead of property_type
                        // due to possible ownership differences
-                       if (!prop2.get_accessor.value_type.equals (get_accessor.value_type)) {
+                       var actual_base_type = base_property.get_accessor.value_type.get_actual_type (object_type, null, this);
+                       if (!actual_base_type.equals (get_accessor.value_type)) {
+                               invalid_match = "incompatible get accessor type";
                                return false;
                        }
                }
@@ -218,14 +224,18 @@ public class Vala.Property : Symbol, Lockable {
                if (set_accessor != null) {
                        // check accessor value_type instead of property_type
                        // due to possible ownership differences
-                       if (!prop2.set_accessor.value_type.equals (set_accessor.value_type)) {
+                       var actual_base_type = base_property.set_accessor.value_type.get_actual_type (object_type, null, this);
+                       if (!actual_base_type.equals (set_accessor.value_type)) {
+                               invalid_match = "incompatible set accessor type";
                                return false;
                        }
 
-                       if (set_accessor.writable != prop2.set_accessor.writable) {
+                       if (set_accessor.writable != base_property.set_accessor.writable) {
+                               invalid_match = "incompatible set accessor";
                                return false;
                        }
-                       if (set_accessor.construction != prop2.set_accessor.construction) {
+                       if (set_accessor.construction != base_property.set_accessor.construction) {
+                               invalid_match = "incompatible set accessor";
                                return false;
                        }
                }
@@ -263,9 +273,10 @@ public class Vala.Property : Symbol, Lockable {
                if (sym is Property) {
                        var base_property = (Property) sym;
                        if (base_property.is_abstract || base_property.is_virtual) {
-                               if (!equals (base_property)) {
+                               string invalid_match;
+                               if (!compatible (base_property, out invalid_match)) {
                                        error = true;
-                                       Report.error (source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s'.".printf (get_full_name (), base_property.get_full_name ()));
+                                       Report.error (source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s': %s.".printf (get_full_name (), base_property.get_full_name (), invalid_match));
                                        return;
                                }
 
@@ -287,9 +298,10 @@ public class Vala.Property : Symbol, Lockable {
                                if (sym is Property) {
                                        var base_property = (Property) sym;
                                        if (base_property.is_abstract) {
-                                               if (!equals (base_property)) {
+                                               string invalid_match;
+                                               if (!compatible (base_property, out invalid_match)) {
                                                        error = true;
-                                                       Report.error (source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s'.".printf (get_full_name (), base_property.get_full_name ()));
+                                                       Report.error (source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s': %s.".printf (get_full_name (), base_property.get_full_name (), invalid_match));
                                                        return;
                                                }