730 lines
30 KiB
C#
730 lines
30 KiB
C#
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
|
|
using Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.CSharp.Symbols;
|
|
|
|
internal static class OverriddenOrHiddenMembersHelpers
|
|
{
|
|
internal static OverriddenOrHiddenMembersResult MakeOverriddenOrHiddenMembers(this MethodSymbol member)
|
|
{
|
|
return MakeOverriddenOrHiddenMembersWorker(member);
|
|
}
|
|
|
|
internal static OverriddenOrHiddenMembersResult MakeOverriddenOrHiddenMembers(this PropertySymbol member)
|
|
{
|
|
return MakeOverriddenOrHiddenMembersWorker(member);
|
|
}
|
|
|
|
internal static OverriddenOrHiddenMembersResult MakeOverriddenOrHiddenMembers(this EventSymbol member)
|
|
{
|
|
return MakeOverriddenOrHiddenMembersWorker(member);
|
|
}
|
|
|
|
private static OverriddenOrHiddenMembersResult MakeOverriddenOrHiddenMembersWorker(Symbol member)
|
|
{
|
|
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0034: Invalid comparison between Unknown and I4
|
|
if (!CanOverrideOrHide(member))
|
|
{
|
|
return OverriddenOrHiddenMembersResult.Empty;
|
|
}
|
|
if (member.IsAccessor())
|
|
{
|
|
MethodSymbol methodSymbol = member as MethodSymbol;
|
|
Symbol associatedSymbol = methodSymbol.AssociatedSymbol;
|
|
if ((object)associatedSymbol != null)
|
|
{
|
|
if ((int)associatedSymbol.Kind == 15)
|
|
{
|
|
return MakePropertyAccessorOverriddenOrHiddenMembers(methodSymbol, (PropertySymbol)associatedSymbol);
|
|
}
|
|
return MakeEventAccessorOverriddenOrHiddenMembers(methodSymbol, (EventSymbol)associatedSymbol);
|
|
}
|
|
}
|
|
NamedTypeSymbol containingType = member.ContainingType;
|
|
bool dangerous_IsFromSomeCompilation = member.Dangerous_IsFromSomeCompilation;
|
|
if (containingType.IsInterface)
|
|
{
|
|
return MakeInterfaceOverriddenOrHiddenMembers(member, dangerous_IsFromSomeCompilation);
|
|
}
|
|
FindOverriddenOrHiddenMembers(member, containingType, dangerous_IsFromSomeCompilation, out var hiddenBuilder, out var overriddenMembers);
|
|
ImmutableArray<Symbol> hiddenMembers = hiddenBuilder?.ToImmutableAndFree() ?? ImmutableArray<Symbol>.Empty;
|
|
return OverriddenOrHiddenMembersResult.Create(overriddenMembers, hiddenMembers);
|
|
}
|
|
|
|
private static void FindOverriddenOrHiddenMembers(Symbol member, NamedTypeSymbol containingType, bool memberIsFromSomeCompilation, out ArrayBuilder<Symbol> hiddenBuilder, out ImmutableArray<Symbol> overriddenMembers)
|
|
{
|
|
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
|
|
Symbol currTypeBestMatch = null;
|
|
hiddenBuilder = null;
|
|
Symbol symbol;
|
|
if (!(member is MethodSymbol method))
|
|
{
|
|
if (member is PEPropertySymbol pEPropertySymbol)
|
|
{
|
|
if (!(pEPropertySymbol.GetMethod is PEMethodSymbol { ExplicitlyOverriddenClassMethod: { AssociatedSymbol: PropertySymbol associatedSymbol } }))
|
|
{
|
|
goto IL_00a0;
|
|
}
|
|
symbol = associatedSymbol;
|
|
}
|
|
else
|
|
{
|
|
if (!(member is RetargetingPropertySymbol { GetMethod: RetargetingMethodSymbol { ExplicitlyOverriddenClassMethod: { AssociatedSymbol: PropertySymbol associatedSymbol2 } } }))
|
|
{
|
|
goto IL_00a0;
|
|
}
|
|
symbol = associatedSymbol2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
symbol = KnownOverriddenClassMethod(method);
|
|
}
|
|
goto IL_00a3;
|
|
IL_00a0:
|
|
symbol = null;
|
|
goto IL_00a3;
|
|
IL_00a3:
|
|
Symbol knownOverriddenMember = symbol;
|
|
NamedTypeSymbol baseTypeNoUseSiteDiagnostics = containingType.BaseTypeNoUseSiteDiagnostics;
|
|
while ((object)baseTypeNoUseSiteDiagnostics != null && (object)currTypeBestMatch == null && hiddenBuilder == null)
|
|
{
|
|
FindOverriddenOrHiddenMembersInType(member, memberIsFromSomeCompilation, containingType, knownOverriddenMember, baseTypeNoUseSiteDiagnostics, out currTypeBestMatch, out var _, out hiddenBuilder);
|
|
baseTypeNoUseSiteDiagnostics = baseTypeNoUseSiteDiagnostics.BaseTypeNoUseSiteDiagnostics;
|
|
}
|
|
FindRelatedMembers(member.IsOverride, memberIsFromSomeCompilation, member.Kind, currTypeBestMatch, out overriddenMembers, ref hiddenBuilder);
|
|
}
|
|
|
|
public static Symbol FindFirstHiddenMemberIfAny(Symbol member, bool memberIsFromSomeCompilation)
|
|
{
|
|
FindOverriddenOrHiddenMembers(member, member.ContainingType, memberIsFromSomeCompilation, out var hiddenBuilder, out var _);
|
|
Symbol? result = ((IEnumerable<Symbol>)hiddenBuilder)?.FirstOrDefault();
|
|
hiddenBuilder?.Free();
|
|
return result;
|
|
}
|
|
|
|
private static MethodSymbol KnownOverriddenClassMethod(MethodSymbol method)
|
|
{
|
|
if (!(method is PEMethodSymbol { ExplicitlyOverriddenClassMethod: var explicitlyOverriddenClassMethod }))
|
|
{
|
|
if (!(method is RetargetingMethodSymbol { ExplicitlyOverriddenClassMethod: var explicitlyOverriddenClassMethod2 }))
|
|
{
|
|
return null;
|
|
}
|
|
return explicitlyOverriddenClassMethod2;
|
|
}
|
|
return explicitlyOverriddenClassMethod;
|
|
}
|
|
|
|
private static OverriddenOrHiddenMembersResult MakePropertyAccessorOverriddenOrHiddenMembers(MethodSymbol accessor, PropertySymbol associatedProperty)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Invalid comparison between Unknown and I4
|
|
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003d: Invalid comparison between Unknown and I4
|
|
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
|
|
bool flag = (int)accessor.MethodKind == 11;
|
|
MethodSymbol methodSymbol = null;
|
|
ArrayBuilder<Symbol> builder = null;
|
|
OverriddenOrHiddenMembersResult overriddenOrHiddenMembers = associatedProperty.OverriddenOrHiddenMembers;
|
|
ImmutableArray<Symbol>.Enumerator enumerator = overriddenOrHiddenMembers.HiddenMembers.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if ((int)current.Kind == 15)
|
|
{
|
|
PropertySymbol propertySymbol = (PropertySymbol)current;
|
|
MethodSymbol methodSymbol2 = (flag ? propertySymbol.GetMethod : propertySymbol.SetMethod);
|
|
if ((object)methodSymbol2 != null)
|
|
{
|
|
AccessOrGetInstance(ref builder).Add((Symbol)methodSymbol2);
|
|
}
|
|
}
|
|
}
|
|
if (overriddenOrHiddenMembers.OverriddenMembers.Any())
|
|
{
|
|
PropertySymbol property = (PropertySymbol)overriddenOrHiddenMembers.OverriddenMembers[0];
|
|
MethodSymbol methodSymbol3 = (flag ? property.GetOwnOrInheritedGetMethod() : property.GetOwnOrInheritedSetMethod());
|
|
if ((object)methodSymbol3 != null)
|
|
{
|
|
methodSymbol = methodSymbol3;
|
|
}
|
|
}
|
|
bool accessorIsFromSomeCompilation = accessor.Dangerous_IsFromSomeCompilation;
|
|
ImmutableArray<Symbol> overriddenMembers = ImmutableArray<Symbol>.Empty;
|
|
if ((object)methodSymbol != null && IsOverriddenSymbolAccessible(methodSymbol, accessor.ContainingType) && isAccessorOverride(accessor, methodSymbol))
|
|
{
|
|
FindRelatedMembers(accessor.IsOverride, accessorIsFromSomeCompilation, accessor.Kind, methodSymbol, out overriddenMembers, ref builder);
|
|
}
|
|
ImmutableArray<Symbol> hiddenMembers = builder?.ToImmutableAndFree() ?? ImmutableArray<Symbol>.Empty;
|
|
return OverriddenOrHiddenMembersResult.Create(overriddenMembers, hiddenMembers);
|
|
bool isAccessorOverride(MethodSymbol methodSymbol4, MethodSymbol overriddenAccessor)
|
|
{
|
|
if (accessorIsFromSomeCompilation)
|
|
{
|
|
return MemberSignatureComparer.CSharpAccessorOverrideComparer.Equals(methodSymbol4, overriddenAccessor);
|
|
}
|
|
if (overriddenAccessor.Equals(KnownOverriddenClassMethod(methodSymbol4), (TypeCompareKind)63))
|
|
{
|
|
return true;
|
|
}
|
|
return MemberSignatureComparer.RuntimeSignatureComparer.Equals(methodSymbol4, overriddenAccessor);
|
|
}
|
|
}
|
|
|
|
private static OverriddenOrHiddenMembersResult MakeEventAccessorOverriddenOrHiddenMembers(MethodSymbol accessor, EventSymbol associatedEvent)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Invalid comparison between Unknown and I4
|
|
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0039: Invalid comparison between Unknown and I4
|
|
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
|
|
bool flag = (int)accessor.MethodKind == 5;
|
|
MethodSymbol methodSymbol = null;
|
|
ArrayBuilder<Symbol> builder = null;
|
|
OverriddenOrHiddenMembersResult overriddenOrHiddenMembers = associatedEvent.OverriddenOrHiddenMembers;
|
|
ImmutableArray<Symbol>.Enumerator enumerator = overriddenOrHiddenMembers.HiddenMembers.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if ((int)current.Kind == 5)
|
|
{
|
|
EventSymbol eventSymbol = (EventSymbol)current;
|
|
MethodSymbol methodSymbol2 = (flag ? eventSymbol.AddMethod : eventSymbol.RemoveMethod);
|
|
if ((object)methodSymbol2 != null)
|
|
{
|
|
AccessOrGetInstance(ref builder).Add((Symbol)methodSymbol2);
|
|
}
|
|
}
|
|
}
|
|
if (overriddenOrHiddenMembers.OverriddenMembers.Any())
|
|
{
|
|
MethodSymbol ownOrInheritedAccessor = ((EventSymbol)overriddenOrHiddenMembers.OverriddenMembers[0]).GetOwnOrInheritedAccessor(flag);
|
|
if ((object)ownOrInheritedAccessor != null)
|
|
{
|
|
methodSymbol = ownOrInheritedAccessor;
|
|
}
|
|
}
|
|
bool dangerous_IsFromSomeCompilation = accessor.Dangerous_IsFromSomeCompilation;
|
|
ImmutableArray<Symbol> overriddenMembers = ImmutableArray<Symbol>.Empty;
|
|
if ((object)methodSymbol != null && IsOverriddenSymbolAccessible(methodSymbol, accessor.ContainingType) && (dangerous_IsFromSomeCompilation ? MemberSignatureComparer.CSharpAccessorOverrideComparer.Equals(accessor, methodSymbol) : MemberSignatureComparer.RuntimeSignatureComparer.Equals(accessor, methodSymbol)))
|
|
{
|
|
FindRelatedMembers(accessor.IsOverride, dangerous_IsFromSomeCompilation, accessor.Kind, methodSymbol, out overriddenMembers, ref builder);
|
|
}
|
|
ImmutableArray<Symbol> hiddenMembers = builder?.ToImmutableAndFree() ?? ImmutableArray<Symbol>.Empty;
|
|
return OverriddenOrHiddenMembersResult.Create(overriddenMembers, hiddenMembers);
|
|
}
|
|
|
|
internal static OverriddenOrHiddenMembersResult MakeInterfaceOverriddenOrHiddenMembers(Symbol member, bool memberIsFromSomeCompilation)
|
|
{
|
|
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
|
|
NamedTypeSymbol containingType = member.ContainingType;
|
|
PooledHashSet<NamedTypeSymbol> instance = PooledHashSet<NamedTypeSymbol>.GetInstance();
|
|
PooledHashSet<NamedTypeSymbol> instance2 = PooledHashSet<NamedTypeSymbol>.GetInstance();
|
|
ArrayBuilder<Symbol> builder = null;
|
|
ImmutableArray<NamedTypeSymbol>.Enumerator enumerator = containingType.AllInterfacesNoUseSiteDiagnostics.GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
NamedTypeSymbol current = enumerator.Current;
|
|
if (((HashSet<NamedTypeSymbol>)(object)instance2).Contains(current))
|
|
{
|
|
continue;
|
|
}
|
|
FindOverriddenOrHiddenMembersInType(member, memberIsFromSomeCompilation, containingType, null, current, out var currTypeBestMatch, out var currTypeHasSameKindNonMatch, out var hiddenBuilder);
|
|
bool flag = (object)currTypeBestMatch != null;
|
|
if (flag)
|
|
{
|
|
ImmutableArray<NamedTypeSymbol>.Enumerator enumerator2 = current.AllInterfacesNoUseSiteDiagnostics.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
NamedTypeSymbol current2 = enumerator2.Current;
|
|
((HashSet<NamedTypeSymbol>)(object)instance2).Add(current2);
|
|
}
|
|
AccessOrGetInstance(ref builder).Add(currTypeBestMatch);
|
|
}
|
|
if (hiddenBuilder != null)
|
|
{
|
|
if (!((HashSet<NamedTypeSymbol>)(object)instance).Contains(current))
|
|
{
|
|
if (!flag)
|
|
{
|
|
ImmutableArray<NamedTypeSymbol>.Enumerator enumerator2 = current.AllInterfacesNoUseSiteDiagnostics.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
NamedTypeSymbol current3 = enumerator2.Current;
|
|
((HashSet<NamedTypeSymbol>)(object)instance2).Add(current3);
|
|
}
|
|
}
|
|
AccessOrGetInstance(ref builder).AddRange(hiddenBuilder);
|
|
}
|
|
hiddenBuilder.Free();
|
|
}
|
|
else if (currTypeHasSameKindNonMatch && !flag)
|
|
{
|
|
ImmutableArray<NamedTypeSymbol>.Enumerator enumerator2 = current.AllInterfacesNoUseSiteDiagnostics.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
NamedTypeSymbol current4 = enumerator2.Current;
|
|
((HashSet<NamedTypeSymbol>)(object)instance).Add(current4);
|
|
}
|
|
}
|
|
}
|
|
instance.Free();
|
|
instance2.Free();
|
|
ImmutableArray<Symbol> overriddenMembers = ImmutableArray<Symbol>.Empty;
|
|
if (builder != null)
|
|
{
|
|
ArrayBuilder<Symbol> hiddenBuilder2 = null;
|
|
Enumerator<Symbol> enumerator3 = builder.GetEnumerator();
|
|
while (enumerator3.MoveNext())
|
|
{
|
|
Symbol current5 = enumerator3.Current;
|
|
FindRelatedMembers(member.IsOverride, memberIsFromSomeCompilation, member.Kind, current5, out overriddenMembers, ref hiddenBuilder2);
|
|
}
|
|
builder.Free();
|
|
builder = hiddenBuilder2;
|
|
}
|
|
ImmutableArray<Symbol> hiddenMembers = builder?.ToImmutableAndFree() ?? ImmutableArray<Symbol>.Empty;
|
|
return OverriddenOrHiddenMembersResult.Create(overriddenMembers, hiddenMembers);
|
|
}
|
|
|
|
private static void FindOverriddenOrHiddenMembersInType(Symbol member, bool memberIsFromSomeCompilation, NamedTypeSymbol memberContainingType, Symbol knownOverriddenMember, NamedTypeSymbol currType, out Symbol currTypeBestMatch, out bool currTypeHasSameKindNonMatch, out ArrayBuilder<Symbol> hiddenBuilder)
|
|
{
|
|
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0163: Invalid comparison between Unknown and I4
|
|
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_016c: Invalid comparison between Unknown and I4
|
|
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00d4: Invalid comparison between Unknown and I4
|
|
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00af: Invalid comparison between Unknown and I4
|
|
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00da: Invalid comparison between Unknown and I4
|
|
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
|
|
currTypeBestMatch = null;
|
|
currTypeHasSameKindNonMatch = false;
|
|
hiddenBuilder = null;
|
|
bool flag = false;
|
|
int num = int.MaxValue;
|
|
IEqualityComparer<Symbol> equalityComparer = (memberIsFromSomeCompilation ? MemberSignatureComparer.CSharpCustomModifierOverrideComparer : MemberSignatureComparer.RuntimePlusRefOutSignatureComparer);
|
|
IEqualityComparer<Symbol> equalityComparer2 = (memberIsFromSomeCompilation ? MemberSignatureComparer.CSharpOverrideComparer : MemberSignatureComparer.RuntimeSignatureComparer);
|
|
SymbolKind kind = member.Kind;
|
|
int memberArity = member.GetMemberArity();
|
|
ImmutableArray<Symbol>.Enumerator enumerator = currType.GetMembers(member.Name).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if (!IsOverriddenSymbolAccessible(current, memberContainingType) || (current.IsAccessor() && !((MethodSymbol)current).IsIndexedPropertyAccessor()))
|
|
{
|
|
continue;
|
|
}
|
|
if (current.Kind != kind)
|
|
{
|
|
int memberArity2 = current.GetMemberArity();
|
|
if (memberArity2 == memberArity || ((int)kind == 9 && memberArity2 == 0))
|
|
{
|
|
AddHiddenMemberIfApplicable(ref hiddenBuilder, kind, current);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (flag)
|
|
{
|
|
continue;
|
|
}
|
|
if ((int)kind != 6)
|
|
{
|
|
if ((int)kind == 11)
|
|
{
|
|
if (current.GetMemberArity() == memberArity)
|
|
{
|
|
flag = true;
|
|
currTypeBestMatch = current;
|
|
}
|
|
}
|
|
else if (current.Equals(knownOverriddenMember, (TypeCompareKind)63))
|
|
{
|
|
flag = true;
|
|
currTypeBestMatch = current;
|
|
}
|
|
else
|
|
{
|
|
if (!(knownOverriddenMember == null))
|
|
{
|
|
continue;
|
|
}
|
|
if (equalityComparer.Equals(member, current))
|
|
{
|
|
flag = true;
|
|
currTypeBestMatch = current;
|
|
}
|
|
else if (equalityComparer2.Equals(member, current))
|
|
{
|
|
int num2 = CustomModifierCount(current);
|
|
if (num2 < num)
|
|
{
|
|
num = num2;
|
|
currTypeBestMatch = current;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
currTypeHasSameKindNonMatch = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
flag = true;
|
|
currTypeBestMatch = current;
|
|
}
|
|
}
|
|
}
|
|
if ((int)kind == 6 || (int)kind == 11 || !(flag && memberIsFromSomeCompilation) || !member.IsDefinition || !TypeOrReturnTypeHasCustomModifiers(currTypeBestMatch))
|
|
{
|
|
return;
|
|
}
|
|
Symbol symbol = currTypeBestMatch;
|
|
enumerator = currType.GetMembers(member.Name).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current2 = enumerator.Current;
|
|
if (current2.Kind == currTypeBestMatch.Kind && (object)current2 != currTypeBestMatch && MemberSignatureComparer.CSharpOverrideComparer.Equals(current2, currTypeBestMatch))
|
|
{
|
|
int num3 = CustomModifierCount(current2);
|
|
if (num3 < num)
|
|
{
|
|
num = num3;
|
|
symbol = current2;
|
|
}
|
|
}
|
|
}
|
|
currTypeBestMatch = symbol;
|
|
}
|
|
|
|
private static void FindRelatedMembers(bool isOverride, bool overridingMemberIsFromSomeCompilation, SymbolKind overridingMemberKind, Symbol representativeMember, out ImmutableArray<Symbol> overriddenMembers, ref ArrayBuilder<Symbol> hiddenBuilder)
|
|
{
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0016: Invalid comparison between Unknown and I4
|
|
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0020: Invalid comparison between Unknown and I4
|
|
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
|
|
overriddenMembers = ImmutableArray<Symbol>.Empty;
|
|
if ((object)representativeMember == null)
|
|
{
|
|
return;
|
|
}
|
|
bool flag = (int)representativeMember.Kind != 6 && (int)representativeMember.Kind != 11 && (!representativeMember.ContainingType.IsDefinition || representativeMember.IsIndexer());
|
|
if (isOverride)
|
|
{
|
|
if (flag)
|
|
{
|
|
ArrayBuilder<Symbol> instance = ArrayBuilder<Symbol>.GetInstance();
|
|
instance.Add(representativeMember);
|
|
FindOtherOverriddenMethodsInContainingType(representativeMember, overridingMemberIsFromSomeCompilation, instance);
|
|
overriddenMembers = instance.ToImmutableAndFree();
|
|
}
|
|
else
|
|
{
|
|
overriddenMembers = ImmutableArray.Create(representativeMember);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AddHiddenMemberIfApplicable(ref hiddenBuilder, overridingMemberKind, representativeMember);
|
|
if (flag)
|
|
{
|
|
FindOtherHiddenMembersInContainingType(overridingMemberKind, representativeMember, ref hiddenBuilder);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void AddHiddenMemberIfApplicable(ref ArrayBuilder<Symbol> hiddenBuilder, SymbolKind hidingMemberKind, Symbol hiddenMember)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Invalid comparison between Unknown and I4
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
if ((int)hiddenMember.Kind != 9 || ((MethodSymbol)hiddenMember).CanBeHiddenByMemberKind(hidingMemberKind))
|
|
{
|
|
AccessOrGetInstance(ref hiddenBuilder).Add(hiddenMember);
|
|
}
|
|
}
|
|
|
|
private static ArrayBuilder<T> AccessOrGetInstance<T>(ref ArrayBuilder<T> builder)
|
|
{
|
|
if (builder == null)
|
|
{
|
|
builder = ArrayBuilder<T>.GetInstance();
|
|
}
|
|
return builder;
|
|
}
|
|
|
|
private static void FindOtherOverriddenMethodsInContainingType(Symbol representativeMember, bool overridingMemberIsFromSomeCompilation, ArrayBuilder<Symbol> overriddenBuilder)
|
|
{
|
|
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
|
|
int num = -1;
|
|
ImmutableArray<Symbol>.Enumerator enumerator = representativeMember.ContainingType.GetMembers(representativeMember.Name).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if (current.Kind != representativeMember.Kind || !(current != representativeMember))
|
|
{
|
|
continue;
|
|
}
|
|
if (overridingMemberIsFromSomeCompilation)
|
|
{
|
|
if (num < 0)
|
|
{
|
|
num = representativeMember.CustomModifierCount();
|
|
}
|
|
if (MemberSignatureComparer.CSharpOverrideComparer.Equals(current, representativeMember) && current.CustomModifierCount() == num)
|
|
{
|
|
overriddenBuilder.Add(current);
|
|
}
|
|
}
|
|
else if (MemberSignatureComparer.CSharpCustomModifierOverrideComparer.Equals(current, representativeMember))
|
|
{
|
|
overriddenBuilder.Add(current);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void FindOtherHiddenMembersInContainingType(SymbolKind hidingMemberKind, Symbol representativeMember, ref ArrayBuilder<Symbol> hiddenBuilder)
|
|
{
|
|
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
|
|
IEqualityComparer<Symbol> cSharpCustomModifierOverrideComparer = MemberSignatureComparer.CSharpCustomModifierOverrideComparer;
|
|
ImmutableArray<Symbol>.Enumerator enumerator = representativeMember.ContainingType.GetMembers(representativeMember.Name).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if (current.Kind == representativeMember.Kind && current != representativeMember && cSharpCustomModifierOverrideComparer.Equals(current, representativeMember))
|
|
{
|
|
AddHiddenMemberIfApplicable(ref hiddenBuilder, hidingMemberKind, current);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static bool CanOverrideOrHide(Symbol member)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0009: Invalid comparison between Unknown and I4
|
|
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000e: Invalid comparison between Unknown and I4
|
|
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0013: Invalid comparison between Unknown and I4
|
|
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
|
|
SymbolKind kind = member.Kind;
|
|
if ((int)kind != 5)
|
|
{
|
|
if ((int)kind == 9)
|
|
{
|
|
MethodSymbol methodSymbol = (MethodSymbol)member;
|
|
if (MethodSymbol.CanOverrideOrHide(methodSymbol.MethodKind))
|
|
{
|
|
return (object)methodSymbol == methodSymbol.ConstructedFrom;
|
|
}
|
|
return false;
|
|
}
|
|
if ((int)kind != 15)
|
|
{
|
|
throw ExceptionUtilities.UnexpectedValue((object)member.Kind);
|
|
}
|
|
}
|
|
return !member.IsExplicitInterfaceImplementation();
|
|
}
|
|
|
|
private static bool TypeOrReturnTypeHasCustomModifiers(Symbol member)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000b: Invalid comparison between Unknown and I4
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0014: Invalid comparison between Unknown and I4
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_001a: Invalid comparison between Unknown and I4
|
|
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
|
|
SymbolKind kind = member.Kind;
|
|
if ((int)kind != 5)
|
|
{
|
|
if ((int)kind != 9)
|
|
{
|
|
if ((int)kind == 15)
|
|
{
|
|
PropertySymbol propertySymbol = (PropertySymbol)member;
|
|
TypeWithAnnotations typeWithAnnotations = propertySymbol.TypeWithAnnotations;
|
|
if (!typeWithAnnotations.CustomModifiers.Any() && !propertySymbol.RefCustomModifiers.Any())
|
|
{
|
|
return typeWithAnnotations.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false);
|
|
}
|
|
return true;
|
|
}
|
|
throw ExceptionUtilities.UnexpectedValue((object)member.Kind);
|
|
}
|
|
MethodSymbol methodSymbol = (MethodSymbol)member;
|
|
TypeWithAnnotations returnTypeWithAnnotations = methodSymbol.ReturnTypeWithAnnotations;
|
|
if (!returnTypeWithAnnotations.CustomModifiers.Any() && !methodSymbol.RefCustomModifiers.Any())
|
|
{
|
|
return returnTypeWithAnnotations.Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false);
|
|
}
|
|
return true;
|
|
}
|
|
return ((EventSymbol)member).Type.HasCustomModifiers(flagNonDefaultArraySizesOrLowerBounds: false);
|
|
}
|
|
|
|
private static int CustomModifierCount(Symbol member)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0009: Invalid comparison between Unknown and I4
|
|
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000e: Invalid comparison between Unknown and I4
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0013: Invalid comparison between Unknown and I4
|
|
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
|
|
SymbolKind kind = member.Kind;
|
|
if ((int)kind != 5)
|
|
{
|
|
if ((int)kind != 9)
|
|
{
|
|
if ((int)kind == 15)
|
|
{
|
|
return ((PropertySymbol)member).CustomModifierCount();
|
|
}
|
|
throw ExceptionUtilities.UnexpectedValue((object)member.Kind);
|
|
}
|
|
return ((MethodSymbol)member).CustomModifierCount();
|
|
}
|
|
return ((EventSymbol)member).Type.CustomModifierCount();
|
|
}
|
|
|
|
internal static bool RequiresExplicitOverride(this MethodSymbol method, out bool warnAmbiguous)
|
|
{
|
|
warnAmbiguous = false;
|
|
if (!method.IsOverride)
|
|
{
|
|
return false;
|
|
}
|
|
MethodSymbol overriddenMethod = method.OverriddenMethod;
|
|
if ((object)overriddenMethod == null)
|
|
{
|
|
return false;
|
|
}
|
|
bool wasAmbiguous;
|
|
MethodSymbol firstRuntimeOverriddenMethodIgnoringNewSlot = method.GetFirstRuntimeOverriddenMethodIgnoringNewSlot(out wasAmbiguous);
|
|
if (overriddenMethod == firstRuntimeOverriddenMethodIgnoringNewSlot && !wasAmbiguous)
|
|
{
|
|
return false;
|
|
}
|
|
if (method.ContainingAssembly.RuntimeSupportsCovariantReturnsOfClasses)
|
|
{
|
|
return true;
|
|
}
|
|
if (!method.ReturnType.Equals(overriddenMethod.ReturnType, (TypeCompareKind)63))
|
|
{
|
|
return true;
|
|
}
|
|
if (!overriddenMethod.MethodHasRuntimeCollision())
|
|
{
|
|
return true;
|
|
}
|
|
bool flag = overriddenMethod.IsDefinition || overriddenMethod.OriginalDefinition.MethodHasRuntimeCollision();
|
|
warnAmbiguous = !flag;
|
|
if (!overriddenMethod.ContainingType.Equals(firstRuntimeOverriddenMethodIgnoringNewSlot.ContainingType, (TypeCompareKind)62))
|
|
{
|
|
return true;
|
|
}
|
|
if (overriddenMethod != firstRuntimeOverriddenMethodIgnoringNewSlot)
|
|
{
|
|
return method.IsAccessor() != firstRuntimeOverriddenMethodIgnoringNewSlot.IsAccessor();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
internal static bool MethodHasRuntimeCollision(this MethodSymbol method)
|
|
{
|
|
ImmutableArray<Symbol>.Enumerator enumerator = method.ContainingType.GetMembers(method.Name).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if (current != method && MemberSignatureComparer.RuntimeSignatureComparer.Equals(current, method))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
internal static MethodSymbol GetFirstRuntimeOverriddenMethodIgnoringNewSlot(this MethodSymbol method, out bool wasAmbiguous)
|
|
{
|
|
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0052: Invalid comparison between Unknown and I4
|
|
wasAmbiguous = false;
|
|
if (!method.IsMetadataVirtual(ignoreInterfaceImplementationChanges: true) || method.IsStatic)
|
|
{
|
|
return null;
|
|
}
|
|
NamedTypeSymbol containingType = method.ContainingType;
|
|
NamedTypeSymbol baseTypeNoUseSiteDiagnostics = containingType.BaseTypeNoUseSiteDiagnostics;
|
|
while ((object)baseTypeNoUseSiteDiagnostics != null)
|
|
{
|
|
MethodSymbol methodSymbol = null;
|
|
ImmutableArray<Symbol>.Enumerator enumerator = baseTypeNoUseSiteDiagnostics.GetMembers(method.Name).GetEnumerator();
|
|
while (enumerator.MoveNext())
|
|
{
|
|
Symbol current = enumerator.Current;
|
|
if ((int)current.Kind != 9 || !IsOverriddenSymbolAccessible(current, containingType) || !MemberSignatureComparer.RuntimeSignatureComparer.Equals(method, current))
|
|
{
|
|
continue;
|
|
}
|
|
MethodSymbol methodSymbol2 = (MethodSymbol)current;
|
|
if (methodSymbol2.IsMetadataVirtual(ignoreInterfaceImplementationChanges: true))
|
|
{
|
|
if ((object)methodSymbol != null)
|
|
{
|
|
wasAmbiguous = true;
|
|
return methodSymbol;
|
|
}
|
|
methodSymbol = methodSymbol2;
|
|
}
|
|
}
|
|
if ((object)methodSymbol != null)
|
|
{
|
|
return methodSymbol;
|
|
}
|
|
baseTypeNoUseSiteDiagnostics = baseTypeNoUseSiteDiagnostics.BaseTypeNoUseSiteDiagnostics;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static bool IsOverriddenSymbolAccessible(Symbol overridden, NamedTypeSymbol overridingContainingType)
|
|
{
|
|
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
|
|
CompoundUseSiteInfo<AssemblySymbol> useSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
|
|
return AccessCheck.IsSymbolAccessible(overridden.OriginalDefinition, overridingContainingType.OriginalDefinition, ref useSiteInfo);
|
|
}
|
|
}
|