From f7334fab4babc2cef606fafc053b4e5abe4edf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Tue, 12 Nov 2024 00:04:29 +0100 Subject: [PATCH] Implement `DAMT.*WithInherited` (#109608) --- .../DynamicallyAccessedMembersBinder.cs | 38 +- .../ILCompiler.ReadyToRun.csproj | 1 + .../DynamicallyAccessedMemberTypes.cs | 70 ++ .../System.Runtime/ref/System.Runtime.cs | 14 + .../DynamicallyAccessedMembersBinder.cs | 37 +- .../DynamicallyAccessedMemberTypesEx.cs | 50 ++ .../TrimAnalysis/HandleCallAction.cs | 24 + .../src/linker/CompatibilitySuppressions.xml | 4 + .../DynamicallyAccessedMembersBinder.cs | 38 +- .../Helpers/DataFlowTypeExtensions.cs | 16 + ...ono.Linker.Tests.Cases.Expectations.csproj | 3 + .../DataFlow/MemberTypes.cs | 690 ++++++++++++++++-- .../DataFlow/MemberTypesRelationships.cs | 8 + .../DataFlow/TypeBaseTypeDataFlow.cs | 120 +++ .../Tests/TestFrameworkRulesAndConventions.cs | 4 + 15 files changed, 1037 insertions(+), 80 deletions(-) create mode 100644 src/tools/illink/src/ILLink.Shared/DynamicallyAccessedMemberTypesEx.cs diff --git a/src/coreclr/tools/Common/Compiler/Dataflow/DynamicallyAccessedMembersBinder.cs b/src/coreclr/tools/Common/Compiler/Dataflow/DynamicallyAccessedMembersBinder.cs index 73b16ebfe5c5c..14372b423f332 100644 --- a/src/coreclr/tools/Common/Compiler/Dataflow/DynamicallyAccessedMembersBinder.cs +++ b/src/coreclr/tools/Common/Compiler/Dataflow/DynamicallyAccessedMembersBinder.cs @@ -34,13 +34,15 @@ public static IEnumerable GetDynamicallyAccessedMembers(this T if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicConstructors)) { - foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited); + foreach (var c in typeDefinition.ApplyIncludeInherited(t => t.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.NonPublic), withInherited)) yield return c; } if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicConstructors)) { - foreach (var c in typeDefinition.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited); + foreach (var c in typeDefinition.ApplyIncludeInherited(t => t.GetConstructorsOnType(filter: null, bindingFlags: BindingFlags.Public), withInherited)) yield return c; } @@ -52,7 +54,8 @@ public static IEnumerable GetDynamicallyAccessedMembers(this T if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicMethods)) { - foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited); + foreach (var m in typeDefinition.ApplyIncludeInherited(t => t.GetMethodsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return m; } @@ -64,7 +67,8 @@ public static IEnumerable GetDynamicallyAccessedMembers(this T if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicFields)) { - foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited); + foreach (var f in typeDefinition.ApplyIncludeInherited(t => t.GetFieldsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return f; } @@ -76,7 +80,8 @@ public static IEnumerable GetDynamicallyAccessedMembers(this T if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicNestedTypes)) { - foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited); + foreach (var t in typeDefinition.ApplyIncludeInherited(t => t.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.NonPublic), withInherited)) { yield return t; var members = new List(); @@ -88,7 +93,8 @@ public static IEnumerable GetDynamicallyAccessedMembers(this T if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.PublicNestedTypes)) { - foreach (var t in typeDefinition.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited); + foreach (var t in typeDefinition.ApplyIncludeInherited(t => t.GetNestedTypesOnType(filter: null, bindingFlags: BindingFlags.Public), withInherited)) { yield return t; var members = new List(); @@ -100,7 +106,8 @@ public static IEnumerable GetDynamicallyAccessedMembers(this T if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicProperties)) { - foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited); + foreach (var p in typeDefinition.ApplyIncludeInherited(t => t.GetPropertiesOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return p; } @@ -112,7 +119,8 @@ public static IEnumerable GetDynamicallyAccessedMembers(this T if (memberTypes.HasFlag(DynamicallyAccessedMemberTypes.NonPublicEvents)) { - foreach (var e in typeDefinition.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag(DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited); + foreach (var e in typeDefinition.ApplyIncludeInherited(t => t.GetEventsOnTypeHierarchy(filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return e; } @@ -504,6 +512,20 @@ private static DefType TryGetBaseType(this TypeDesc type) } } + private static IEnumerable ApplyIncludeInherited(this TypeDesc type, Func> selector, bool includeBases) + { + do + { + foreach (var m in selector(type)) + yield return m; + + if (!includeBases) + yield break; + + type = type.TryGetBaseType(); + } while (type != null); + } + private static DefType[] TryGetExplicitlyImplementedInterfaces(this TypeDesc type) { if (type is MetadataType mdType) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index da8f861c4dba5..112af3a715db7 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -139,6 +139,7 @@ + diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs index 1c7e30cbc36f5..5cabd72975ee8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs @@ -92,6 +92,76 @@ enum DynamicallyAccessedMemberTypes /// Interfaces = 0x2000, + /// + /// Specifies all non-public constructors, including those inherited from base classes. + /// + NonPublicConstructorsWithInherited = NonPublicConstructors | 0x4000, + + /// + /// Specifies all non-public methods, including those inherited from base classes. + /// + NonPublicMethodsWithInherited = NonPublicMethods | 0x8000, + + /// + /// Specifies all non-public fields, including those inherited from base classes. + /// + NonPublicFieldsWithInherited = NonPublicFields | 0x10000, + + /// + /// Specifies all non-public nested types, including those inherited from base classes. + /// + NonPublicNestedTypesWithInherited = NonPublicNestedTypes | 0x20000, + + /// + /// Specifies all non-public properties, including those inherited from base classes. + /// + NonPublicPropertiesWithInherited = NonPublicProperties | 0x40000, + + /// + /// Specifies all non-public events, including those inherited from base classes. + /// + NonPublicEventsWithInherited = NonPublicEvents | 0x80000, + + /// + /// Specifies all public constructors, including those inherited from base classes. + /// + PublicConstructorsWithInherited = PublicConstructors | 0x100000, + + /// + /// Specifies all public nested types, including those inherited from base classes. + /// + PublicNestedTypesWithInherited = PublicNestedTypes | 0x200000, + + /// + /// Specifies all constructors, including those inherited from base classes. + /// + AllConstructors = PublicConstructorsWithInherited | NonPublicConstructorsWithInherited, + + /// + /// Specifies all methods, including those inherited from base classes. + /// + AllMethods = PublicMethods | NonPublicMethodsWithInherited, + + /// + /// Specifies all fields, including those inherited from base classes. + /// + AllFields = PublicFields | NonPublicFieldsWithInherited, + + /// + /// Specifies all nested types, including those inherited from base classes. + /// + AllNestedTypes = PublicNestedTypesWithInherited | NonPublicNestedTypesWithInherited, + + /// + /// Specifies all properties, including those inherited from base classes. + /// + AllProperties = PublicProperties | NonPublicPropertiesWithInherited, + + /// + /// Specifies all events, including those inherited from base classes. + /// + AllEvents = PublicEvents | NonPublicEventsWithInherited, + /// /// Specifies all members. /// diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index fe7f17353d852..595845c514906 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8846,6 +8846,20 @@ public enum DynamicallyAccessedMemberTypes PublicEvents = 2048, NonPublicEvents = 4096, Interfaces = 8192, + NonPublicConstructorsWithInherited = 16388, + NonPublicMethodsWithInherited = 32784, + AllMethods = 32792, + NonPublicFieldsWithInherited = 65600, + AllFields = 65632, + NonPublicNestedTypesWithInherited = 131328, + NonPublicPropertiesWithInherited = 263168, + AllProperties = 263680, + NonPublicEventsWithInherited = 528384, + AllEvents = 530432, + PublicConstructorsWithInherited = 1048579, + AllConstructors = 1064967, + PublicNestedTypesWithInherited = 2097280, + AllNestedTypes = 2228608, } [System.AttributeUsageAttribute(System.AttributeTargets.Constructor | System.AttributeTargets.Field | System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)] public sealed partial class DynamicDependencyAttribute : System.Attribute diff --git a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/DynamicallyAccessedMembersBinder.cs b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/DynamicallyAccessedMembersBinder.cs index c0018482e13b8..0a341169593f6 100644 --- a/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/DynamicallyAccessedMembersBinder.cs +++ b/src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/DynamicallyAccessedMembersBinder.cs @@ -30,12 +30,14 @@ public static IEnumerable GetDynamicallyAccessedMembers (this ITypeSymb var declaredOnlyFlags = declaredOnly ? BindingFlags.DeclaredOnly : BindingFlags.Default; if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicConstructors)) { - foreach (var c in typeDefinition.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.NonPublic)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited); + foreach (var c in typeDefinition.ApplyIncludeInherited (t => t.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.NonPublic), withInherited)) yield return c; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicConstructors)) { - foreach (var c in typeDefinition.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.Public)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited); + foreach (var c in typeDefinition.ApplyIncludeInherited (t => t.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.Public), withInherited)) yield return c; } @@ -45,7 +47,8 @@ public static IEnumerable GetDynamicallyAccessedMembers (this ITypeSymb } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicMethods)) { - foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited); + foreach (var m in typeDefinition.ApplyIncludeInherited (t => t.GetMethodsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return m; } @@ -55,7 +58,8 @@ public static IEnumerable GetDynamicallyAccessedMembers (this ITypeSymb } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicFields)) { - foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited); + foreach (var f in typeDefinition.ApplyIncludeInherited (t => t.GetFieldsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return f; } @@ -65,7 +69,8 @@ public static IEnumerable GetDynamicallyAccessedMembers (this ITypeSymb } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)) { - foreach (var nested in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.NonPublic)) { + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited); + foreach (var nested in typeDefinition.ApplyIncludeInherited (t => t.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.NonPublic), withInherited)) { yield return nested; var members = new List (); nested.GetAllOnType (declaredOnly: false, members); @@ -75,7 +80,8 @@ public static IEnumerable GetDynamicallyAccessedMembers (this ITypeSymb } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicNestedTypes)) { - foreach (var nested in typeDefinition.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.Public)) { + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited); + foreach (var nested in typeDefinition.ApplyIncludeInherited (t => t.GetNestedTypesOnType (filter: null, bindingFlags: BindingFlags.Public), withInherited)) { yield return nested; var members = new List (); nested.GetAllOnType (declaredOnly: false, members); @@ -85,7 +91,8 @@ public static IEnumerable GetDynamicallyAccessedMembers (this ITypeSymb } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicProperties)) { - foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited); + foreach (var p in typeDefinition.ApplyIncludeInherited (t => t.GetPropertiesOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return p; } @@ -95,7 +102,8 @@ public static IEnumerable GetDynamicallyAccessedMembers (this ITypeSymb } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicEvents)) { - foreach (var e in typeDefinition.GetEventsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited); + foreach (var e in typeDefinition.ApplyIncludeInherited (t => t.GetEventsOnTypeHierarchy (filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return e; } @@ -410,5 +418,18 @@ static void GetAllOnType (ITypeSymbol type, bool declaredOnly, List mem } } } + private static IEnumerable ApplyIncludeInherited (this ITypeSymbol thisType, Func> selector, bool includeBases) + { + ITypeSymbol? type = thisType; + do { + foreach (var m in selector (type)) + yield return m; + + if (!includeBases) + yield break; + + type = type.BaseType; + } while (type != null); + } } } diff --git a/src/tools/illink/src/ILLink.Shared/DynamicallyAccessedMemberTypesEx.cs b/src/tools/illink/src/ILLink.Shared/DynamicallyAccessedMemberTypesEx.cs new file mode 100644 index 0000000000000..d73a10daeeede --- /dev/null +++ b/src/tools/illink/src/ILLink.Shared/DynamicallyAccessedMemberTypesEx.cs @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace System.Diagnostics.CodeAnalysis +{ + public static class DynamicallyAccessedMemberTypesEx + { + /// + /// Specifies all non-public constructors, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes NonPublicConstructorsWithInherited = DynamicallyAccessedMemberTypes.NonPublicConstructors | (DynamicallyAccessedMemberTypes) 0x4000; + + /// + /// Specifies all non-public methods, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes NonPublicMethodsWithInherited = DynamicallyAccessedMemberTypes.NonPublicMethods | (DynamicallyAccessedMemberTypes) 0x8000; + + /// + /// Specifies all non-public fields, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes NonPublicFieldsWithInherited = DynamicallyAccessedMemberTypes.NonPublicFields | (DynamicallyAccessedMemberTypes) 0x10000; + + /// + /// Specifies all non-public nested types, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes NonPublicNestedTypesWithInherited = DynamicallyAccessedMemberTypes.NonPublicNestedTypes | (DynamicallyAccessedMemberTypes) 0x20000; + + /// + /// Specifies all non-public properties, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes NonPublicPropertiesWithInherited = DynamicallyAccessedMemberTypes.NonPublicProperties | (DynamicallyAccessedMemberTypes) 0x40000; + + /// + /// Specifies all non-public events, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes NonPublicEventsWithInherited = DynamicallyAccessedMemberTypes.NonPublicEvents | (DynamicallyAccessedMemberTypes) 0x80000; + + /// + /// Specifies all public constructors, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes PublicConstructorsWithInherited = DynamicallyAccessedMemberTypes.PublicConstructors | (DynamicallyAccessedMemberTypes) 0x100000; + + /// + /// Specifies all public nested types, including those inherited from base classes. + /// + public const DynamicallyAccessedMemberTypes PublicNestedTypesWithInherited = DynamicallyAccessedMemberTypes.PublicNestedTypes | (DynamicallyAccessedMemberTypes) 0x200000; + } +} diff --git a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs index bce23ec2c2f0d..a58bcdd7ea7a0 100644 --- a/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs +++ b/src/tools/illink/src/ILLink.Shared/TrimAnalysis/HandleCallAction.cs @@ -947,22 +947,46 @@ ValueWithDynamicallyAccessedMembers valueWithDynamicallyAccessedMembers else { // PublicConstructors are not propagated to base type + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited; + + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicEvents)) propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicEvents; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicFields)) propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicFields; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicMethods)) propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicMethods; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited; + // PublicNestedTypes are not propagated to base type + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited; + + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited; + // PublicParameterlessConstructor is not propagated to base type if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicProperties)) propagatedMemberTypes |= DynamicallyAccessedMemberTypes.PublicProperties; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited)) + propagatedMemberTypes |= DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited; + if (valueWithDynamicallyAccessedMembers.DynamicallyAccessedMemberTypes.HasFlag (DynamicallyAccessedMemberTypes.Interfaces)) propagatedMemberTypes |= DynamicallyAccessedMemberTypes.Interfaces; } diff --git a/src/tools/illink/src/linker/CompatibilitySuppressions.xml b/src/tools/illink/src/linker/CompatibilitySuppressions.xml index 2426bdbf49276..4166608e4ada0 100644 --- a/src/tools/illink/src/linker/CompatibilitySuppressions.xml +++ b/src/tools/illink/src/linker/CompatibilitySuppressions.xml @@ -1,6 +1,10 @@ + + CP0001 + T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypesEx + CP0001 T:ILLink.Shared.DataFlow.Box`1 diff --git a/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs b/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs index f797b8c5499b5..9c2f276cb0f49 100644 --- a/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs +++ b/src/tools/illink/src/linker/Linker.Dataflow/DynamicallyAccessedMembersBinder.cs @@ -31,12 +31,14 @@ public static IEnumerable GetDynamicallyAccessedMembers var declaredOnlyFlags = declaredOnly ? BindingFlags.DeclaredOnly : BindingFlags.Default; if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicConstructors)) { - foreach (var c in typeDefinition.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.NonPublic)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited); + foreach (var c in typeDefinition.ApplyIncludeInherited (context, t => t.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.NonPublic), withInherited)) yield return c; } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicConstructors)) { - foreach (var c in typeDefinition.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.Public)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited); + foreach (var c in typeDefinition.ApplyIncludeInherited (context, t => t.GetConstructorsOnType (filter: null, bindingFlags: BindingFlags.Public), withInherited)) yield return c; } @@ -46,7 +48,8 @@ public static IEnumerable GetDynamicallyAccessedMembers } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicMethods)) { - foreach (var m in typeDefinition.GetMethodsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited); + foreach (var m in typeDefinition.ApplyIncludeInherited (context, t => t.GetMethodsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return m; } @@ -56,7 +59,8 @@ public static IEnumerable GetDynamicallyAccessedMembers } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicFields)) { - foreach (var f in typeDefinition.GetFieldsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited); + foreach (var f in typeDefinition.ApplyIncludeInherited (context, t => t.GetFieldsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return f; } @@ -66,7 +70,8 @@ public static IEnumerable GetDynamicallyAccessedMembers } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)) { - foreach (var nested in typeDefinition.GetNestedTypesOnType (context, filter: null, bindingFlags: BindingFlags.NonPublic)) { + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited); + foreach (var nested in typeDefinition.ApplyIncludeInherited (context, t => t.GetNestedTypesOnType (context, filter: null, bindingFlags: BindingFlags.NonPublic), withInherited)) { yield return nested; var members = new List (); nested.GetAllOnType (context, declaredOnly: false, members); @@ -76,7 +81,8 @@ public static IEnumerable GetDynamicallyAccessedMembers } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.PublicNestedTypes)) { - foreach (var nested in typeDefinition.GetNestedTypesOnType (context, filter: null, bindingFlags: BindingFlags.Public)) { + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited); + foreach (var nested in typeDefinition.ApplyIncludeInherited (context, t => t.GetNestedTypesOnType (context, filter: null, bindingFlags: BindingFlags.Public), withInherited)) { yield return nested; var members = new List (); nested.GetAllOnType (context, declaredOnly: false, members); @@ -86,7 +92,8 @@ public static IEnumerable GetDynamicallyAccessedMembers } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicProperties)) { - foreach (var p in typeDefinition.GetPropertiesOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited); + foreach (var p in typeDefinition.ApplyIncludeInherited (context, t => t.GetPropertiesOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return p; } @@ -96,7 +103,8 @@ public static IEnumerable GetDynamicallyAccessedMembers } if (memberTypes.HasFlag (DynamicallyAccessedMemberTypes.NonPublicEvents)) { - foreach (var e in typeDefinition.GetEventsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags)) + bool withInherited = !declaredOnly && memberTypes.HasFlag (DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited); + foreach (var e in typeDefinition.ApplyIncludeInherited (context, t => t.GetEventsOnTypeHierarchy (context, filter: null, bindingFlags: BindingFlags.NonPublic | declaredOnlyFlags), withInherited)) yield return e; } @@ -423,5 +431,19 @@ static void GetAllOnType (TypeDefinition type, LinkContext context, bool declare members.Add (e); } } + + private static IEnumerable ApplyIncludeInherited (this TypeDefinition thisType, LinkContext context, Func> selector, bool includeBases) + { + TypeDefinition? type = thisType; + do { + foreach (var m in selector (type)) + yield return m; + + if (!includeBases) + yield break; + + type = context.TryResolve (type.BaseType); + } while (type != null); + } } } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs index e11f78abe89ad..48065805047c4 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs @@ -12,6 +12,8 @@ public static void RequiresAll ([DynamicallyAccessedMembers (DynamicallyAccessed public static void RequiresPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] this Type type) { } + public static void RequiresPublicConstructorsWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited)] this Type type) { } + public static void RequiresPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] this Type type) { } public static void RequiresPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] this Type type) { } @@ -20,22 +22,36 @@ public static void RequiresPublicMethods ([DynamicallyAccessedMembers (Dynamical public static void RequiresPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] this Type type) { } + public static void RequiresPublicNestedTypesWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited)] this Type type) { } + public static void RequiresPublicParameterlessConstructor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] this Type type) { } public static void RequiresPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] this Type type) { } public static void RequiresNonPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] this Type type) { } + public static void RequiresNonPublicEventsWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited)] this Type type) { } + public static void RequiresNonPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] this Type type) { } + public static void RequiresNonPublicFieldsWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited)] this Type type) { } + public static void RequiresNonPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type type) { } + public static void RequiresNonPublicMethodsWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited)] this Type type) { } + public static void RequiresNonPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] this Type type) { } + public static void RequiresNonPublicNestedTypesWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited)] this Type type) { } + public static void RequiresNonPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] this Type type) { } + public static void RequiresNonPublicConstructorsWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited)] this Type type) { } + public static void RequiresNonPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] this Type type) { } + public static void RequiresNonPublicPropertiesWithInherited ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited)] this Type type) { } + public static void RequiresInterfaces ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] this Type type) { } public static void RequiresNone (this Type type) { } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj index 35e3d8428b7cf..b65c85abb00f5 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj @@ -1,2 +1,5 @@ + + + diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs index 9ac116330ac81..ff00a2da5fa71 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs @@ -27,25 +27,33 @@ public static void Main () RequirePublicConstructors (typeof (PublicConstructorsType)); RequirePublicConstructors (typeof (PublicConstructorsBeforeFieldInitType)); RequirePublicConstructors (typeof (PublicConstructorsPrivateParameterlessConstructorType)); + RequirePublicConstructorsWithInherited (typeof (PublicConstructorsWithInheritedType)); RequireNonPublicConstructors (typeof (NonPublicConstructorsType)); RequireNonPublicConstructors (typeof (NonPublicConstructorsBeforeFieldInitType)); - RequireAllConstructors (typeof (AllConstructorsType)); - RequireAllConstructors (typeof (AllConstructorsBeforeFieldInitType)); + RequireNonPublicConstructorsWithInherited (typeof (NonPublicConstructorsWithInheritedType)); + RequirePublicAndNonPublicConstructors (typeof (AllConstructorsType)); + RequirePublicAndNonPublicConstructors (typeof (AllConstructorsBeforeFieldInitType)); RequirePublicMethods (typeof (PublicMethodsType)); RequireNonPublicMethods (typeof (NonPublicMethodsType)); - RequireAllMethods (typeof (AllMethodsType)); + RequireNonPublicMethodsWithInherited (typeof (NonPublicMethodsWithInheritedType)); + RequirePublicAndNonPublicMethods (typeof (AllMethodsType)); RequirePublicFields (typeof (PublicFieldsType)); RequireNonPublicFields (typeof (NonPublicFieldsType)); - RequireAllFields (typeof (AllFieldsType)); + RequireNonPublicFieldsWithInherited (typeof (NonPublicFieldsWithInheritedType)); + RequirePublicAndNonPublicFields (typeof (AllFieldsType)); RequirePublicNestedTypes (typeof (PublicNestedTypesType)); + RequirePublicNestedTypesWithInherited (typeof (PublicNestedTypesWithInheritedType)); RequireNonPublicNestedTypes (typeof (NonPublicNestedTypesType)); - RequireAllNestedTypes (typeof (AllNestedTypesType)); + RequireNonPublicNestedTypesWithInherited (typeof (NonPublicNestedTypesWithInheritedType)); + RequirePublicAndNonPublicNestedTypes (typeof (AllNestedTypesType)); RequirePublicProperties (typeof (PublicPropertiesType)); RequireNonPublicProperties (typeof (NonPublicPropertiesType)); - RequireAllProperties (typeof (AllPropertiesType)); + RequireNonPublicPropertiesWithInherited (typeof (NonPublicPropertiesWithInheritedType)); + RequirePublicAndNonPublicProperties (typeof (AllPropertiesType)); RequirePublicEvents (typeof (PublicEventsType)); RequireNonPublicEvents (typeof (NonPublicEventsType)); - RequireAllEvents (typeof (AllEventsType)); + RequireNonPublicEventsWithInherited (typeof (NonPublicEventsWithInheritedType)); + RequirePublicAndNonPublicEvents (typeof (AllEventsType)); RequireInterfaces (typeof (InterfacesType)); RequireAll (typeof (AllType)); RequireAll (typeof (RequireAllWithRecursiveTypeReferences)); @@ -163,6 +171,45 @@ public void Method1 () { } public bool Field1; } + [Kept] + private static void RequirePublicConstructorsWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class PublicConstructorsWithInheritedBaseType + { + [Kept] + public PublicConstructorsWithInheritedBaseType () { } + + [Kept] + public PublicConstructorsWithInheritedBaseType (int i) { } + } + + [Kept] + [KeptBaseType (typeof (PublicConstructorsWithInheritedBaseType))] + class PublicConstructorsWithInheritedType : PublicConstructorsWithInheritedBaseType + { + private PublicConstructorsWithInheritedType () { } + + [Kept] + public PublicConstructorsWithInheritedType (int i) { } + + private PublicConstructorsWithInheritedType (int i, int j) { } + + // Not implied by the DynamicallyAccessedMemberTypes logic, but + // explicit cctors would be kept by ILLink. + // [Kept] + // static PublicConstructorsType () { } + + public void Method1 () { } + public bool Property1 { get; set; } + public bool Field1; + } + [Kept] class PublicConstructorsBeforeFieldInitType { @@ -217,6 +264,45 @@ public void Method1 () { } public bool Field1; } + [Kept] + private static void RequireNonPublicConstructorsWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class NonPublicConstructorsWithInheritedBaseType + { + [Kept] + protected NonPublicConstructorsWithInheritedBaseType () { } + + [Kept] + protected NonPublicConstructorsWithInheritedBaseType (int i) { } + } + + [Kept] + [KeptBaseType (typeof (NonPublicConstructorsWithInheritedBaseType))] + class NonPublicConstructorsWithInheritedType : NonPublicConstructorsWithInheritedBaseType + { + [Kept] + private NonPublicConstructorsWithInheritedType () { } + + public NonPublicConstructorsWithInheritedType (int i) { } + + [Kept] + private NonPublicConstructorsWithInheritedType (int i, int j) { } + + // Kept by the DynamicallyAccessedMembers logic + [Kept] + static NonPublicConstructorsWithInheritedType () { } + + public void Method1 () { } + public bool Property1 { get; set; } + public bool Field1; + } + [Kept] class NonPublicConstructorsBeforeFieldInitType { @@ -227,7 +313,7 @@ public NonPublicConstructorsBeforeFieldInitType () { } [Kept] - private static void RequireAllConstructors ( + private static void RequirePublicAndNonPublicConstructors ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) @@ -543,9 +629,149 @@ public static void HideStaticMethod () { } public bool Field1; } + [Kept] + private static void RequireNonPublicMethodsWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class NonPublicMethodsWithInheritedBaseType + { + public void PublicBaseMethod () { } + [Kept] + private void PrivateBaseMethod () { } + [Kept] + protected void ProtectedBaseMethod () { } + public void HideMethod () { } + + public bool PublicPropertyOnBase { get; set; } + [Kept] + protected bool ProtectedPropertyOnBase { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + [Kept] + private bool PrivatePropertyOnBase { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + public bool HideProperty { get; set; } + + public event EventHandler PublicEventOnBase; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + protected event EventHandler ProtectedEventOnBase; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + private event EventHandler PrivateEventOnBase; + public event EventHandler HideEvent; + + public static void PublicStaticBaseMethod () { } + [Kept] + private static void PrivateStaticBaseMethod () { } + [Kept] + protected static void ProtectedStaticBaseMethod () { } + public static void HideStaticMethod () { } + + static public bool PublicStaticPropertyOnBase { get; set; } + [Kept] + [KeptBackingField] + static protected bool ProtectedStaticPropertyOnBase { [Kept] get; [Kept] set; } + [Kept] + [KeptBackingField] + static private bool PrivateStaticPropertyOnBase { [Kept] get; [Kept] set; } + static public bool HideStaticProperty { get; set; } + + public static event EventHandler PublicStaticEventOnBase; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + protected static event EventHandler ProtectedStaticEventOnBase; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + private static event EventHandler PrivateStaticEventOnBase; + public static event EventHandler HideStaticEvent; + } + + [Kept] + [KeptBaseType (typeof (NonPublicMethodsWithInheritedBaseType))] + class NonPublicMethodsWithInheritedType : NonPublicMethodsWithInheritedBaseType + { + private NonPublicMethodsWithInheritedType () { } + + public void PublicMethod1 () { } + public bool PublicMethod2 (int i) { return false; } + + [Kept] + internal void InternalMethod () { } + [Kept] + protected void ProtectedMethod () { } + [Kept] + private void PrivateMethod () { } + public void HideMethod () { } + + public bool PublicProperty { get; set; } + [Kept] + protected bool ProtectedProperty { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + [Kept] + private bool PrivateProperty { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + public bool HideProperty { get; set; } + + public event EventHandler PublicEvent; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + protected event EventHandler ProtectedEvent; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + private event EventHandler PrivateEvent; + public event EventHandler HideEvent; + + public static void PublicStaticMethod () { } + [Kept] + private static void PrivateStaticMethod () { } + [Kept] + protected static void ProtectedStaticMethod () { } + public static void HideStaticMethod () { } + + static public bool PublicStaticProperty { get; set; } + [Kept] + [KeptBackingField] + static protected bool ProtectedStaticProperty { [Kept] get; [Kept] set; } + [Kept] + [KeptBackingField] + static private bool PrivateStaticProperty { [Kept] get; [Kept] set; } + static public bool HideStaticProperty { get; set; } + + public static event EventHandler PublicStaticEvent; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + protected static event EventHandler ProtectedStaticEvent; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + private static event EventHandler PrivateStaticEvent; + public static event EventHandler HideStaticEvent; + + public bool Field1; + } [Kept] - private static void RequireAllMethods ( + private static void RequirePublicAndNonPublicMethods ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) @@ -922,61 +1148,70 @@ class NonPublicFieldsType : NonPublicFieldsBaseType public static event EventHandler HideStaticEvent; } - [Kept] - private static void RequireAllFields ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] + private static void RequireNonPublicFieldsWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) { } [Kept] - class AllFieldsBaseType + class NonPublicFieldsWithInheritedBaseType { - [Kept] public bool PublicBaseField; [Kept] protected bool ProtectedBaseField; - private bool PrivateBaseField; [Kept] + private bool PrivateBaseField; public bool HideField; - // Backing fields are private, so they are not accessible from a derived type + // Backing fields are always private, so they will be kept even if the property itself is public + [KeptBackingField] public bool PublicPropertyOnBase { get; set; } + [KeptBackingField] protected bool ProtectedPropertyOnBase { get; set; } + [KeptBackingField] private bool PrivatePropertyOnBase { get; set; } + [KeptBackingField] public event EventHandler PublicEventOnBase; + [KeptBackingField] protected event EventHandler ProtectedEventOnBase; + [KeptBackingField] private event EventHandler PrivateEventOnBase; - [Kept] static public bool StaticPublicBaseField; [Kept] static protected bool StaticProtectedBaseField; - static private bool StaticPrivateBaseField; [Kept] + static private bool StaticPrivateBaseField; static public bool HideStaticField; + [KeptBackingField] static public bool PublicStaticPropertyOnBase { get; set; } + [KeptBackingField] static protected bool ProtectedStaticPropertyOnBase { get; set; } + [KeptBackingField] static private bool PrivateStaticPropertyOnBase { get; set; } + [KeptBackingField] static public bool HideStaticProperty { get; set; } + [KeptBackingField] public static event EventHandler PublicStaticEventOnBase; + [KeptBackingField] protected static event EventHandler ProtectedStaticEventOnBase; + [KeptBackingField] private static event EventHandler PrivateStaticEventOnBase; + [KeptBackingField] public static event EventHandler HideStaticEvent; } [Kept] - [KeptBaseType (typeof (AllFieldsBaseType))] - class AllFieldsType : AllFieldsBaseType + [KeptBaseType (typeof (NonPublicFieldsWithInheritedBaseType))] + class NonPublicFieldsWithInheritedType : NonPublicFieldsWithInheritedBaseType { - [Kept] public bool PublicField; - [Kept] public string PublicStringField; [Kept] internal bool InternalField; @@ -984,9 +1219,9 @@ class AllFieldsType : AllFieldsBaseType protected bool ProtectedField; [Kept] private bool PrivateField; - [Kept] public bool HideField; + // Backing fields are always private, so they will be kept even if the property itself is public [KeptBackingField] public bool PublicProperty { get; set; } [KeptBackingField] @@ -1005,15 +1240,12 @@ class AllFieldsType : AllFieldsBaseType [KeptBackingField] public event EventHandler HideEvent; - [Kept] static public bool StaticPublicField; - [Kept] static public string StaticPublicStringField; [Kept] static protected bool StaticProtectedField; [Kept] static private bool StaticPrivateField; - [Kept] static public bool HideStaticField; [KeptBackingField] @@ -1035,44 +1267,156 @@ class AllFieldsType : AllFieldsBaseType public static event EventHandler HideStaticEvent; } - [Kept] - private static void RequirePublicNestedTypes ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes)] + private static void RequirePublicAndNonPublicFields ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) { } [Kept] - class PublicNestedTypesBaseType - { - // Nested types are not propagated from base class at all - public class PublicBaseNestedType { } - protected class ProtectedBaseNestedType { } - private class PrivateBaseNestedType { } - public class HideBaseNestedType { } - public delegate int PublicDelegate (); - private delegate int PrivateDelegate (); - } - - [Kept] - [KeptBaseType (typeof (PublicNestedTypesBaseType))] - class PublicNestedTypesType : PublicNestedTypesBaseType + class AllFieldsBaseType { [Kept] - [KeptMember (".ctor()")] - public class PublicNestedType { } - protected class ProtectedNestedType { } - private class PrivateNestedType { } + public bool PublicBaseField; [Kept] - [KeptMember (".ctor()")] - public class HideNestedType { } - + protected bool ProtectedBaseField; + private bool PrivateBaseField; [Kept] - [KeptBaseType (typeof (MulticastDelegate))] - [KeptMember (".ctor(System.Object,System.IntPtr)")] - [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] + public bool HideField; + + // Backing fields are private, so they are not accessible from a derived type + public bool PublicPropertyOnBase { get; set; } + protected bool ProtectedPropertyOnBase { get; set; } + private bool PrivatePropertyOnBase { get; set; } + + public event EventHandler PublicEventOnBase; + protected event EventHandler ProtectedEventOnBase; + private event EventHandler PrivateEventOnBase; + + [Kept] + static public bool StaticPublicBaseField; + [Kept] + static protected bool StaticProtectedBaseField; + static private bool StaticPrivateBaseField; + [Kept] + static public bool HideStaticField; + + static public bool PublicStaticPropertyOnBase { get; set; } + static protected bool ProtectedStaticPropertyOnBase { get; set; } + static private bool PrivateStaticPropertyOnBase { get; set; } + static public bool HideStaticProperty { get; set; } + + public static event EventHandler PublicStaticEventOnBase; + protected static event EventHandler ProtectedStaticEventOnBase; + private static event EventHandler PrivateStaticEventOnBase; + public static event EventHandler HideStaticEvent; + } + + [Kept] + [KeptBaseType (typeof (AllFieldsBaseType))] + class AllFieldsType : AllFieldsBaseType + { + [Kept] + public bool PublicField; + [Kept] + public string PublicStringField; + [Kept] + internal bool InternalField; + [Kept] + protected bool ProtectedField; + [Kept] + private bool PrivateField; + [Kept] + public bool HideField; + + [KeptBackingField] + public bool PublicProperty { get; set; } + [KeptBackingField] + protected bool ProtectedProperty { get; set; } + [KeptBackingField] + private bool PrivateProperty { get; set; } + [KeptBackingField] + public bool HideProperty { get; set; } + + [KeptBackingField] + public event EventHandler PublicEvent; + [KeptBackingField] + protected event EventHandler ProtectedEvent; + [KeptBackingField] + private event EventHandler PrivateEvent; + [KeptBackingField] + public event EventHandler HideEvent; + + [Kept] + static public bool StaticPublicField; + [Kept] + static public string StaticPublicStringField; + [Kept] + static protected bool StaticProtectedField; + [Kept] + static private bool StaticPrivateField; + [Kept] + static public bool HideStaticField; + + [KeptBackingField] + static public bool PublicStaticProperty { get; set; } + [KeptBackingField] + static protected bool ProtectedStaticProperty { get; set; } + [KeptBackingField] + static private bool PrivateStaticProperty { get; set; } + [KeptBackingField] + static public bool HideStaticProperty { get; set; } + + [KeptBackingField] + public static event EventHandler PublicStaticEvent; + [KeptBackingField] + protected static event EventHandler ProtectedStaticEvent; + [KeptBackingField] + private static event EventHandler PrivateStaticEvent; + [KeptBackingField] + public static event EventHandler HideStaticEvent; + } + + + [Kept] + private static void RequirePublicNestedTypes ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class PublicNestedTypesBaseType + { + // Nested types are not propagated from base class at all + public class PublicBaseNestedType { } + protected class ProtectedBaseNestedType { } + private class PrivateBaseNestedType { } + public class HideBaseNestedType { } + public delegate int PublicDelegate (); + private delegate int PrivateDelegate (); + } + + [Kept] + [KeptBaseType (typeof (PublicNestedTypesBaseType))] + class PublicNestedTypesType : PublicNestedTypesBaseType + { + [Kept] + [KeptMember (".ctor()")] + public class PublicNestedType { } + protected class ProtectedNestedType { } + private class PrivateNestedType { } + [Kept] + [KeptMember (".ctor()")] + public class HideNestedType { } + + [Kept] + [KeptBaseType (typeof (MulticastDelegate))] + [KeptMember (".ctor(System.Object,System.IntPtr)")] + [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] [KeptMember ("EndInvoke(System.IAsyncResult)")] [KeptMember ("Invoke()")] public delegate int PublicDelegate (); @@ -1080,6 +1424,58 @@ public class HideNestedType { } private delegate int PrivateDelegate (); } + [Kept] + private static void RequirePublicNestedTypesWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class PublicNestedTypesWithInheritedBaseType + { + [Kept] + [KeptMember (".ctor()")] + public class PublicBaseNestedType { } + protected class ProtectedBaseNestedType { } + private class PrivateBaseNestedType { } + [Kept] + [KeptMember (".ctor()")] + public class HideBaseNestedType { } + [Kept] + [KeptBaseType (typeof (MulticastDelegate))] + [KeptMember (".ctor(System.Object,System.IntPtr)")] + [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] + [KeptMember ("EndInvoke(System.IAsyncResult)")] + [KeptMember ("Invoke()")] + public delegate int PublicDelegate (); + private delegate int PrivateDelegate (); + } + + [Kept] + [KeptBaseType (typeof (PublicNestedTypesWithInheritedBaseType))] + class PublicNestedTypesWithInheritedType : PublicNestedTypesWithInheritedBaseType + { + [Kept] + [KeptMember (".ctor()")] + public class PublicNestedType { } + protected class ProtectedNestedType { } + private class PrivateNestedType { } + [Kept] + [KeptMember (".ctor()")] + public class HideNestedType { } + + [Kept] + [KeptBaseType (typeof (MulticastDelegate))] + [KeptMember (".ctor(System.Object,System.IntPtr)")] + [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] + [KeptMember ("EndInvoke(System.IAsyncResult)")] + [KeptMember ("Invoke()")] + public delegate int PublicDelegate (); + + private delegate int PrivateDelegate (); + } [Kept] private static void RequireNonPublicNestedTypes ( @@ -1125,9 +1521,61 @@ public class HideNestedType { } private delegate int PrivateDelegate (); } + [Kept] + private static void RequireNonPublicNestedTypesWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class NonPublicNestedTypesWithInheritedBaseType + { + public class PublicBaseNestedType { } + [Kept] + [KeptMember (".ctor()")] + protected class ProtectedBaseNestedType { } + [Kept] + [KeptMember (".ctor()")] + private class PrivateBaseNestedType { } + public class HideBaseNestedType { } + public delegate int PublicDelegate (); + [Kept] + [KeptBaseType (typeof (MulticastDelegate))] + [KeptMember (".ctor(System.Object,System.IntPtr)")] + [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] + [KeptMember ("EndInvoke(System.IAsyncResult)")] + [KeptMember ("Invoke()")] + private delegate int PrivateDelegate (); + } [Kept] - private static void RequireAllNestedTypes ( + [KeptBaseType (typeof (NonPublicNestedTypesWithInheritedBaseType))] + class NonPublicNestedTypesWithInheritedType : NonPublicNestedTypesWithInheritedBaseType + { + public class PublicNestedType { } + [Kept] + [KeptMember (".ctor()")] + protected class ProtectedNestedType { } + [Kept] + [KeptMember (".ctor()")] + private class PrivateNestedType { } + public class HideNestedType { } + + public delegate int PublicDelegate (); + + [Kept] + [KeptBaseType (typeof (MulticastDelegate))] + [KeptMember (".ctor(System.Object,System.IntPtr)")] + [KeptMember ("BeginInvoke(System.AsyncCallback,System.Object)")] + [KeptMember ("EndInvoke(System.IAsyncResult)")] + [KeptMember ("Invoke()")] + private delegate int PrivateDelegate (); + } + + [Kept] + private static void RequirePublicAndNonPublicNestedTypes ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) @@ -1302,7 +1750,64 @@ public bool PublicPropertyOnlySetter { set { } } } [Kept] - private static void RequireAllProperties ( + private static void RequireNonPublicPropertiesWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class NonPublicPropertiesWithInheritedBaseType + { + public bool PublicPropertyOnBase { get; set; } + public bool PublicPropertyGetterOnBase { get { return false; } private set { } } + public bool PublicPropertySetterOnBase { private get { return false; } set { } } + public bool PublicPropertyOnlyGetterOnBase { get { return false; } } + public bool PublicPropertyOnlySetterOnBase { set { } } + [Kept] + protected bool ProtectedPropertyOnBase { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + [Kept] + private bool PrivatePropertyOnBase { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + public bool HideProperty { get; set; } + + static public bool PublicStaticPropertyOnBase { get; set; } + [Kept] + [KeptBackingField] + static protected bool ProtectedStaticPropertyOnBase { [Kept] get; [Kept] set; } + [Kept] + [KeptBackingField] + static private bool PrivateStaticPropertyOnBase { [Kept] get; [Kept] set; } + static public bool HideStaticProperty { get; set; } + } + + [Kept] + [KeptBaseType (typeof (NonPublicPropertiesWithInheritedBaseType))] + class NonPublicPropertiesWithInheritedType : NonPublicPropertiesWithInheritedBaseType + { + public bool PublicProperty { get; set; } + public bool PublicPropertyGetter { get { return false; } private set { } } + public bool PublicPropertySetter { private get { return false; } set { } } + public bool PublicPropertyOnlyGetter { get { return false; } } + public bool PublicPropertyOnlySetter { set { } } + [Kept] + protected bool ProtectedProperty { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + [Kept] + private bool PrivateProperty { [Kept][ExpectBodyModified] get; [Kept][ExpectBodyModified] set; } + public bool HideProperty { get; set; } + + static public bool PublicStaticProperty { get; set; } + [Kept] + [KeptBackingField] + static protected bool ProtectedStaticProperty { [Kept] get; [Kept] set; } + [Kept] + [KeptBackingField] + static private bool PrivateStaticProperty { [Kept] get; [Kept] set; } + static public bool HideStaticProperty { get; set; } + } + + [Kept] + private static void RequirePublicAndNonPublicProperties ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) @@ -1515,7 +2020,80 @@ class NonPublicEventsType : NonPublicEventsBaseType } [Kept] - private static void RequireAllEvents ( + private static void RequireNonPublicEventsWithInherited ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + class NonPublicEventsWithInheritedBaseType + { + public event EventHandler PublicEventOnBase; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + protected event EventHandler ProtectedEventOnBase; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + private event EventHandler PrivateEventOnBase; + public event EventHandler HideEvent; + + static public event EventHandler PublicStaticEventOnBase; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + static protected event EventHandler ProtectedStaticEventOnBase; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + static private event EventHandler PrivateStaticEventOnBase; + static public event EventHandler HideStaticEvent; + } + + [Kept] + [KeptBaseType (typeof (NonPublicEventsWithInheritedBaseType))] + class NonPublicEventsWithInheritedType : NonPublicEventsWithInheritedBaseType + { + public event EventHandler PublicEvent; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + protected event EventHandler ProtectedEvent; + [Kept] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + [method: ExpectBodyModified] + [method: ExpectLocalsModified] + private event EventHandler PrivateEvent; + public event EventHandler HideEvent; + + static public event EventHandler PublicStaticEvent; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + static protected event EventHandler ProtectedStaticEvent; + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + static private event EventHandler PrivateStaticEvent; + static public event EventHandler HideStaticEvent; + } + + [Kept] + private static void RequirePublicAndNonPublicEvents ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] Type type) diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs index 77c5aa15ca31b..cc21c3b62ea27 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs @@ -227,17 +227,25 @@ static void TestAll ( type.RequiresNone (); type.RequiresPublicParameterlessConstructor (); type.RequiresPublicConstructors (); + type.RequiresPublicConstructorsWithInherited (); type.RequiresNonPublicConstructors (); + type.RequiresNonPublicConstructorsWithInherited (); type.RequiresPublicMethods (); type.RequiresNonPublicMethods (); + type.RequiresNonPublicMethodsWithInherited (); type.RequiresPublicFields (); type.RequiresNonPublicFields (); + type.RequiresNonPublicFieldsWithInherited (); type.RequiresPublicNestedTypes (); + type.RequiresPublicNestedTypesWithInherited (); type.RequiresNonPublicNestedTypes (); + type.RequiresNonPublicNestedTypesWithInherited (); type.RequiresPublicProperties (); type.RequiresNonPublicProperties (); + type.RequiresNonPublicPropertiesWithInherited (); type.RequiresPublicEvents (); type.RequiresNonPublicEvents (); + type.RequiresNonPublicEventsWithInherited (); type.RequiresInterfaces (); } diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs index 445b1b6304dc5..4c5b2ca49aa8e 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs @@ -21,19 +21,27 @@ public static void Main () AllPropagatedWithDerivedClass.Test (); TestPublicConstructorsAreNotPropagated (typeof (TestType)); + TestPublicConstructorsWithInheritedArePropagated (typeof (TestType)); TestPublicEventsPropagated (typeof (TestType)); TestPublicFieldsPropagated (typeof (TestType)); TestPublicMethodsPropagated (typeof (TestType)); TestPublicNestedTypesAreNotPropagated (typeof (TestType)); + TestPublicNestedTypesWithInheritedArePropagated (typeof (TestType)); TestPublicParameterlessConstructorIsNotPropagated (typeof (TestType)); TestPublicPropertiesPropagated (typeof (TestType)); TestNonPublicConstructorsAreNotPropagated (typeof (TestType)); + TestNonPublicConstructorsWithInheritedArePropagated (typeof (TestType)); TestNonPublicEventsAreNotPropagated (typeof (TestType)); + TestNonPublicEventsWithInheritedArePropagated (typeof (TestType)); TestNonPublicFieldsAreNotPropagated (typeof (TestType)); + TestNonPublicFieldsWithInheritedArePropagated (typeof (TestType)); TestNonPublicMethodsAreNotPropagated (typeof (TestType)); + TestNonPublicMethodsWithInheritedArePropagated (typeof (TestType)); TestNonPublicNestedTypesAreNotPropagated (typeof (TestType)); + TestNonPublicNestedTypesWithInheritedArePropagated (typeof (TestType)); TestNonPublicPropertiesAreNotPropagated (typeof (TestType)); + TestNonPublicPropertiesWithInheritedArePropagated (typeof (TestType)); TestInterfacesPropagated (typeof (TestType)); @@ -74,9 +82,25 @@ public static void Test () } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructorsWithInherited))] static void TestPublicConstructorsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type derivedType) { derivedType.BaseType.RequiresPublicConstructors (); + derivedType.BaseType.RequiresPublicConstructorsWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructorsWithInherited))] + static void TestPublicConstructorsWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.PublicConstructorsWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresPublicConstructors (); + derivedType.BaseType.RequiresPublicConstructorsWithInherited (); + + // Should warn + derivedType.BaseType.RequiresNonPublicConstructors (); + + // Should warn + derivedType.BaseType.RequiresNonPublicConstructorsWithInherited (); } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] @@ -119,9 +143,25 @@ static void TestPublicMethodsPropagated ([DynamicallyAccessedMembers (Dynamicall } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicNestedTypesWithInherited))] static void TestPublicNestedTypesAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type derivedType) { derivedType.BaseType.RequiresPublicNestedTypes (); + derivedType.BaseType.RequiresPublicNestedTypesWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypesWithInherited))] + static void TestPublicNestedTypesWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.PublicNestedTypesWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresPublicNestedTypes (); + derivedType.BaseType.RequiresPublicNestedTypesWithInherited (); + + // Should warn + derivedType.BaseType.RequiresNonPublicNestedTypes (); + + // Should warn + derivedType.BaseType.RequiresNonPublicNestedTypesWithInherited (); } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor))] @@ -144,39 +184,119 @@ static void TestPublicPropertiesPropagated ([DynamicallyAccessedMembers (Dynamic } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructorsWithInherited))] static void TestNonPublicConstructorsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type derivedType) { derivedType.BaseType.RequiresNonPublicConstructors (); + derivedType.BaseType.RequiresNonPublicConstructorsWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructorsWithInherited))] + static void TestNonPublicConstructorsWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicConstructorsWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresNonPublicConstructors (); + derivedType.BaseType.RequiresNonPublicConstructorsWithInherited (); + + // Should warn + derivedType.BaseType.RequiresPublicConstructors (); + + // Should warn + derivedType.BaseType.RequiresPublicConstructorsWithInherited (); } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicEvents))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicEventsWithInherited))] static void TestNonPublicEventsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] Type derivedType) { derivedType.BaseType.RequiresNonPublicEvents (); + derivedType.BaseType.RequiresNonPublicEventsWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicEvents))] + static void TestNonPublicEventsWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicEventsWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresNonPublicEvents (); + derivedType.BaseType.RequiresNonPublicEventsWithInherited (); + + // Should warn + derivedType.BaseType.RequiresPublicEvents (); } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicFields))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicFieldsWithInherited))] static void TestNonPublicFieldsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] Type derivedType) { derivedType.BaseType.RequiresNonPublicFields (); + derivedType.BaseType.RequiresNonPublicFieldsWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicFields))] + static void TestNonPublicFieldsWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicFieldsWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresNonPublicFields (); + derivedType.BaseType.RequiresNonPublicFieldsWithInherited (); + + // Should warn + derivedType.BaseType.RequiresPublicFields (); } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicMethods))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicMethodsWithInherited))] static void TestNonPublicMethodsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] Type derivedType) { derivedType.BaseType.RequiresNonPublicMethods (); + derivedType.BaseType.RequiresNonPublicMethodsWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + static void TestNonPublicMethodsWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicMethodsWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresNonPublicMethods (); + derivedType.BaseType.RequiresNonPublicMethodsWithInherited (); + + // Should warn + derivedType.BaseType.RequiresPublicMethods (); } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypesWithInherited))] static void TestNonPublicNestedTypesAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] Type derivedType) { derivedType.BaseType.RequiresNonPublicNestedTypes (); + derivedType.BaseType.RequiresNonPublicNestedTypesWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicNestedTypesWithInherited))] + static void TestNonPublicNestedTypesWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicNestedTypesWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresNonPublicNestedTypes (); + derivedType.BaseType.RequiresNonPublicNestedTypesWithInherited (); + + // Should warn + derivedType.BaseType.RequiresPublicNestedTypes (); + + // Should warn + derivedType.BaseType.RequiresPublicNestedTypesWithInherited (); } [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicProperties))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicPropertiesWithInherited))] static void TestNonPublicPropertiesAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] Type derivedType) { derivedType.BaseType.RequiresNonPublicProperties (); + derivedType.BaseType.RequiresNonPublicPropertiesWithInherited (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicProperties))] + static void TestNonPublicPropertiesWithInheritedArePropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypesEx.NonPublicPropertiesWithInherited)] Type derivedType) + { + derivedType.BaseType.RequiresNonPublicProperties (); + derivedType.BaseType.RequiresNonPublicPropertiesWithInherited (); + + // Should warn + derivedType.BaseType.RequiresPublicProperties (); } static void TestInterfacesPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type derivedType) diff --git a/src/tools/illink/test/Mono.Linker.Tests/Tests/TestFrameworkRulesAndConventions.cs b/src/tools/illink/test/Mono.Linker.Tests/Tests/TestFrameworkRulesAndConventions.cs index 7dcfe9bfcddfa..e44d2cfe7c57d 100644 --- a/src/tools/illink/test/Mono.Linker.Tests/Tests/TestFrameworkRulesAndConventions.cs +++ b/src/tools/illink/test/Mono.Linker.Tests/Tests/TestFrameworkRulesAndConventions.cs @@ -76,6 +76,10 @@ static bool IsAcceptableExpectationsAssemblyType (TypeDefinition type) if (IsAttributeType (type)) return true; + // Extension types extending public enums + if (type.Name.EndsWith ("Ex") && type.IsAbstract && type.IsSealed) + return true; + // Anything else is not OK and should probably be defined in Mono.Linker.Tests.Cases and use SandboxDependency in order to be included // with the tests that need it return false;