diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
index 333897bed..bead8f466 100644
--- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
@@ -24,6 +24,7 @@ using System.Threading;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Refactoring;
+using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using Mono.Cecil;
@@ -397,7 +398,6 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
- #region SetNewModifier
///
/// Sets new modifier if the member hides some other member from a base type.
///
@@ -405,82 +405,34 @@ namespace ICSharpCode.Decompiler.CSharp
void SetNewModifier(EntityDeclaration member)
{
bool addNewModifier = false;
- if (member is IndexerDeclaration) {
- var propertyDef = GetDefinitionFromAnnotation(member) as PropertyDefinition;
- if (propertyDef != null)
- addNewModifier = TypesHierarchyHelpers.FindBaseProperties(propertyDef).Any();
- } else
- addNewModifier = HidesBaseMember(member) == true;
-
- if (addNewModifier)
- member.Modifiers |= Modifiers.New;
- }
-
- IMemberDefinition GetDefinitionFromAnnotation(EntityDeclaration member)
- {
- if (member is TypeDeclaration) {
- return (IMemberDefinition)typeSystem.GetCecil(member.Annotation()?.Type.GetDefinition());
+ var entity = (IEntity)member.GetSymbol();
+ var lookup = new MemberLookup(entity.DeclaringTypeDefinition, entity.ParentAssembly);
+
+ var baseTypes = entity.DeclaringType.GetNonInterfaceBaseTypes().Where(t => entity.DeclaringType != t);
+ if (entity is ITypeDefinition) {
+ addNewModifier = baseTypes.SelectMany(b => b.GetNestedTypes(t => t.Name == entity.Name && lookup.IsAccessible(t, true))).Any();
} else {
- return (IMemberDefinition)typeSystem.GetCecil(member.Annotation()?.Member.MemberDefinition);
- }
- }
-
- bool? HidesBaseMember(EntityDeclaration member)
- {
- var memberDefinition = GetDefinitionFromAnnotation(member);
- if (memberDefinition == null)
- return null;
- var methodDefinition = memberDefinition as MethodDefinition;
- if (methodDefinition != null) {
- bool? hidesByName = HidesByName(memberDefinition, includeBaseMethods: false);
- return hidesByName != true && TypesHierarchyHelpers.FindBaseMethods(methodDefinition).Any();
- } else
- return HidesByName(memberDefinition, includeBaseMethods: true);
- }
-
- ///
- /// Determines whether any base class member has the same name as the given member.
- ///
- /// The derived type's member.
- /// true if names of methods declared in base types should also be checked.
- /// true if any base member has the same name as given member, otherwise false. Returns null on error.
- static bool? HidesByName(IMemberDefinition member, bool includeBaseMethods)
- {
- Debug.Assert(!(member is PropertyDefinition) || !((PropertyDefinition)member).IsIndexer());
-
- if (member.DeclaringType.BaseType != null) {
- var baseTypeRef = member.DeclaringType.BaseType;
- while (baseTypeRef != null) {
- var baseType = baseTypeRef.Resolve();
- if (baseType == null)
- return null;
- if (baseType.HasProperties && AnyIsHiddenBy(baseType.Properties, member, m => !m.IsIndexer()))
- return true;
- if (baseType.HasEvents && AnyIsHiddenBy(baseType.Events, member))
- return true;
- if (baseType.HasFields && AnyIsHiddenBy(baseType.Fields, member))
- return true;
- if (includeBaseMethods && baseType.HasMethods
- && AnyIsHiddenBy(baseType.Methods, member, m => !m.IsSpecialName))
- return true;
- if (baseType.HasNestedTypes && AnyIsHiddenBy(baseType.NestedTypes, member))
- return true;
- baseTypeRef = baseType.BaseType;
+ var members = baseTypes.SelectMany(b => b.GetMembers(m => m.Name == entity.Name).Where(m => lookup.IsAccessible(m, true)));
+ switch (entity.SymbolKind) {
+ case SymbolKind.Field:
+ case SymbolKind.Property:
+ case SymbolKind.Event:
+ addNewModifier = members.Any();
+ break;
+ case SymbolKind.Method:
+ case SymbolKind.Constructor:
+ case SymbolKind.Indexer:
+ case SymbolKind.Operator:
+ addNewModifier = members.Any(m => SignatureComparer.Ordinal.Equals(m, (IMember)entity));
+ break;
+ default:
+ throw new NotSupportedException();
}
}
- return false;
- }
- static bool AnyIsHiddenBy(IEnumerable members, IMemberDefinition derived, Predicate condition = null)
- where T : IMemberDefinition
- {
- int numberOfGenericParameters = (derived as IGenericParameterProvider)?.GenericParameters.Count ?? 0;
- return members.Any(m => m.Name == derived.Name
- && ((m as IGenericParameterProvider)?.GenericParameters.Count ?? 0) == numberOfGenericParameters
- && (condition == null || condition(m))
- && TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType));
+ if (addNewModifier)
+ member.Modifiers |= Modifiers.New;
}
- #endregion
void FixParameterNames(EntityDeclaration entity)
{
@@ -608,9 +560,7 @@ namespace ICSharpCode.Decompiler.CSharp
} else if (!method.IsAbstract && method.DeclaringType.Kind != TypeKind.Interface) {
methodDecl.Modifiers |= Modifiers.Extern;
}
- if (decompilationContext.CurrentTypeDefinition.Kind != TypeKind.Interface
- && method.SymbolKind == SymbolKind.Method
- && methodDefinition.IsVirtual == methodDefinition.IsNewSlot) {
+ if (method.SymbolKind == SymbolKind.Method && !method.IsExplicitInterfaceImplementation && methodDefinition.IsVirtual == methodDefinition.IsNewSlot) {
SetNewModifier(methodDecl);
}
return methodDecl;
@@ -685,7 +635,7 @@ namespace ICSharpCode.Decompiler.CSharp
DecompileBody(propertyDefinition.SetMethod, property.Setter, setter, decompilationContext);
}
var accessor = propertyDefinition.GetMethod ?? propertyDefinition.SetMethod;
- if (!accessor.HasOverrides && !accessor.DeclaringType.IsInterface && accessor.IsVirtual == accessor.IsNewSlot)
+ if (!accessor.HasOverrides && accessor.IsVirtual == accessor.IsNewSlot)
SetNewModifier(propertyDecl);
return propertyDecl;
}