Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2016-06-20 15:21:33 +0300
committerMarek Safar <marek.safar@gmail.com>2016-06-20 20:36:41 +0300
commit9bdc135cdf856ac9171a8a7e441a0775b1df51e3 (patch)
treeafe4c256b6f3976a3d2cf06fc77a19705b80a4af
parent587a89e17c038521eaf52866d25affadc52db4ff (diff)
[reflection] Properties always use name and signature hidding rules. Fixes #41874
-rw-r--r--mcs/class/corlib/Test/System/TypeTest.cs59
-rw-r--r--mono/metadata/icall.c19
2 files changed, 71 insertions, 7 deletions
diff --git a/mcs/class/corlib/Test/System/TypeTest.cs b/mcs/class/corlib/Test/System/TypeTest.cs
index 541acb6afb7..3f2d6283fb7 100644
--- a/mcs/class/corlib/Test/System/TypeTest.cs
+++ b/mcs/class/corlib/Test/System/TypeTest.cs
@@ -456,6 +456,65 @@ namespace MonoTests.System
}
+ class GetProperties_Overrides_Input
+ {
+ public class TestClass : BaseClass<object>
+ {
+ public override object TestProperty { get; set; }
+ }
+
+ public abstract class BaseClass<T>
+ {
+ public virtual T TestProperty { get; set; }
+ }
+
+ public class TestClass_Indexer : BaseClass_Indexer<object>
+ {
+ public override object this[int arg] { set { } }
+ }
+
+ public abstract class BaseClass_Indexer<T>
+ {
+ public virtual T this[int arg] { set { } }
+ }
+
+ public interface IB : IA<object>
+ {
+ new object TestProperty { get; set; }
+ }
+
+ public interface IA<T>
+ {
+ T TestProperty { get; set; }
+ }
+
+ public class TestClass_HiddenProperty : BaseClass_HiddenProperty
+ {
+ public new virtual string Prop { set { } }
+ }
+
+ public class BaseClass_HiddenProperty
+ {
+ public virtual string Prop { set { } }
+ }
+ }
+
+ [Test]
+ public void GetProperties_Overrides ()
+ {
+ Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.IB).GetProperties().Length);
+
+ var prop = typeof (GetProperties_Overrides_Input.TestClass).GetProperty ("TestProperty");
+ Assert.AreEqual (typeof (GetProperties_Overrides_Input.TestClass), prop.DeclaringType);
+
+ var prop_2 = typeof (GetProperties_Overrides_Input.TestClass_HiddenProperty).GetProperty ("Prop");
+ Assert.AreEqual (typeof (GetProperties_Overrides_Input.TestClass_HiddenProperty), prop_2.DeclaringType);
+
+ Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass).GetProperties().Length);
+ Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass_Indexer).GetProperties().Length);
+ Assert.AreEqual (1, typeof (GetProperties_Overrides_Input.TestClass_HiddenProperty).GetProperties().Length);
+ }
+
[Test] // GetProperties (BindingFlags)
public void GetProperties_Flags ()
{
diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c
index 6f8827dfb84..3a7706caa6d 100644
--- a/mono/metadata/icall.c
+++ b/mono/metadata/icall.c
@@ -3623,12 +3623,17 @@ property_hash (gconstpointer data)
}
static gboolean
-method_declaring_signatures_equal (MonoMethod *method1, MonoMethod *method2)
+property_accessor_override (MonoMethod *method1, MonoMethod *method2)
{
- if (method1->is_inflated)
- method1 = ((MonoMethodInflated*) method1)->declaring;
- if (method2->is_inflated)
- method2 = ((MonoMethodInflated*) method2)->declaring;
+ if (method1->slot != -1 && method1->slot == method2->slot)
+ return TRUE;
+
+ if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
+ if (method1->is_inflated)
+ method1 = ((MonoMethodInflated*) method1)->declaring;
+ if (method2->is_inflated)
+ method2 = ((MonoMethodInflated*) method2)->declaring;
+ }
return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
}
@@ -3654,10 +3659,10 @@ property_equal (MonoProperty *prop1, MonoProperty *prop2)
the indexer came from method 1 or from method 2, and we
shouldn't conflate them. (Bugzilla 36283)
*/
- if (prop1->get && prop2->get && !method_declaring_signatures_equal (prop1->get, prop2->get))
+ if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
return FALSE;
- if (prop1->set && prop2->set && !method_declaring_signatures_equal (prop1->set, prop2->set))
+ if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
return FALSE;
return TRUE;