diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs
index 9063ac7368dbe4..a2bec61ee624b2 100644
--- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs
+++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs
@@ -367,18 +367,24 @@ GenericParameterValue genericParam
// GetMember (String, MemberTypes, BindingFlags)
//
case IntrinsicId.Type_GetMember: {
- if (instanceValue.IsEmpty ()) {
+ if (instanceValue.IsEmpty () || argumentValues[0].IsEmpty ()) {
returnValue = MultiValueLattice.Top;
break;
}
BindingFlags? bindingFlags;
+ MemberTypes? memberTypes;
if (calledMethod.HasMetadataParametersCount (1)) {
- // Assume a default value for BindingFlags for methods that don't use BindingFlags as a parameter
- bindingFlags = BindingFlags.Public | BindingFlags.Instance;
- } else if (calledMethod.HasMetadataParametersCount (2) && calledMethod.HasParameterOfType ((ParameterIndex) 2, "System.Reflection.BindingFlags"))
+ // Assume a default value for MemberTypes for methods that don't use MemberTypes as a parameter
+ memberTypes = MemberTypes.All;
+ // Assume a default value for BindingFlags for methods that don't use BindingFlags as a parameter (Type.DefaultLookup)
+ bindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
+ } else if (calledMethod.HasMetadataParametersCount (2) && calledMethod.HasParameterOfType ((ParameterIndex) 2, "System.Reflection.BindingFlags")) {
+ // Assume a default value for MemberTypes for methods that don't use MemberTypes as a parameter
+ memberTypes = MemberTypes.All;
bindingFlags = GetBindingFlagsFromValue (argumentValues[1]);
- else if (calledMethod.HasMetadataParametersCount (3) && calledMethod.HasParameterOfType ((ParameterIndex) 3, "System.Reflection.BindingFlags")) {
+ } else if (calledMethod.HasMetadataParametersCount (3) && calledMethod.HasParameterOfType ((ParameterIndex) 2, "System.Reflection.MemberTypes") && calledMethod.HasParameterOfType ((ParameterIndex) 3, "System.Reflection.BindingFlags")) {
+ memberTypes = GetMemberTypesFromValue (argumentValues[1]);
bindingFlags = GetBindingFlagsFromValue (argumentValues[2]);
} else // Non recognized intrinsic
throw new ArgumentException ($"Reflection call '{calledMethod.GetDisplayName ()}' inside '{GetContainingSymbolDisplayName ()}' is an unexpected intrinsic.");
@@ -394,13 +400,59 @@ GenericParameterValue genericParam
} else {
requiredMemberTypes = GetDynamicallyAccessedMemberTypesFromBindingFlagsForMembers (bindingFlags);
}
+ if (!MemberTypesAreUnsupported (memberTypes)) {
+ DynamicallyAccessedMemberTypes requiredMemberTypesMaskFromMemberTypes;
+ requiredMemberTypesMaskFromMemberTypes = GetDynamicallyAccessedMemberTypesFromMemberTypesForMembers (memberTypes);
+ requiredMemberTypes &= requiredMemberTypesMaskFromMemberTypes;
+ }
var targetValue = _annotations.GetMethodThisParameterValue (calledMethod, requiredMemberTypes);
// Go over all types we've seen
foreach (var value in instanceValue.AsEnumerable ()) {
- // Mark based on bitfield requirements
- _requireDynamicallyAccessedMembersAction.Invoke (value, targetValue);
+ if (value is SystemTypeValue systemTypeValue) {
+ foreach (var stringParam in argumentValues[0].AsEnumerable ()) {
+ if (stringParam is KnownStringValue stringValue && !BindingFlagsAreUnsupported (bindingFlags) && !MemberTypesAreUnsupported (memberTypes)) {
+ // determine if we've got a prefix (for example, abc* searches for anything starting with abc)
+ var isPrefix = stringValue.Contents.EndsWith("*");
+ if (isPrefix)
+ {
+ // Mark based on bitfield requirements
+ _requireDynamicallyAccessedMembersAction.Invoke (value, targetValue);
+ continue;
+ }
+ var name = stringValue.Contents;
+
+ // search for all the things we want by name
+ if (name == ".ctor" && (requiredMemberTypes & (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)) != 0) {
+ MarkConstructorsOnType (systemTypeValue.RepresentedType, bindingFlags, parameterCount: null);
+ }
+ if ((requiredMemberTypes & (DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)) != 0) {
+ MarkEventsOnTypeHierarchy (systemTypeValue.RepresentedType, name, bindingFlags);
+ }
+ if ((requiredMemberTypes & (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)) != 0) {
+ MarkFieldsOnTypeHierarchy (systemTypeValue.RepresentedType, name, bindingFlags);
+ }
+ if ((requiredMemberTypes & (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)) != 0) {
+ foreach (var methodValue in ProcessGetMethodByName (systemTypeValue.RepresentedType, name, bindingFlags)) /*mark method*/;
+ }
+ if ((requiredMemberTypes & (DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)) != 0) {
+ MarkPropertiesOnTypeHierarchy (systemTypeValue.RepresentedType, name, bindingFlags);
+ }
+ if ((requiredMemberTypes & (DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)) != 0) {
+ foreach (var nestedTypeValue in GetNestedTypesOnType (systemTypeValue.RepresentedType, name, bindingFlags)) {
+ MarkType (nestedTypeValue.RepresentedType);
+ }
+ }
+ } else if (stringParam is not NullValue) {
+ // Mark based on bitfield requirements
+ _requireDynamicallyAccessedMembersAction.Invoke (value, targetValue);
+ }
+ }
+ } else if (value is not NullValue) {
+ // Mark based on bitfield requirements
+ _requireDynamicallyAccessedMembersAction.Invoke (value, targetValue);
+ }
}
}
break;
@@ -1352,6 +1404,7 @@ private void ProcessCreateInstanceByName (MethodProxy calledMethod, IReadOnlyLis
}
internal static BindingFlags? GetBindingFlagsFromValue (in MultiValue parameter) => (BindingFlags?) parameter.AsConstInt ();
+ internal static MemberTypes? GetMemberTypesFromValue (in MultiValue parameter) => (MemberTypes?) parameter.AsConstInt ();
internal static bool BindingFlagsAreUnsupported (BindingFlags? bindingFlags)
{
@@ -1381,6 +1434,25 @@ internal static bool BindingFlagsAreUnsupported (BindingFlags? bindingFlags)
return (flags & ~(UnderstoodBindingFlags | IgnorableBindingFlags)) != 0;
}
+ internal static bool MemberTypesAreUnsupported (MemberTypes? memberTypes)
+ {
+ if (memberTypes == null)
+ return true;
+
+ // Member types we understand
+ const MemberTypes UnderstoodMemberTypes =
+ MemberTypes.Constructor |
+ MemberTypes.Event |
+ MemberTypes.Field |
+ MemberTypes.Method |
+ MemberTypes.Property |
+ MemberTypes.TypeInfo |
+ MemberTypes.NestedType;
+
+ MemberTypes flags = memberTypes.Value;
+ return (flags & ~UnderstoodMemberTypes) != 0;
+ }
+
internal static bool HasBindingFlag (BindingFlags? bindingFlags, BindingFlags? search) => bindingFlags != null && (bindingFlags & search) == search;
internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromBindingFlagsForNestedTypes (BindingFlags? bindingFlags) =>
@@ -1421,6 +1493,41 @@ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypes
GetDynamicallyAccessedMemberTypesFromBindingFlagsForProperties (bindingFlags) |
GetDynamicallyAccessedMemberTypesFromBindingFlagsForNestedTypes (bindingFlags);
+ internal static bool HasMemberType (MemberTypes? memberTypes, MemberTypes? search) => memberTypes != null && (memberTypes & search) == search;
+
+ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromMemberTypesForNestedTypes (MemberTypes? memberTypes) =>
+ (HasMemberType (memberTypes, MemberTypes.TypeInfo) ? DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes : DynamicallyAccessedMemberTypes.None) |
+ (HasMemberType (memberTypes, MemberTypes.NestedType) ? DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes : DynamicallyAccessedMemberTypes.None) |
+ (MemberTypesAreUnsupported (memberTypes) ? DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes : DynamicallyAccessedMemberTypes.None);
+
+ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromMemberTypesForConstructors (MemberTypes? memberTypes) =>
+ (HasMemberType (memberTypes, MemberTypes.Constructor) ? DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors : DynamicallyAccessedMemberTypes.None) |
+ (MemberTypesAreUnsupported (memberTypes) ? DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors : DynamicallyAccessedMemberTypes.None);
+
+ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromMemberTypesForMethods (MemberTypes? memberTypes) =>
+ (HasMemberType (memberTypes, MemberTypes.Method) ? DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods : DynamicallyAccessedMemberTypes.None) |
+ (MemberTypesAreUnsupported (memberTypes) ? DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods : DynamicallyAccessedMemberTypes.None);
+
+ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromMemberTypesForFields (MemberTypes? memberTypes) =>
+ (HasMemberType (memberTypes, MemberTypes.Field) ? DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields : DynamicallyAccessedMemberTypes.None) |
+ (MemberTypesAreUnsupported (memberTypes) ? DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields : DynamicallyAccessedMemberTypes.None);
+
+ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromMemberTypesForProperties (MemberTypes? memberTypes) =>
+ (HasMemberType (memberTypes, MemberTypes.Property) ? DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties : DynamicallyAccessedMemberTypes.None) |
+ (MemberTypesAreUnsupported (memberTypes) ? DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties : DynamicallyAccessedMemberTypes.None);
+
+ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromMemberTypesForEvents (MemberTypes? memberTypes) =>
+ (HasMemberType (memberTypes, MemberTypes.Event) ? DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents : DynamicallyAccessedMemberTypes.None) |
+ (MemberTypesAreUnsupported (memberTypes) ? DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents : DynamicallyAccessedMemberTypes.None);
+
+ internal static DynamicallyAccessedMemberTypes GetDynamicallyAccessedMemberTypesFromMemberTypesForMembers (MemberTypes? memberTypes) =>
+ GetDynamicallyAccessedMemberTypesFromMemberTypesForConstructors (memberTypes) |
+ GetDynamicallyAccessedMemberTypesFromMemberTypesForEvents (memberTypes) |
+ GetDynamicallyAccessedMemberTypesFromMemberTypesForFields (memberTypes) |
+ GetDynamicallyAccessedMemberTypesFromMemberTypesForMethods (memberTypes) |
+ GetDynamicallyAccessedMemberTypesFromMemberTypesForProperties (memberTypes) |
+ GetDynamicallyAccessedMemberTypesFromMemberTypesForNestedTypes (memberTypes);
+
///
/// Returns true if the method is a .ctor for System.Type or a type that derives from System.Type (i.e. fields and params of this type can have DynamicallyAccessedMembers annotations)
///
diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs
index 9ddc8fa45debe4..26b52bd3bd6602 100644
--- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs
+++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs
@@ -12,14 +12,15 @@ public class MemberUsedViaReflection
{
public static void Main ()
{
- // Normally calls to GetMember use prefix lookup to match multiple values, we took a conservative approach
- // and preserve not based on the string passed but on the binding flags requirements
TestWithName ();
TestWithNullName ();
TestWithEmptyName ();
TestWithNoValueName ();
TestWithPrefixLookup ();
TestWithBindingFlags ();
+ TestConstructorPrefix ();
+ TestConstructorName ();
+ TestMemberTypeNamed ();
TestWithUnknownBindingFlags (BindingFlags.Public);
TestWithMemberTypes ();
TestNullType ();
@@ -32,7 +33,7 @@ public static void Main ()
[Kept]
static void TestWithName ()
{
- var members = typeof (SimpleType).GetMember ("memberKept");
+ var members = typeof (SpecificName).GetMember ("memberKept");
}
[Kept]
@@ -67,18 +68,35 @@ static void TestWithBindingFlags ()
var members = typeof (BindingFlagsType).GetMember ("PrefixLookup*", BindingFlags.Public | BindingFlags.NonPublic);
}
+ [Kept]
+ static void TestConstructorPrefix ()
+ {
+ var members = typeof (ConstructorPrefixClass).GetMember (".ct*");
+ }
+
+ [Kept]
+ static void TestConstructorName ()
+ {
+ var members = typeof (ConstructorNameClass).GetMember (".ctor");
+ }
+
+ [Kept]
+ static void TestMemberTypeNamed ()
+ {
+ var members1 = typeof (MemberTypeNamedClass1).GetMember ("FieldName", MemberTypes.Field, BindingFlags.Public | BindingFlags.Instance);
+ var members2 = typeof (MemberTypeNamedClass2).GetMember ("FieldName", MemberTypes.Field, BindingFlags.Public | BindingFlags.Instance);
+ }
+
[Kept]
static void TestWithUnknownBindingFlags (BindingFlags bindingFlags)
{
- // Since the binding flags are not known trimming tools should mark all members on the type
+ // The binding flags are not known trimming tools should mark all members on the type with that prefix
var members = typeof (UnknownBindingFlags).GetMember ("PrefixLookup*", bindingFlags);
}
[Kept]
static void TestWithMemberTypes ()
{
- // Here we took the same conservative approach, instead of understanding MemberTypes we only use
- // the information in the binding flags requirements and keep all the MemberTypes
var members = typeof (TestMemberTypes).GetMember ("PrefixLookup*", MemberTypes.Method, BindingFlags.Public);
}
@@ -135,9 +153,11 @@ static void TestIfElse (bool decision)
var members = myType.GetMember ("PrefixLookup*", BindingFlags.Public);
}
- [Kept]
- private class SimpleType
+ private class SpecificName
{
+ public SpecificName()
+ { }
+
[Kept]
public static int field;
@@ -149,10 +169,27 @@ public int memberKept {
set { field = value; }
}
+ public void otherMember() { }
+ }
+
+ [Kept]
+ private class SimpleType
+ {
[Kept]
public SimpleType ()
{ }
+ [Kept]
+ public static int field;
+
+ [Kept]
+ public int memberKept {
+ [Kept]
+ get { return field; }
+ [Kept]
+ set { field = value; }
+ }
+
[Kept]
public void someMethod () { }
}
@@ -160,7 +197,6 @@ public void someMethod () { }
[Kept]
private class PrefixLookupType
{
- [Kept]
public PrefixLookupType ()
{ }
@@ -172,6 +208,8 @@ private PrefixLookupType (int i)
private static int PrefixLookup_privatefield;
+ public static int IncorrectPrefix_field;
+
[Kept]
public int PrefixLookupProperty {
[Kept]
@@ -185,11 +223,18 @@ private int PrefixLookupPrivateProperty {
set { PrefixLookup_privatefield = value; }
}
+ public int IncorrectPrefixProperty {
+ get { return IncorrectPrefix_field; }
+ set { IncorrectPrefix_field = value; }
+ }
+
[Kept]
public void PrefixLookupMethod () { }
private void PrefixLookupPrivateMethod () { }
+ public void IncorrectPrefixMethod() { }
+
[Kept]
[KeptBackingField]
[KeptEventAddMethod]
@@ -198,20 +243,22 @@ private void PrefixLookupPrivateMethod () { }
private event EventHandler PrefixLookupPrivateEvent;
+ public event EventHandler IncorrectPrefixEvent;
+
[Kept]
public static class PrefixLookupNestedType { }
private static class PrefixLookupPrivateNestedType { }
+
+ public static class IncorrectPrefixNestedType { }
}
[Kept]
private class BindingFlagsType
{
- [Kept]
public BindingFlagsType ()
{ }
- [Kept]
private BindingFlagsType (int i)
{ }
@@ -221,6 +268,8 @@ private BindingFlagsType (int i)
[Kept]
private static int PrefixLookup_privatefield;
+ public static int IncorrectPrefix_field;
+
[Kept]
public int PrefixLookupProperty {
[Kept]
@@ -237,12 +286,19 @@ private int PrefixLookupPrivateProperty {
set { PrefixLookup_privatefield = value; }
}
+ public int IncorrectPrefixProperty {
+ get { return IncorrectPrefix_field; }
+ set { IncorrectPrefix_field = value; }
+ }
+
[Kept]
public void PrefixLookupMethod () { }
[Kept]
private void PrefixLookupPrivateMethod () { }
+ public void IncorrectPrefixMethod() { }
+
[Kept]
[KeptBackingField]
[KeptEventAddMethod]
@@ -255,21 +311,73 @@ private void PrefixLookupPrivateMethod () { }
[KeptEventRemoveMethod]
private event EventHandler PrefixLookupPrivateEvent;
+ public event EventHandler IncorrectPrefixEvent;
+
[Kept]
public static class PrefixLookupNestedType { }
[Kept]
private static class PrefixLookupPrivateNestedType { }
+
+ public static class IncorrectPrefixNestedType { }
}
[Kept]
- private class UnknownBindingFlags
+ private class ConstructorPrefixClass
{
[Kept]
- public UnknownBindingFlags ()
+ public ConstructorPrefixClass()
+ { }
+
+ [Kept]
+ public ConstructorPrefixClass(int a)
+ { }
+
+ private ConstructorPrefixClass(string a)
{ }
+ }
+ [Kept]
+ private class ConstructorNameClass
+ {
[Kept]
+ public ConstructorNameClass()
+ { }
+
+ [Kept]
+ public ConstructorNameClass(int a)
+ { }
+
+ private ConstructorNameClass(string a)
+ { }
+ }
+
+ [Kept]
+ private class MemberTypeNamedClass1
+ {
+ public MemberTypeNamedClass1()
+ { }
+
+ [Kept]
+ public int FieldName;
+
+ public int IncorrectFieldName;
+ }
+
+ private class MemberTypeNamedClass2
+ {
+ public MemberTypeNamedClass2()
+ { }
+
+ public void FieldName() { }
+ }
+
+ [Kept]
+ private class UnknownBindingFlags
+ {
+ public UnknownBindingFlags ()
+ { }
+
private UnknownBindingFlags (int i)
{ }
@@ -279,6 +387,8 @@ private UnknownBindingFlags (int i)
[Kept]
private static int PrefixLookup_privatefield;
+ public static int IncorrectPrefix_field;
+
[Kept]
public int PrefixLookupProperty {
[Kept]
@@ -295,12 +405,19 @@ private int PrefixLookupPrivateProperty {
set { PrefixLookup_privatefield = value; }
}
+ public int IncorrectPrefixProperty {
+ get { return IncorrectPrefix_field; }
+ set { IncorrectPrefix_field = value; }
+ }
+
[Kept]
public void PrefixLookupMethod () { }
[Kept]
private void PrefixLookupPrivateMethod () { }
+ public void IncorrectPrefixMethod() { }
+
[Kept]
[KeptBackingField]
[KeptEventAddMethod]
@@ -313,33 +430,32 @@ private void PrefixLookupPrivateMethod () { }
[KeptEventRemoveMethod]
private event EventHandler PrefixLookupPrivateEvent;
+ public event EventHandler IncorrectPrefixEvent;
+
[Kept]
public static class PrefixLookupNestedType { }
[Kept]
private static class PrefixLookupPrivateNestedType { }
+
+ public static class IncorrectPrefixNestedType { }
}
[Kept]
private class TestMemberTypes
{
- [Kept]
public TestMemberTypes ()
{ }
private TestMemberTypes (int i)
{ }
- [Kept]
public static int PrefixLookup_field;
private static int PrefixLookup_privatefield;
- [Kept]
public int PrefixLookupProperty {
- [Kept]
get { return PrefixLookup_field; }
- [Kept]
set { PrefixLookup_field = value; }
}
@@ -353,15 +469,10 @@ public void PrefixLookupMethod () { }
private void PrefixLookupPrivateMethod () { }
- [Kept]
- [KeptBackingField]
- [KeptEventAddMethod]
- [KeptEventRemoveMethod]
public event EventHandler PrefixLookupEvent;
private event EventHandler PrefixLookupPrivateEvent;
- [Kept]
public static class PrefixLookupNestedType { }
private static class PrefixLookupPrivateNestedType { }
@@ -370,7 +481,6 @@ private static class PrefixLookupPrivateNestedType { }
[Kept]
private class MyType
{
- [Kept]
public MyType ()
{ }
@@ -417,7 +527,6 @@ private static class PrefixLookupPrivateNestedType { }
[Kept]
private class IfMember
{
- [Kept]
public IfMember ()
{ }
@@ -429,6 +538,8 @@ private IfMember (int i)
private static int PrefixLookup_privatefield;
+ public static int IncorrectPrefix_field;
+
[Kept]
public int PrefixLookupProperty {
[Kept]
@@ -442,11 +553,18 @@ private int PrefixLookupPrivateProperty {
set { PrefixLookup_privatefield = value; }
}
+ public int IncorrectPrefixProperty {
+ get { return IncorrectPrefix_field; }
+ set { IncorrectPrefix_field = value; }
+ }
+
[Kept]
public void PrefixLookupMethod () { }
private void PrefixLookupPrivateMethod () { }
+ public void IncorrectPrefixMethod () { }
+
[Kept]
[KeptBackingField]
[KeptEventAddMethod]
@@ -455,16 +573,19 @@ private void PrefixLookupPrivateMethod () { }
private event EventHandler PrefixLookupPrivateEvent;
+ public event EventHandler IncorrectPrefixEvent;
+
[Kept]
public static class PrefixLookupNestedType { }
private static class PrefixLookupPrivateNestedType { }
+
+ public static class IncorrectPrefixNestedType { }
}
[Kept]
private class ElseMember
{
- [Kept]
public ElseMember ()
{ }
@@ -476,6 +597,8 @@ private ElseMember (int i)
private static int PrefixLookup_privatefield;
+ public static int IncorrectPrefix_field;
+
[Kept]
public int PrefixLookupProperty {
[Kept]
@@ -489,11 +612,18 @@ private int PrefixLookupPrivateProperty {
set { PrefixLookup_privatefield = value; }
}
+ public int IncorrectPrefixProperty {
+ get { return IncorrectPrefix_field; }
+ set { IncorrectPrefix_field = value; }
+ }
+
[Kept]
public void PrefixLookupMethod () { }
private void PrefixLookupPrivateMethod () { }
+ public void IncorrectPrefixMethod () { }
+
[Kept]
[KeptBackingField]
[KeptEventAddMethod]
@@ -502,10 +632,14 @@ private void PrefixLookupPrivateMethod () { }
private event EventHandler PrefixLookupPrivateEvent;
+ public event EventHandler IncorrectPrefixEvent;
+
[Kept]
public static class PrefixLookupNestedType { }
private static class PrefixLookupPrivateNestedType { }
+
+ public static class IncorrectPrefixNestedType { }
}
}
}
\ No newline at end of file