1c7820775b1639159d0defce453622eb31d890b1
[platform/upstream/dotnet/runtime.git] /
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 using System.Collections.Generic;
6 using RuntimeTypeInfo = System.Reflection.TypeLoading.RoType;
7
8 namespace System.Reflection.Runtime.BindingFlagSupport
9 {
10     /// <summary>
11     /// Policies for properties.
12     /// </summary>
13     internal sealed class PropertyPolicies : MemberPolicies<PropertyInfo>
14     {
15         public sealed override IEnumerable<PropertyInfo> GetDeclaredMembers(TypeInfo typeInfo)
16         {
17             return typeInfo.DeclaredProperties;
18         }
19
20         public sealed override IEnumerable<PropertyInfo> CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter filter, RuntimeTypeInfo reflectedType)
21         {
22             return type.GetPropertiesCore(filter, reflectedType);
23         }
24
25         public sealed override bool AlwaysTreatAsDeclaredOnly => false;
26
27         public sealed override void GetMemberAttributes(PropertyInfo member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot)
28         {
29             MethodInfo accessorMethod = GetAccessorMethod(member);
30             if (accessorMethod == null)
31             {
32                 // If we got here, this is a inherited PropertyInfo that only had private accessors and is now refusing to give them out
33                 // because that's what the rules of inherited PropertyInfo's are. Such a PropertyInfo is also considered private and will never be
34                 // given out of a Type.GetProperty() call. So all we have to do is set its visibility to Private and it will get filtered out.
35                 // Other values need to be set to satisfy C# but they are meaningless.
36                 visibility = MethodAttributes.Private;
37                 isStatic = false;
38                 isVirtual = false;
39                 isNewSlot = true;
40                 return;
41             }
42
43             MethodAttributes methodAttributes = accessorMethod.Attributes;
44             visibility = methodAttributes & MethodAttributes.MemberAccessMask;
45             isStatic = (0 != (methodAttributes & MethodAttributes.Static));
46             isVirtual = (0 != (methodAttributes & MethodAttributes.Virtual));
47             isNewSlot = (0 != (methodAttributes & MethodAttributes.NewSlot));
48         }
49
50         public sealed override bool ImplicitlyOverrides(PropertyInfo baseMember, PropertyInfo derivedMember)
51         {
52             MethodInfo baseAccessor = GetAccessorMethod(baseMember);
53             MethodInfo derivedAccessor = GetAccessorMethod(derivedMember);
54             return MemberPolicies<MethodInfo>.Default.ImplicitlyOverrides(baseAccessor, derivedAccessor);
55         }
56
57         //
58         // .NET Framework compat: Properties hide properties in base types if they share the same vtable slot, or
59         // have the same name, return type, signature and hasThis value.
60         //
61         public sealed override bool IsSuppressedByMoreDerivedMember(PropertyInfo member, PropertyInfo[] priorMembers, int startIndex, int endIndex)
62         {
63             MethodInfo baseAccessor = GetAccessorMethod(member);
64             for (int i = startIndex; i < endIndex; i++)
65             {
66                 PropertyInfo prior = priorMembers[i];
67                 MethodInfo derivedAccessor = GetAccessorMethod(prior);
68                 if (!AreNamesAndSignaturesEqual(baseAccessor, derivedAccessor))
69                     continue;
70                 if (derivedAccessor.IsStatic != baseAccessor.IsStatic)
71                     continue;
72                 if (!(prior.PropertyType.Equals(member.PropertyType)))
73                     continue;
74
75                 return true;
76             }
77             return false;
78         }
79
80         public sealed override bool OkToIgnoreAmbiguity(PropertyInfo m1, PropertyInfo m2)
81         {
82             return false;
83         }
84
85         private MethodInfo GetAccessorMethod(PropertyInfo property)
86         {
87             MethodInfo accessor = property.GetMethod;
88             if (accessor == null)
89             {
90                 accessor = property.SetMethod;
91             }
92
93             return accessor;
94         }
95     }
96 }