diff options
Diffstat (limited to 'test/Mono.Linker.Tests.Cases/DataFlow')
3 files changed, 508 insertions, 1 deletions
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs new file mode 100644 index 000000000..630fc3c14 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs @@ -0,0 +1,142 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class GetInterfaceDataFlow + { + public static void Main () + { + GetInterface_Name.Test (); + GetInterface_Name_IgnoreCase.Test (); + } + + class GetInterface_Name + { + [ExpectedWarning ("IL2070", nameof (Type.GetInterface), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))] + static void TestNoAnnotation (Type type) + { + type.GetInterface ("ITestInterface"); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestWithAnnotation ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.GetInterface ("ITestInterface").RequiresInterfaces (); + type.GetInterface ("ITestInterface").RequiresAll (); // Warns + } + + static void TestWithAll ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) + { + type.GetInterface ("ITestInterface").RequiresInterfaces (); + type.GetInterface ("ITestInterface").RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestKnownType () + { + // Interfaces marking is transitive - meaning that it marks all interfaces in the entire hierarchy + // so the return value of GetInterface always has all interfaces on it already. + typeof (TestType).GetInterface ("ITestInterface").RequiresInterfaces (); + typeof (TestType).GetInterface ("ITestInterface").RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestMultipleValues (int p, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeWithAll) + { + Type type; + if (p == 0) + type = typeof (TestType); + else + type = typeWithAll; + + type.GetInterface ("ITestInterface").RequiresInterfaces (); + type.GetInterface ("ITestInterface").RequiresAll (); // Warns since only one of the values is guaranteed All + } + + public static void Test () + { + TestNoAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (ITestInterface)); + TestWithAll (typeof (TestType)); + TestKnownType (); + TestMultipleValues (0, typeof (TestType)); + } + } + + class GetInterface_Name_IgnoreCase + { + [ExpectedWarning ("IL2070", nameof (Type.GetInterface), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))] + static void TestNoAnnotation (Type type) + { + type.GetInterface ("ITestInterface", false); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestWithAnnotation ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.GetInterface ("ITestInterface", false).RequiresInterfaces (); + type.GetInterface ("ITestInterface", false).RequiresAll (); // Warns + } + + static void TestWithAll ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) + { + type.GetInterface ("ITestInterface", false).RequiresInterfaces (); + type.GetInterface ("ITestInterface", false).RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestKnownType () + { + // Interfaces marking is transitive - meaning that it marks all interfaces in the entire hierarchy + // so the return value of GetInterface always has all interfaces on it already. + typeof (TestType).GetInterface ("ITestInterface", false).RequiresInterfaces (); + typeof (TestType).GetInterface ("ITestInterface", false).RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestMultipleValues (int p, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeWithAll) + { + Type type; + if (p == 0) + type = typeof (TestType); + else + type = typeWithAll; + + type.GetInterface ("ITestInterface", false).RequiresInterfaces (); + type.GetInterface ("ITestInterface", false).RequiresAll (); // Warns since only one of the values is guaranteed All + } + + public static void Test () + { + TestNoAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (ITestInterface)); + TestWithAll (typeof (TestType)); + TestKnownType (); + TestMultipleValues (0, typeof (TestType)); + } + } + + interface ITestInterface + { + } + + class TestType : ITestInterface + { + } + } +} diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs index d0b51abf5..d28c3ed54 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs @@ -42,6 +42,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow RequirePublicEvents (typeof (PublicEventsType)); RequireNonPublicEvents (typeof (NonPublicEventsType)); RequireAllEvents (typeof (AllEventsType)); + RequireInterfaces (typeof (InterfacesType)); RequireAll (typeof (AllType)); RequireAll (typeof (RequireAllWithRecursiveTypeReferences)); } @@ -1565,6 +1566,94 @@ namespace Mono.Linker.Tests.Cases.DataFlow static public event EventHandler<EventArgs> HideStaticEvent; } + [Kept] + private static void RequireInterfaces ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] + [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] + Type type) + { + } + + [Kept] + interface IInterfaceOnBaseBase + { + } + + [Kept] + [KeptInterface (typeof (IInterfaceOnBaseBase))] + interface IInterfacesOnBase : IInterfaceOnBaseBase + { + void OnBaseInterfaceMethod (); + } + + [Kept] + [KeptInterface (typeof (IInterfacesOnBase))] // Interface implementations are collected across all base types, so this one has to be included as well + [KeptInterface (typeof (IInterfaceOnBaseBase))] // Roslyn adds transitively implemented interfaces automatically + class InterfacesBaseType : IInterfacesOnBase + { + public void OnBaseInterfaceMethod () { } + } + + [Kept] + interface IInterfacesEmpty + { + } + + [Kept] + interface IInterfacesWithMethods + { + void InterfaceMethod (); + } + + [Kept] + interface IInterfaceGeneric<T> + { + void GenericMethod<U> (T t, U u); + } + + [Kept] + interface IInterfacesBase + { + void BaseMethod (); + } + + [Kept] + [KeptInterface (typeof (IInterfacesBase))] + interface IInterfacesDerived : IInterfacesBase + { + void DerivedMethod (); + } + + interface IInterfacesSuperDerived : IInterfacesDerived + { + void SuperDerivedMethod (); + } + + [Kept] + [KeptInterface (typeof (IInterfacesEmpty))] + [KeptInterface (typeof (IInterfacesWithMethods))] + [KeptInterface (typeof (IInterfacesBase))] // Roslyn adds transitively implemented interfaces automatically + [KeptInterface (typeof (IInterfacesDerived))] + [KeptInterface (typeof (IInterfaceGeneric<int>))] + [KeptBaseType (typeof (InterfacesBaseType))] + class InterfacesType : InterfacesBaseType, IInterfacesEmpty, IInterfacesWithMethods, IInterfacesDerived, IInterfaceGeneric<int> + { + public void InterfaceMethod () + { + } + + public void BaseMethod () + { + } + + public void DerivedMethod () + { + } + + public void GenericMethod<U> (int t, U u) + { + } + } [Kept] private static void RequireAll ( @@ -1575,7 +1664,29 @@ namespace Mono.Linker.Tests.Cases.DataFlow } [Kept] - class AllBaseType + interface IAllBaseGenericInterface<T> + { + [Kept] + void BaseInterfaceMethod (); + [Kept] + void BaseDefaultMethod () { } + } + + [Kept] + [KeptInterface (typeof (IAllBaseGenericInterface<Int64>))] + interface IAllDerivedInterface : IAllBaseGenericInterface<Int64> + { + [Kept] + void DerivedInterfaceMethod (); + + [Kept] + void DerivedDefaultMethod () { } + } + + [Kept] + [KeptInterface (typeof (IAllDerivedInterface))] + [KeptInterface (typeof (IAllBaseGenericInterface<Int64>))] + class AllBaseType : IAllDerivedInterface { // This is different from all of the above cases. // All means really everything - so we include everything on base class as well - including private stuff @@ -1639,6 +1750,11 @@ namespace Mono.Linker.Tests.Cases.DataFlow public static void HideStaticMethod () { } [Kept] + public void DerivedInterfaceMethod () { } + [Kept] + public void BaseInterfaceMethod () { } + + [Kept] [KeptBackingField] static public bool PublicStaticPropertyOnBase { [Kept] get; [Kept] set; } [Kept] diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs new file mode 100644 index 000000000..a16ffd9ef --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs @@ -0,0 +1,249 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class MemberTypesRelationships + { + public static void Main () + { + TestPublicParameterlessConstructor (typeof (TestType)); + TestPublicConstructors (typeof (TestType)); + TestNonPublicConstructors (typeof (TestType)); + TestPublicMethods (typeof (TestType)); + TestNonPublicMethods (typeof (TestType)); + TestPublicFields (typeof (TestType)); + TestNonPublicFields (typeof (TestType)); + TestPublicNestedTypes (typeof (TestType)); + TestNonPublicNestedTypes (typeof (TestType)); + TestPublicProperties (typeof (TestType)); + TestNonPublicProperties (typeof (TestType)); + TestPublicEvents (typeof (TestType)); + TestNonPublicEvents (typeof (TestType)); + TestInterfaces (typeof (TestType)); + TestAll (typeof (TestType)); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestPublicParameterlessConstructor ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type) + { + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); // Warns + type.RequiresNonPublicConstructors (); // Warns + type.RequiresNone (); + type.RequiresPublicMethods (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestPublicConstructors ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + { + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); // Warns + type.RequiresNone (); + type.RequiresPublicMethods (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestNonPublicConstructors ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) + { + type.RequiresPublicParameterlessConstructor (); // Warns + type.RequiresPublicConstructors (); // Warns + type.RequiresNonPublicConstructors (); + type.RequiresNone (); + type.RequiresPublicMethods (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestPublicMethods ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + type.RequiresPublicMethods (); + type.RequiresNonPublicMethods (); // Warns + type.RequiresNone (); + type.RequiresPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestNonPublicMethods ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] Type type) + { + type.RequiresPublicMethods (); // Warns + type.RequiresNonPublicMethods (); + type.RequiresNone (); + type.RequiresNonPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestPublicFields ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type) + { + type.RequiresPublicFields (); + type.RequiresNonPublicFields (); // Warns + type.RequiresNone (); + type.RequiresPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestNonPublicFields ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] Type type) + { + type.RequiresPublicFields (); // Warns + type.RequiresNonPublicFields (); + type.RequiresNone (); + type.RequiresNonPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresInterfaces))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestPublicNestedTypes ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type type) + { + type.RequiresPublicNestedTypes (); + type.RequiresNonPublicNestedTypes (); // Warns + type.RequiresNone (); + type.RequiresInterfaces (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresInterfaces))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestNonPublicNestedTypes ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] Type type) + { + type.RequiresPublicNestedTypes (); // Warns + type.RequiresNonPublicNestedTypes (); + type.RequiresNone (); + type.RequiresInterfaces (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicProperties))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestPublicProperties ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) + { + type.RequiresPublicProperties (); + type.RequiresNonPublicProperties (); // Warns + type.RequiresNone (); + type.RequiresPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicProperties))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestNonPublicProperties ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) + { + type.RequiresPublicProperties (); // Warns + type.RequiresNonPublicProperties (); + type.RequiresNone (); + type.RequiresNonPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicEvents))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestPublicEvents ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] Type type) + { + type.RequiresPublicEvents (); + type.RequiresNonPublicEvents (); // Warns + type.RequiresNone (); + type.RequiresPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicEvents))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestNonPublicEvents ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] Type type) + { + type.RequiresPublicEvents (); // Warns + type.RequiresNonPublicEvents (); + type.RequiresNone (); + type.RequiresNonPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestInterfaces ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.RequiresInterfaces (); + type.RequiresNone (); + type.RequiresPublicNestedTypes (); // Warns + type.RequiresNonPublicNestedTypes (); // Warns + type.RequiresAll (); // Warns + } + + static void TestAll ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) + { + type.RequiresAll (); + type.RequiresNone (); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresPublicMethods (); + type.RequiresNonPublicMethods (); + type.RequiresPublicFields (); + type.RequiresNonPublicFields (); + type.RequiresPublicNestedTypes (); + type.RequiresNonPublicNestedTypes (); + type.RequiresPublicProperties (); + type.RequiresNonPublicProperties (); + type.RequiresPublicEvents (); + type.RequiresNonPublicEvents (); + type.RequiresInterfaces (); + } + + class TestType { } + } +} |