From: Luca Bruno Date: Tue, 24 Jan 2012 13:29:44 +0000 (+0100) Subject: Allow specialization of generic properties X-Git-Tag: 0.15.1~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=556a22f808de35dbdfd510c287de1f5f3806f60a;p=thirdparty%2Fvala.git Allow specialization of generic properties Fixes bug 667668. --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 931db3315..119f1f836 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 000000000..8f760c7be --- /dev/null +++ b/tests/objects/bug667668.vala @@ -0,0 +1,13 @@ +public abstract class Foo : Object { + public abstract G foo { get; set; } +} + +public class Bar : Foo { + public override string foo { get; set; } +} + +void main () { + var bar = new Bar (); + bar.foo = "foo"; + assert (bar.foo == "foo"); +} diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index 7816020f7..150275879 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -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; }