diff --git a/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/ICSharpCode.Decompiler/Ast/AstBuilder.cs index d6fe56def..b4860eb7d 100644 --- a/ICSharpCode.Decompiler/Ast/AstBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstBuilder.cs @@ -232,7 +232,9 @@ namespace ICSharpCode.Decompiler.Ast foreach (TypeDefinition nestedTypeDef in typeDef.NestedTypes) { if (MemberIsHidden(nestedTypeDef, context.Settings)) continue; - astType.AddChild(CreateType(nestedTypeDef), TypeDeclaration.MemberRole); + var nestedType = CreateType(nestedTypeDef); + SetNewModifier(nestedType); + astType.AddChild(nestedType, TypeDeclaration.MemberRole); } AttributedNode result = astType; @@ -627,7 +629,7 @@ namespace ICSharpCode.Decompiler.Ast // Create mapping - used in debugger MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings); - MethodDeclaration astMethod = new MethodDeclaration(); + MethodDeclaration astMethod = new MethodDeclaration().WithAnnotation(methodMapping); astMethod.AddAnnotation(methodDef); astMethod.ReturnType = ConvertType(methodDef.ReturnType, methodDef.MethodReturnType); astMethod.Name = CleanName(methodDef.Name); @@ -638,14 +640,8 @@ namespace ICSharpCode.Decompiler.Ast if (!methodDef.DeclaringType.IsInterface) { if (!methodDef.HasOverrides) { astMethod.Modifiers = ConvertModifiers(methodDef); - if (methodDef.IsVirtual ^ !methodDef.IsNewSlot) { - try { - if (TypesHierarchyHelpers.FindBaseMethods(methodDef).Any()) - astMethod.Modifiers |= Modifiers.New; - } catch (ReferenceResolvingException) { - // TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references. - } - } + if (methodDef.IsVirtual == methodDef.IsNewSlot) + SetNewModifier(astMethod); } else { astMethod.PrivateImplementationType = ConvertType(methodDef.Overrides.First().DeclaringType); } @@ -675,7 +671,6 @@ namespace ICSharpCode.Decompiler.Ast return op; } } - astMethod.WithAnnotation(methodMapping); return astMethod; } @@ -775,10 +770,6 @@ namespace ICSharpCode.Decompiler.Ast } } } - if (accessor.IsVirtual ^ !accessor.IsNewSlot) { - if (TypesHierarchyHelpers.FindBaseProperties(propDef).Any()) - astProp.Modifiers |= Modifiers.New; - } } catch (ReferenceResolvingException) { // TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references. } @@ -791,7 +782,7 @@ namespace ICSharpCode.Decompiler.Ast astProp.Getter = new Accessor(); astProp.Getter.Body = CreateMethodBody(propDef.GetMethod); - astProp.AddAnnotation(propDef.GetMethod); + astProp.Getter.AddAnnotation(propDef.GetMethod); ConvertAttributes(astProp.Getter, propDef.GetMethod); if ((getterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask)) @@ -815,11 +806,14 @@ namespace ICSharpCode.Decompiler.Ast astProp.Setter.WithAnnotation(methodMapping); } ConvertCustomAttributes(astProp, propDef); - + + MemberDeclaration member = astProp; if(propDef.IsIndexer()) - return ConvertPropertyToIndexer(astProp, propDef); - else - return astProp; + member = ConvertPropertyToIndexer(astProp, propDef); + if(!accessor.HasOverrides && !accessor.DeclaringType.IsInterface) + if (accessor.IsVirtual == accessor.IsNewSlot) + SetNewModifier(member); + return member; } IndexerDeclaration ConvertPropertyToIndexer(PropertyDeclaration astProp, PropertyDefinition propDef) @@ -882,9 +876,8 @@ namespace ICSharpCode.Decompiler.Ast astEvent.RemoveAccessor.WithAnnotation(methodMapping); } MethodDefinition accessor = eventDef.AddMethod ?? eventDef.RemoveMethod; - if (accessor.IsVirtual ^ !accessor.IsNewSlot) { - if (TypesHierarchyHelpers.FindBaseMethods(accessor).Any()) - astEvent.Modifiers |= Modifiers.New; + if (accessor.IsVirtual == accessor.IsNewSlot) { + SetNewModifier(astEvent); } return astEvent; } @@ -912,6 +905,7 @@ namespace ICSharpCode.Decompiler.Ast initializer.Initializer = CreateExpressionForConstant(fieldDef.Constant, fieldDef.FieldType, fieldDef.DeclaringType.IsEnum); } ConvertAttributes(astField, fieldDef); + SetNewModifier(astField); return astField; } @@ -1379,6 +1373,83 @@ namespace ICSharpCode.Decompiler.Ast return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute"); } + + /// + /// Sets new modifier if the member hides some other member from a base type. + /// + /// The node of the member which new modifier state should be determined. + static void SetNewModifier(AttributedNode member) + { + try { + bool addNewModifier = false; + if (member is IndexerDeclaration) { + var propertyDef = member.Annotation(); + var baseProperties = + TypesHierarchyHelpers.FindBaseProperties(propertyDef); + addNewModifier = baseProperties.Any(); + } else + addNewModifier = HidesBaseMember(member); + + if (addNewModifier) + member.Modifiers |= Modifiers.New; + } + catch (ReferenceResolvingException) { + // TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references. + } + } + + private static bool HidesBaseMember(AttributedNode member) + { + var memberDefinition = member.Annotation(); + bool addNewModifier = false; + var methodDefinition = memberDefinition as MethodDefinition; + if (methodDefinition != null) { + addNewModifier = HidesByName(memberDefinition, includeBaseMethods: false); + if (!addNewModifier) + addNewModifier = TypesHierarchyHelpers.FindBaseMethods(methodDefinition).Any(); + } else + addNewModifier = HidesByName(memberDefinition, includeBaseMethods: true); + return addNewModifier; + } + + /// + /// 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. + 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.ResolveOrThrow(); + 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; + } + } + return false; + } + + static bool AnyIsHiddenBy(IEnumerable members, IMemberDefinition derived, Predicate condition = null) + where T : IMemberDefinition + { + return members.Any(m => m.Name == derived.Name + && (condition == null || condition(m)) + && TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType)); + } /// /// diff --git a/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs b/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs index ca1d72f8f..a7cd35a30 100644 --- a/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs +++ b/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs @@ -27,6 +27,13 @@ namespace ICSharpCode.Decompiler.Ast } } + /// + /// Determines whether one method overrides or hides another method. + /// + /// The method declared in a base type. + /// The method declared in a derived type. + /// true if hides or overrides , + /// otherwise false. public static bool IsBaseMethod(MethodDefinition parentMethod, MethodDefinition childMethod) { if (parentMethod == null) @@ -44,6 +51,13 @@ namespace ICSharpCode.Decompiler.Ast return FindBaseMethods(childMethod).Any(m => m == parentMethod);// || (parentMethod.HasGenericParameters && m.); } + /// + /// Determines whether a property overrides or hides another property. + /// + /// The property declared in a base type. + /// The property declared in a derived type. + /// true if the hides or overrides , + /// otherwise false. public static bool IsBaseProperty(PropertyDefinition parentProperty, PropertyDefinition childProperty) { if (parentProperty == null) @@ -69,6 +83,11 @@ namespace ICSharpCode.Decompiler.Ast return FindBaseEvents(childEvent).Any(m => m == parentEvent); } + /// + /// Finds all methods from base types overridden or hidden by the specified method. + /// + /// The method which overrides or hides methods from base types. + /// Methods overriden or hidden by the specified method. public static IEnumerable FindBaseMethods(MethodDefinition method) { if (method == null) @@ -79,30 +98,41 @@ namespace ICSharpCode.Decompiler.Ast foreach (var baseType in BaseTypes(method.DeclaringType)) foreach (var baseMethod in baseType.Item.Methods) - if (MatchMethod(baseType.ApplyTo(baseMethod), gMethod) && IsVisbleFrom(baseMethod, method)) { + if (MatchMethod(baseType.ApplyTo(baseMethod), gMethod) && IsVisibleFromDerived(baseMethod, method.DeclaringType)) { yield return baseMethod; - if (!(baseMethod.IsNewSlot ^ baseMethod.IsVirtual)) + if (baseMethod.IsNewSlot == baseMethod.IsVirtual) yield break; } } - public static IEnumerable FindBaseProperties(PropertyDefinition property, bool ignoreResolveExceptions = false) + /// + /// Finds all properties from base types overridden or hidden by the specified property. + /// + /// The property which overrides or hides properties from base types. + /// Properties overriden or hidden by the specified property. + public static IEnumerable FindBaseProperties(PropertyDefinition property) { if (property == null) throw new ArgumentNullException("property"); + if ((property.GetMethod ?? property.SetMethod).HasOverrides) + yield break; + var typeContext = CreateGenericContext(property.DeclaringType); var gProperty = typeContext.ApplyTo(property); + bool isIndexer = property.IsIndexer(); foreach (var baseType in BaseTypes(property.DeclaringType)) foreach (var baseProperty in baseType.Item.Properties) - if (MatchProperty(baseType.ApplyTo(baseProperty), gProperty) && IsVisbleFrom(baseProperty, property)) { + if (MatchProperty(baseType.ApplyTo(baseProperty), gProperty) + && IsVisibleFromDerived(baseProperty, property.DeclaringType)) { + if (isIndexer != baseProperty.IsIndexer()) + continue; yield return baseProperty; var anyPropertyAccessor = baseProperty.GetMethod ?? baseProperty.SetMethod; - if (!(anyPropertyAccessor.IsNewSlot ^ anyPropertyAccessor.IsVirtual)) + if (anyPropertyAccessor.IsNewSlot == anyPropertyAccessor.IsVirtual) yield break; } - } public static IEnumerable FindBaseEvents(EventDefinition eventDef) @@ -115,40 +145,78 @@ namespace ICSharpCode.Decompiler.Ast foreach (var baseType in BaseTypes(eventDef.DeclaringType)) foreach (var baseEvent in baseType.Item.Events) - if (MatchEvent(baseType.ApplyTo(baseEvent), gEvent) && IsVisbleFrom(baseEvent, eventDef)) { + if (MatchEvent(baseType.ApplyTo(baseEvent), gEvent) && IsVisibleFromDerived(baseEvent, eventDef.DeclaringType)) { yield return baseEvent; var anyEventAccessor = baseEvent.AddMethod ?? baseEvent.RemoveMethod; - if (!(anyEventAccessor.IsNewSlot ^ anyEventAccessor.IsVirtual)) + if (anyEventAccessor.IsNewSlot == anyEventAccessor.IsVirtual) yield break; } } - private static bool IsVisbleFrom(MethodDefinition baseCandidate, MethodDefinition method) + /// + /// Determinates whether member of the base type is visible from a derived type. + /// + /// The member which visibility is checked. + /// The derived type. + /// true if the member is visible from derived type, othewise false. + public static bool IsVisibleFromDerived(IMemberDefinition baseMember, TypeDefinition derivedType) { - if (baseCandidate.IsPrivate) - return false; - if ((baseCandidate.IsAssembly || baseCandidate.IsFamilyAndAssembly) && baseCandidate.Module != method.Module) + if (baseMember == null) + throw new ArgumentNullException("baseMember"); + if (derivedType == null) + throw new ArgumentNullException("derivedType"); + + var visibility = IsVisibleFromDerived(baseMember); + if (visibility.HasValue) + return visibility.Value; + + if (baseMember.DeclaringType.Module == derivedType.Module) + return true; + // TODO: Check also InternalsVisibleToAttribute. return false; - return true; } - private static bool IsVisbleFrom(PropertyDefinition baseCandidate, PropertyDefinition property) + private static bool? IsVisibleFromDerived(IMemberDefinition member) { - if (baseCandidate.GetMethod != null && property.GetMethod != null && IsVisbleFrom(baseCandidate.GetMethod, property.GetMethod)) - return true; - if (baseCandidate.SetMethod != null && property.SetMethod != null && IsVisbleFrom(baseCandidate.SetMethod, property.SetMethod)) + MethodAttributes attrs = GetAccessAttributes(member) & MethodAttributes.MemberAccessMask; + if (attrs == MethodAttributes.Private) + return false; + if (attrs == MethodAttributes.Assembly || attrs == MethodAttributes.FamANDAssem) + return null; return true; - return false; } - private static bool IsVisbleFrom(EventDefinition baseCandidate, EventDefinition eventDef) + private static MethodAttributes GetAccessAttributes(IMemberDefinition member) { - if (baseCandidate.AddMethod != null && eventDef.AddMethod != null && IsVisbleFrom(baseCandidate.AddMethod, eventDef.AddMethod)) - return true; - if (baseCandidate.RemoveMethod != null && eventDef.RemoveMethod != null && IsVisbleFrom(baseCandidate.RemoveMethod, eventDef.RemoveMethod)) - return true; - return false; + var fld = member as FieldDefinition; + if (fld != null) + return (MethodAttributes)fld.Attributes; + + var method = member as MethodDefinition; + if (method != null) + return method.Attributes; + + var prop = member as PropertyDefinition; + if (prop != null) { + return (prop.GetMethod ?? prop.SetMethod).Attributes; + } + + var evnt = member as EventDefinition; + if (evnt != null) { + return (evnt.AddMethod ?? evnt.RemoveMethod).Attributes; + } + + var nestedType = member as TypeDefinition; + if (nestedType != null) { + if (nestedType.IsNestedPrivate) + return MethodAttributes.Private; + if (nestedType.IsNestedAssembly || nestedType.IsNestedFamilyAndAssembly) + return MethodAttributes.Assembly; + return MethodAttributes.Public; + } + + throw new NotSupportedException(); } private static bool MatchMethod(GenericContext candidate, GenericContext method) @@ -161,7 +229,7 @@ namespace ICSharpCode.Decompiler.Ast if (mCandidate.HasOverrides) return false; - if (!IsSameType(candidate.ResolveWithContext(mCandidate.ReturnType), method.ResolveWithContext(mMethod.ReturnType))) + if (mCandidate.IsSpecialName != method.Item.IsSpecialName) return false; if (mCandidate.HasGenericParameters || mMethod.HasGenericParameters) { @@ -208,9 +276,6 @@ namespace ICSharpCode.Decompiler.Ast if ((mCandidate.GetMethod ?? mCandidate.SetMethod).HasOverrides) return false; - if (!IsSameType(candidate.ResolveWithContext(mCandidate.PropertyType), property.ResolveWithContext(mProperty.PropertyType))) - return false; - if (mCandidate.HasParameters || mProperty.HasParameters) { if (!mCandidate.HasParameters || !mProperty.HasParameters || mCandidate.Parameters.Count != mProperty.Parameters.Count) return false; @@ -242,6 +307,9 @@ namespace ICSharpCode.Decompiler.Ast private static bool MatchParameters(GenericContext baseParameterType, GenericContext parameterType) { + if (baseParameterType.Item.IsIn != parameterType.Item.IsIn || + baseParameterType.Item.IsOut != parameterType.Item.IsOut) + return false; var baseParam = baseParameterType.ResolveWithContext(baseParameterType.Item.ParameterType); var param = parameterType.ResolveWithContext(parameterType.Item.ParameterType); return IsSameType(baseParam, param); @@ -254,8 +322,12 @@ namespace ICSharpCode.Decompiler.Ast if (tr1 == null || tr2 == null) return false; + if (tr1.GetType() != tr2.GetType()) + return false; + if (tr1.Name == tr2.Name && tr1.FullName == tr2.FullName) return true; + return false; } @@ -288,6 +360,10 @@ namespace ICSharpCode.Decompiler.Ast struct GenericContext where T : class { private static readonly ReadOnlyCollection Empty = new ReadOnlyCollection(new List()); + private static readonly GenericParameter UnresolvedGenericTypeParameter = + new DummyGenericParameterProvider(false).DummyParameter; + private static readonly GenericParameter UnresolvedGenericMethodParameter = + new DummyGenericParameterProvider(true).DummyParameter; public readonly T Item; public readonly ReadOnlyCollection TypeArguments; @@ -324,28 +400,99 @@ namespace ICSharpCode.Decompiler.Ast public TypeReference ResolveWithContext(TypeReference type) { var genericParameter = type as GenericParameter; - if (genericParameter != null && genericParameter.Owner.GenericParameterType == GenericParameterType.Type) { + if (genericParameter != null) + if (genericParameter.Owner.GenericParameterType == GenericParameterType.Type) return this.TypeArguments[genericParameter.Position]; + else + return genericParameter.Owner.GenericParameterType == GenericParameterType.Type + ? UnresolvedGenericTypeParameter : UnresolvedGenericMethodParameter; + var typeSpecification = type as TypeSpecification; + if (typeSpecification != null) { + var resolvedElementType = ResolveWithContext(typeSpecification.ElementType); + return ReplaceElementType(typeSpecification, resolvedElementType); } - var arrayType = type as ArrayType; + return type.ResolveOrThrow(); + } + + private TypeReference ReplaceElementType(TypeSpecification ts, TypeReference newElementType) + { + var arrayType = ts as ArrayType; if (arrayType != null) { - var resolvedElementType = ResolveWithContext(arrayType.ElementType); - if (resolvedElementType == null) - return null; - if (resolvedElementType == arrayType.ElementType) + if (newElementType == arrayType.ElementType) return arrayType; - var newArrayType = new ArrayType(resolvedElementType, arrayType.Rank); + var newArrayType = new ArrayType(newElementType, arrayType.Rank); for (int dimension = 0; dimension < arrayType.Rank; dimension++) newArrayType.Dimensions[dimension] = arrayType.Dimensions[dimension]; return newArrayType; } - return type.ResolveOrThrow(); + var byReferenceType = ts as ByReferenceType; + if (byReferenceType != null) { + return new ByReferenceType(newElementType); + } + // TODO: should we throw an exception instead calling Resolve method? + return ts.ResolveOrThrow(); } public GenericContext ApplyTo(T2 item) where T2 : class { return new GenericContext(item, this.TypeArguments); } + + private class DummyGenericParameterProvider : IGenericParameterProvider + { + readonly Mono.Cecil.GenericParameterType type; + readonly Mono.Collections.Generic.Collection parameters; + + public DummyGenericParameterProvider(bool methodTypeParameter) + { + type = methodTypeParameter ? Mono.Cecil.GenericParameterType.Method : + Mono.Cecil.GenericParameterType.Type; + parameters = new Mono.Collections.Generic.Collection(1); + parameters.Add(new GenericParameter(this)); + } + + public GenericParameter DummyParameter + { + get { return parameters[0]; } + } + + bool IGenericParameterProvider.HasGenericParameters + { + get { throw new NotImplementedException(); } + } + + bool IGenericParameterProvider.IsDefinition + { + get { throw new NotImplementedException(); } + } + + ModuleDefinition IGenericParameterProvider.Module + { + get { throw new NotImplementedException(); } + } + + Mono.Collections.Generic.Collection IGenericParameterProvider.GenericParameters + { + get { return parameters; } + } + + GenericParameterType IGenericParameterProvider.GenericParameterType + { + get { return type; } + } + + MetadataToken IMetadataTokenProvider.MetadataToken + { + get + { + throw new NotImplementedException(); + } + set + { + throw new NotImplementedException(); + } + } + } } } } diff --git a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj index 90a2db494..b4906c60f 100644 --- a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj @@ -69,7 +69,7 @@ - + @@ -107,4 +107,4 @@ - + \ No newline at end of file diff --git a/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs b/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs index 401bfab61..22458bcfc 100644 --- a/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs +++ b/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs @@ -428,8 +428,8 @@ namespace IndexerOverrideRestrictedAccessorOnly } } } -//$$ PropertyHiding -namespace PropertyHiding +//$$ HideProperty +namespace HideProperty { public class A { @@ -467,8 +467,397 @@ namespace PropertyHiding } } } -//$$ IndexerHidingGeneric -namespace IndexerHidingGeneric +//$$ HideMembers +namespace HideMembers +{ + public class A + { + public int F; + public int Prop + { + get + { + return 3; + } + } + public int G + { + get + { + return 3; + } + } + } + public class B : A + { + public new int F + { + get + { + return 3; + } + } + public new string Prop + { + get + { + return "a"; + } + } + } + public class C : A + { + public new int G; + } + public class D : A + { + public new void F() + { + } + } + public class D1 : D + { + public new int F; + } + public class E : A + { + private new class F + { + } + } +} +//$$ HideMembers2 +namespace HideMembers2 +{ + public class G + { + public int Item + { + get + { + return 1; + } + } + } + public class G2 : G + { + public int this[int i] + { + get + { + return 2; + } + } + } + public class G3 : G2 + { + public new int Item + { + get + { + return 4; + } + } + } + public class H + { + public int this[int j] + { + get + { + return 0; + } + } + } + public class H2 : H + { + public int Item + { + get + { + return 2; + } + } + } + public class H3 : H2 + { + public new string this[int j] + { + get + { + return null; + } + } + } +} +//$$ HideMembers2a +namespace HideMembers2a +{ + public interface IA + { + int this[int i] + { + get; + } + } + public class A : IA + { + int IA.this[int i] + { + get + { + throw new NotImplementedException(); + } + } + } + public class A1 : A + { + public int this[int i] + { + get + { + return 3; + } + } + } +} +//$$ HideMembers3 +namespace HideMembers3 +{ + public class G + { + public void M1(T p) + { + } + public int M2(int t) + { + return 3; + } + } + public class G1 : G + { + public new int M1(int i) + { + return 0; + } + public int M2(T i) + { + return 2; + } + } + public class G2 : G + { + public int M1(T p) + { + return 4; + } + } + public class J + { + public int P + { + get + { + return 2; + } + } + } + public class J2 : J + { + public int get_P; + } +} +//$$ HideMembers4 +namespace HideMembers4 +{ + public class A + { + public void M(T t) + { + } + } + public class A1 : A + { + public new void M(K t) + { + } + public void M(int t) + { + } + } + public class B + { + public void M() + { + } + public void M1() + { + } + public void M2(T t) + { + } + } + public class B1 : B + { + public void M() + { + } + public new void M1() + { + } + public new void M2(R r) + { + } + } + public class C + { + public void M(T t) + { + } + } + public class C1 : C + { + public void M(TT t) + { + } + } +} +//$$ HideMembers5 +namespace HideMembers5 +{ + public class A + { + public void M(int t) + { + } + } + public class A1 : A + { + public void M(ref int t) + { + } + } + public class B + { + public void M(ref int l) + { + } + } + public class B1 : B + { + public void M(out int l) + { + l = 2; + } + public void M(ref long l) + { + } + } +} +//$$ HideMemberSkipNotVisible +namespace HideMemberSkipNotVisible +{ + public class A + { + protected int F; + protected string P + { + get + { + return null; + } + } + } + public class B : A + { + private new string F; + private new int P + { + set + { + } + } + } +} +//$$ HideNestedClass +namespace HideNestedClass +{ + public class A + { + public class N1 + { + } + protected class N2 + { + } + private class N3 + { + } + internal class N4 + { + } + protected internal class N5 + { + } + } + public class B : A + { + public new int N1; + public new int N2; + public int N3; + public new int N4; + public new int N5; + } +} +//$$ HidePropertyReservedMethod +namespace HidePropertyReservedMethod +{ + public class A + { + public int P + { + get + { + return 1; + } + } + } + public class B : A + { + public int get_P() + { + return 2; + } + public void set_P(int value) + { + } + } +} +//$$ HideIndexerDiffAccessor +namespace HideIndexerDiffAccessor +{ + public class A + { + public int this[int i] + { + get + { + return 2; + } + } + } + public class B : A + { + public new int this[int j] + { + set + { + } + } + } +} +//$$ HideIndexerGeneric +namespace HideIndexerGeneric { public class A { @@ -515,8 +904,8 @@ namespace IndexerHidingGeneric } } } -//$$ MethodHiding -namespace MethodHiding +//$$ HideMethod +namespace HideMethod { public class A { @@ -539,8 +928,8 @@ namespace MethodHiding } } } -//$$ MethodHideGeneric -namespace MethodHideGeneric +//$$ HideMethodGeneric +namespace HideMethodGeneric { public class A { @@ -583,8 +972,8 @@ namespace MethodHideGeneric } } } -//$$ MethodHideGenericSkipPrivate -namespace MethodHideGenericSkipPrivate +//$$ HideMethodGenericSkipPrivate +namespace HideMethodGenericSkipPrivate { public class A { @@ -617,8 +1006,8 @@ namespace MethodHideGenericSkipPrivate } } } -//$$ MethodHideGeneric2 -namespace MethodHideGeneric2 +//$$ HideMethodGeneric2 +namespace HideMethodGeneric2 { public class A { @@ -669,8 +1058,51 @@ namespace MethodHideGeneric2 } } } -//$$ EventHiding -namespace EventHiding +//$$ HideMethodDiffSignatures +namespace HideMethodDiffSignatures +{ + public class C1 + { + public virtual void M(T arg) + { + } + } + public class C2 : C1 + { + public new virtual void M(T2 arg) + { + } + } + public class C3 : C2 + { + public new virtual void M(bool arg) + { + } + } +} +//$$ HideMethodStatic +namespace HideMethodStatic +{ + public class A + { + public int N + { + get + { + return 0; + } + } + } + public class B + { + public int N() + { + return 0; + } + } +} +//$$ HideEvent +namespace HideEvent { public class A {