diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs index 9dc4df8ff039c..b76e2a90e7a60 100644 --- a/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs @@ -67,6 +67,7 @@ public static void TestNull () { const string reflectionTypeKeptString = null; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] @@ -74,119 +75,180 @@ public static void TestEmptyString () { const string reflectionTypeKeptString = ""; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (Full))] public class Full { } [Kept] + [ExpectedWarning ("IL2026", nameof (Full), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestFullString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Full, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (Generic))] public class Generic { } [Kept] + [ExpectedWarning ("IL2026", "Generic", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestGenericString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Generic`1, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (GenericInstantiation))] public class GenericInstantiation { } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (GenericArgument))] public class GenericArgument { } [Kept] + [ExpectedWarning ("IL2026", "GenericInstantiation", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestGenericInstantiation () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiation`1[[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericArgument]]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (GenericInstantiationFullString))] public class GenericInstantiationFullString { } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (GenericArgumentFullString))] public class GenericArgumentFullString { } [Kept] + [ExpectedWarning ("IL2026", "GenericInstantiationFullString", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestGenericInstantiationFullString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiationFullString`1[" + "[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericArgumentFullString, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]" + "], test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (GenericInstantiationOverCoreLib))] public class GenericInstantiationOverCoreLib { } [Kept] + [ExpectedWarning ("IL2026", "GenericInstantiationOverCoreLib", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestGenericInstantiationOverCoreLib () { // Note: the argument type should not be assembly-qualified for this test, which is checking that // we can resolve non-assembly-qualified generic argument types from corelib. const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericInstantiationOverCoreLib`1[[System.String]], test"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (FullConst))] public class FullConst { } [Kept] + [ExpectedWarning ("IL2026", nameof (FullConst), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestFullStringConst () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+FullConst, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (TypeAsmName))] public class TypeAsmName { } [Kept] + [ExpectedWarning ("IL2026", nameof (TypeAsmName), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestTypeAsmName () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+TypeAsmName, test"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (AType))] public class AType { } [Kept] + [ExpectedWarning ("IL2026", nameof (AType), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] public static void TestType () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AType"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] +#if !NATIVEAOT // https://github.com/dotnet/runtime/issues/106214 + [KeptMember (".ctor()")] +#endif + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (Pointer))] public class Pointer { } [Kept] + [UnexpectedWarning ("IL2026", nameof (Pointer), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/106214")] public static void TestPointer () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Pointer*"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] +#if !NATIVEAOT // https://github.com/dotnet/runtime/issues/106214 + [KeptMember (".ctor()")] +#endif + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (Reference))] public class Reference { } [Kept] + [UnexpectedWarning ("IL2026", nameof (Reference), Tool.Trimmer, "https://github.com/dotnet/runtime/issues/106214")] public static void TestReference () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Reference&"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (Array))] public class Array { } [Kept] @@ -194,9 +256,12 @@ public static void TestArray () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Array[]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (ArrayOfArray))] public class ArrayOfArray { } [Kept] @@ -204,10 +269,13 @@ public static void TestArrayOfArray () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+ArrayOfArray[][]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (MultiDimensionalArray))] public class MultiDimensionalArray { } [Kept] @@ -215,9 +283,12 @@ public static void TestMultiDimensionalArray () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+MultiDimensionalArray[,]"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (MultiDimensionalArrayFullString))] public class MultiDimensionalArrayFullString { } [Kept] @@ -225,9 +296,12 @@ public static void TestMultiDimensionalArrayFullString () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+MultiDimensionalArrayFullString[,], test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (MultiDimensionalArrayAsmName))] public class MultiDimensionalArrayAsmName { } [Kept] @@ -235,6 +309,7 @@ public static void TestMultiDimensionalArrayAsmName () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+MultiDimensionalArrayAsmName[,], test"; var typeKept = Type.GetType (reflectionTypeKeptString, false); + RequireConstructor (typeKept); } [Kept] @@ -244,6 +319,9 @@ class Nested1 class N2 { [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (N3))] class N3 { } @@ -251,26 +329,39 @@ class N3 } [Kept] + [ExpectedWarning ("IL2026", "N3", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestDeeplyNested () { var typeKept = Type.GetType ("Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+Nested1+N2+N3"); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] class TypeOfToKeep { } [Kept] static void TestTypeOf () { var typeKept = typeof (TypeOfToKeep); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (TypeFromBranchA))] class TypeFromBranchA { } + [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (TypeFromBranchB))] class TypeFromBranchB { } [Kept] + [ExpectedWarning ("IL2026", nameof (TypeFromBranchA), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning ("IL2026", nameof (TypeFromBranchB), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestTypeFromBranch (int b) { string name = null; @@ -286,6 +377,7 @@ static void TestTypeFromBranch (int b) } var typeKept = Type.GetType (name); + RequireConstructor (typeKept); } public class CaseInsensitive { } @@ -308,6 +400,7 @@ static void TestTypeUsingCaseUnknownByTheLinker () bool hideCase = GetCase (); const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false, hideCase); + RequireConstructor (typeKept); } [Kept] @@ -327,27 +420,38 @@ static void TestTypeUsingCaseUnknownByTheLinker2 () { const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; var typeKept = Type.GetType (reflectionTypeKeptString, false, fieldHideCase); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (OverloadWith3Parameters))] public class OverloadWith3Parameters { } [Kept] + [ExpectedWarning ("IL2026", nameof (OverloadWith3Parameters), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestTypeOverloadWith3Parameters () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith3Parameters"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (OverloadWith3Parameters))] public class OverloadWith4Parameters { } [Kept] + [ExpectedWarning ("IL2026", nameof (OverloadWith4Parameters), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestTypeOverloadWith4Parameters () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith4Parameters"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false); + RequireConstructor (typeKept); } public class OverloadWith5ParametersWithIgnoreCase { } @@ -361,16 +465,22 @@ static void TestTypeOverloadWith5ParametersWithIgnoreCase () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith5ParametersWithIgnoreCase"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false, true); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (OverloadWith3Parameters))] public class OverloadWith5ParametersWithoutIgnoreCase { } [Kept] + [ExpectedWarning ("IL2026", nameof (OverloadWith5ParametersWithoutIgnoreCase), Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestTypeOverloadWith5ParametersWithoutIgnoreCase () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith5ParametersWithoutIgnoreCase"; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false, false); + RequireConstructor (typeKept); } /// @@ -415,16 +525,22 @@ static void TestUnknownIgnoreCase5Params (int num) const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; bool unknownValue = num + 1 == 1; var typeKept = Type.GetType (reflectionTypeKeptString, AssemblyResolver, GetTypeFromAssembly, false, unknownValue); + RequireConstructor (typeKept); } [Kept] + [KeptMember (".ctor()")] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (OverloadWith3Parameters))] public class GenericTypeWithAnnotations_OuterType< [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] T> + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] T> { } [Kept] + [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] + [RequiresUnreferencedCode (nameof (OverloadWith3Parameters))] public class GenericTypeWithAnnotations_InnerType { [Kept] @@ -435,12 +551,16 @@ private static void PrivateMethod () { } } [Kept] + [ExpectedWarning ("IL2026", "GenericTypeWithAnnotations_OuterType", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning ("IL2026", nameof (GenericTypeWithAnnotations_InnerType), "PrivateProperty.get", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] + [ExpectedWarning ("IL2026", nameof (GenericTypeWithAnnotations_InnerType), "PrivateProperty.set", Tool.Trimmer | Tool.NativeAot, "https://github.com/dotnet/runtime/issues/95118")] static void TestGenericTypeWithAnnotations () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericTypeWithAnnotations_OuterType`1[" + "[Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+GenericTypeWithAnnotations_InnerType, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]" + "], test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; - Type.GetType (reflectionTypeKeptString); + var typeKept = Type.GetType (reflectionTypeKeptString); + RequireConstructor (typeKept); } [Kept] @@ -493,8 +613,11 @@ static void TestInvalidTypeCombination () static void TestEscapedTypeName () { var typeKept = Type.GetType ("Library.Not\\+Nested, EscapedTypeNames"); + RequireConstructor (typeKept); typeKept = Type.GetType ("Library.Not\\+Nested+Nes\\\\ted, EscapedTypeNames"); + RequireConstructor (typeKept); typeKept = Type.GetType ("Library.Not\\+Nested+Nes/ted, EscapedTypeNames"); + RequireConstructor (typeKept); } [Kept] @@ -562,5 +685,11 @@ class PointerElementGenericArgumentType {} class ByRefElementGenericArgumentType {} } + + [Kept] + static void RequireConstructor ( + [KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + Type type) { } } }