Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLakshan Fernando <lakshanf@hotmail.com>2022-02-01 03:27:34 +0300
committerGitHub <noreply@github.com>2022-02-01 03:27:34 +0300
commit56421a1b1c1713d9d02567f481595d6b7b5ac000 (patch)
treec308034fe957e46dd37adb60844c25a653d60e36 /test/Mono.Linker.Tests.Cases/DataFlow
parentf6fde401e2841726ac04fcc37a34ce402ac800c6 (diff)
generic type annotation (#2478)
* generic type annotation - take 1 * fb * FB2 * Using Syntax API and refactored GenericParameterDataFlow test into 2 * incorprate FB * fix remaining issues * CI build break fix * FB * FB * FB * enhanced comments
Diffstat (limited to 'test/Mono.Linker.Tests.Cases/DataFlow')
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs808
-rw-r--r--test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs501
2 files changed, 684 insertions, 625 deletions
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs
index f94b62a0c..0c6a77867 100644
--- a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs
@@ -25,9 +25,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow
TestMultipleGenericParametersOnMethod ();
TestMethodGenericParametersViaInheritance ();
- MakeGenericType.Test ();
- MakeGenericMethod.Test ();
-
TestNewConstraintSatisfiesParameterlessConstructor<object> ();
TestStructConstraintSatisfiesParameterlessConstructor<TestStruct> ();
TestUnmanagedConstraintSatisfiesParameterlessConstructor<byte> ();
@@ -45,11 +42,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow
TypeRequiresNothingPassThrough<TestType>.Test ();
}
- static void TestGenericParameterFlowsToField ()
- {
- TypeRequiresPublicFields<TestType>.TestFields ();
- }
-
static void TestGenericParameterFlowsToReturnValue ()
{
_ = TypeRequiresPublicFields<TestType>.ReturnRequiresPublicFields ();
@@ -65,6 +57,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
static Type FieldRequiresNothing;
+
class TypeRequiresPublicFields<
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
{
@@ -84,21 +77,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow
FieldRequiresNothing = typeof (T);
}
-
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
public static Type ReturnRequiresPublicFields ()
{
return typeof (T);
}
-
[ExpectedWarning ("IL2088", "'" + nameof (T) + "'", nameof (TypeRequiresPublicFields<T>), nameof (ReturnRequiresPublicMethods))]
[return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]
public static Type ReturnRequiresPublicMethods ()
{
return typeof (T);
}
-
public static Type ReturnRequiresNothing ()
{
return typeof (T);
@@ -156,6 +146,77 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
}
+ static void TestBaseTypeGenericRequirements ()
+ {
+ new DerivedTypeWithInstantiatedGenericOnBase ();
+ new DerivedTypeWithInstantiationOverSelfOnBase ();
+ new DerivedTypeWithOpenGenericOnBase<TestType> ();
+ TestDerivedTypeWithOpenGenericOnBaseWithRUCOnBase ();
+ TestDerivedTypeWithOpenGenericOnBaseWithRUCOnDerived ();
+ new DerivedTypeWithOpenGenericOnBaseWithRequirements<TestType> ();
+ }
+
+ class GenericBaseTypeWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
+ {
+ public GenericBaseTypeWithRequirements ()
+ {
+ typeof (T).RequiresPublicFields ();
+ }
+ }
+
+ class DerivedTypeWithInstantiatedGenericOnBase : GenericBaseTypeWithRequirements<TestType>
+ {
+ }
+
+ class DerivedTypeWithInstantiationOverSelfOnBase : GenericBaseTypeWithRequirements<DerivedTypeWithInstantiationOverSelfOnBase>
+ {
+ }
+
+ [ExpectedWarning ("IL2091", nameof (GenericBaseTypeWithRequirements<T>))]
+ class DerivedTypeWithOpenGenericOnBase<T> : GenericBaseTypeWithRequirements<T>
+ {
+ // Analyzer does not see the base class constructor
+ [ExpectedWarning ("IL2091", nameof (GenericBaseTypeWithRequirements<T>), ProducedBy = ProducedBy.Trimmer)]
+ public DerivedTypeWithOpenGenericOnBase () { }
+ }
+
+ static void TestDerivedTypeWithOpenGenericOnBaseWithRUCOnBase ()
+ {
+ new DerivedTypeWithOpenGenericOnBaseWithRUCOnBase<TestType> ();
+ }
+
+ [ExpectedWarning ("IL2109", nameof (BaseTypeWithOpenGenericDAMTAndRUC<T>))]
+ [ExpectedWarning ("IL2091", nameof (BaseTypeWithOpenGenericDAMTAndRUC<T>))]
+ class DerivedTypeWithOpenGenericOnBaseWithRUCOnBase<T> : BaseTypeWithOpenGenericDAMTAndRUC<T>
+ {
+ [ExpectedWarning ("IL2091", nameof (DerivedTypeWithOpenGenericOnBaseWithRUCOnBase<T>), ProducedBy = ProducedBy.Trimmer)]
+ [ExpectedWarning ("IL2026", nameof (BaseTypeWithOpenGenericDAMTAndRUC<T>), ProducedBy = ProducedBy.Trimmer)]
+ public DerivedTypeWithOpenGenericOnBaseWithRUCOnBase () { }
+ }
+
+ [RequiresUnreferencedCode ("RUC")]
+ class BaseTypeWithOpenGenericDAMTAndRUC<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] T> { }
+
+
+ [ExpectedWarning ("IL2026", nameof (DerivedTypeWithOpenGenericOnBaseWithRUCOnDerived<TestType>))]
+ static void TestDerivedTypeWithOpenGenericOnBaseWithRUCOnDerived ()
+ {
+ new DerivedTypeWithOpenGenericOnBaseWithRUCOnDerived<TestType> ();
+ }
+ [ExpectedWarning ("IL2091", nameof (BaseTypeWithOpenGenericDAMT<T>))]
+ [RequiresUnreferencedCode ("RUC")]
+ class DerivedTypeWithOpenGenericOnBaseWithRUCOnDerived<T> : BaseTypeWithOpenGenericDAMT<T>
+ {
+ }
+
+ class BaseTypeWithOpenGenericDAMT<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] T> { }
+
+
+ class DerivedTypeWithOpenGenericOnBaseWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
+ : GenericBaseTypeWithRequirements<T>
+ {
+ }
+
static void TestMultipleGenericParametersOnType ()
{
MultipleTypesWithDifferentRequirements<TestType, TestType, TestType, TestType>.TestMultiple ();
@@ -216,46 +277,27 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
}
- static void TestBaseTypeGenericRequirements ()
+ static void TestDeepNestedTypesWithGenerics ()
{
- new DerivedTypeWithInstantiatedGenericOnBase ();
- new DerivedTypeWithInstantiationOverSelfOnBase ();
- new DerivedTypeWithOpenGenericOnBase<TestType> ();
- new DerivedTypeWithOpenGenericOnBaseWithRequirements<TestType> ();
+ RootTypeWithRequirements<TestType>.InnerTypeWithNoAddedGenerics.TestAccess ();
}
- class GenericBaseTypeWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
+ class RootTypeWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TRoot>
{
- public GenericBaseTypeWithRequirements ()
+ public class InnerTypeWithNoAddedGenerics
{
- typeof (T).RequiresPublicFields ();
+ [ExpectedWarning ("IL2087", nameof (TRoot),
+ "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.RootTypeWithRequirements<TRoot>",
+ "type",
+ "DataFlowTypeExtensions.RequiresPublicMethods(Type)")]
+ public static void TestAccess ()
+ {
+ typeof (TRoot).RequiresPublicFields ();
+ typeof (TRoot).RequiresPublicMethods ();
+ }
}
}
- class DerivedTypeWithInstantiatedGenericOnBase : GenericBaseTypeWithRequirements<TestType>
- {
- }
-
- class GenericBaseTypeWithRequiresAll<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] T>
- {
- }
-
- class DerivedTypeWithInstantiationOverSelfOnBase : GenericBaseTypeWithRequirements<DerivedTypeWithInstantiationOverSelfOnBase>
- {
- }
-
- [ExpectedWarning ("IL2091", nameof (GenericBaseTypeWithRequirements<T>))]
- class DerivedTypeWithOpenGenericOnBase<T> : GenericBaseTypeWithRequirements<T>
- {
- [ExpectedWarning ("IL2091", nameof (GenericBaseTypeWithRequirements<T>))]
- public DerivedTypeWithOpenGenericOnBase () { }
- }
-
- class DerivedTypeWithOpenGenericOnBaseWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
- : GenericBaseTypeWithRequirements<T>
- {
- }
-
static void TestInterfaceTypeGenericRequirements ()
{
IGenericInterfaceTypeWithRequirements<TestType> instance = new InterfaceImplementationTypeWithInstantiatedGenericOnBase ();
@@ -284,35 +326,11 @@ namespace Mono.Linker.Tests.Cases.DataFlow
class InterfaceImplementationTypeWithOpenGenericOnBase<T> : IGenericInterfaceTypeWithRequirements<T>
{
}
-
class InterfaceImplementationTypeWithOpenGenericOnBaseWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
: IGenericInterfaceTypeWithRequirements<T>
{
}
- static void TestDeepNestedTypesWithGenerics ()
- {
- RootTypeWithRequirements<TestType>.InnerTypeWithNoAddedGenerics.TestAccess ();
- }
-
- class RootTypeWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TRoot>
- {
- public class InnerTypeWithNoAddedGenerics
- {
- // The message is not ideal since we report the TRoot to come from RootTypeWithRequirements/InnerTypeWIthNoAddedGenerics
- // while it originates on RootTypeWithRequirements, but it's correct from IL's point of view.
- [ExpectedWarning ("IL2087", nameof (TRoot),
- "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.RootTypeWithRequirements<TRoot>.InnerTypeWithNoAddedGenerics",
- "type",
- "DataFlowTypeExtensions.RequiresPublicMethods(Type)")]
- public static void TestAccess ()
- {
- typeof (TRoot).RequiresPublicFields ();
- typeof (TRoot).RequiresPublicMethods ();
- }
- }
- }
-
static void TestTypeGenericRequirementsOnMembers ()
{
// Basically just root everything we need to test
@@ -348,10 +366,11 @@ namespace Mono.Linker.Tests.Cases.DataFlow
set;
}
+ [ExpectedWarning ("IL2091", nameof (TypeGenericRequirementsOnMembers<TOuter>), ProducedBy = ProducedBy.Analyzer)]
public TypeRequiresPublicMethods<TOuter> PublicMethodsProperty {
- [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))]
+ [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>), ProducedBy = ProducedBy.Trimmer)]
get => null;
- [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))]
+ [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>), ProducedBy = ProducedBy.Trimmer)]
set { }
}
@@ -360,8 +379,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
public void PublicMethodsMethodParameter (TypeRequiresPublicMethods<TOuter> param) { }
public TypeRequiresPublicFields<TOuter> PublicFieldsMethodReturnValue () { return null; }
- [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))] // Return value
- [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))] // Compiler generated local variable
+
+ [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>), ProducedBy = ProducedBy.Trimmer)]
+ [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))]
public TypeRequiresPublicMethods<TOuter> PublicMethodsMethodReturnValue () { return null; }
public void PublicFieldsMethodLocalVariable ()
@@ -404,7 +424,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow
class PartialyInstantiatedMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TOuter>
: BaseForPartialInstantiation<TestType, TOuter>
{
- [ExpectedWarning ("IL2091", nameof (BaseForPartialInstantiation<TestType, TOuter>), "'TMethods'")]
+ // Analyzer does not see the base class constructor
+ [ExpectedWarning ("IL2091", nameof (BaseForPartialInstantiation<TestType, TOuter>), "'TMethods'", ProducedBy = ProducedBy.Trimmer)]
public PartialyInstantiatedMethods () { }
}
@@ -467,6 +488,79 @@ namespace Mono.Linker.Tests.Cases.DataFlow
MethodRequiresNothing<T> ();
}
+ static void TestMultipleGenericParametersOnMethod ()
+ {
+ MethodMultipleWithDifferentRequirements_TestMultiple<TestType, TestType, TestType, TestType> ();
+ MethodMultipleWithDifferentRequirements_TestFields<TestType, TestType, TestType, TestType> ();
+ MethodMultipleWithDifferentRequirements_TestMethods<TestType, TestType, TestType, TestType> ();
+ MethodMultipleWithDifferentRequirements_TestBoth<TestType, TestType, TestType, TestType> ();
+ MethodMultipleWithDifferentRequirements_TestNothing<TestType, TestType, TestType, TestType> ();
+ }
+
+ static void MethodMultipleWithDifferentRequirements_TestMultiple<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
+ TNothing> ()
+ {
+ typeof (TFields).RequiresPublicFields (); ;
+ typeof (TMethods).RequiresPublicMethods ();
+ typeof (TBoth).RequiresPublicFields (); ;
+ typeof (TBoth).RequiresPublicMethods ();
+ typeof (TFields).RequiresNone ();
+ typeof (TMethods).RequiresNone ();
+ typeof (TBoth).RequiresNone ();
+ typeof (TNothing).RequiresNone ();
+ }
+
+ [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))]
+ static void MethodMultipleWithDifferentRequirements_TestFields<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
+ TNothing> ()
+ {
+ typeof (TFields).RequiresPublicFields (); ;
+ typeof (TFields).RequiresPublicMethods ();
+ typeof (TFields).RequiresNone ();
+ }
+
+ [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))]
+ static void MethodMultipleWithDifferentRequirements_TestMethods<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
+ TNothing> ()
+ {
+ typeof (TMethods).RequiresPublicFields ();
+ typeof (TMethods).RequiresPublicMethods ();
+ typeof (TMethods).RequiresNone ();
+ }
+
+ static void MethodMultipleWithDifferentRequirements_TestBoth<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
+ TNothing> ()
+ {
+ typeof (TBoth).RequiresPublicFields ();
+ typeof (TBoth).RequiresPublicMethods ();
+ typeof (TBoth).RequiresNone ();
+ }
+
+ [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))]
+ [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))]
+ static void MethodMultipleWithDifferentRequirements_TestNothing<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
+ TNothing> ()
+ {
+ typeof (TNothing).RequiresPublicFields ();
+ typeof (TNothing).RequiresPublicMethods ();
+ typeof (TNothing).RequiresNone ();
+ }
+
static void TestMethodGenericParametersViaInheritance ()
{
TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticRequiresPublicFields<TestType> ();
@@ -501,9 +595,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow
public static void StaticRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ()
=> typeof (T).RequiresPublicMethods ();
- public void InstanceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]T> ()
+ public void InstanceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ()
=> typeof (T).RequiresPublicMethods ();
- public virtual void VirtualRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]T> ()
+ public virtual void VirtualRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ()
=> typeof (T).RequiresPublicMethods ();
public static void StaticRequiresMultipleGenericParams<
@@ -521,6 +615,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow
void InterfaceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> ();
}
+
class TypeWithInstantiatedGenericMethodViaGenericParameter<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TOuter>
: BaseTypeWithGenericMethod, IInterfaceWithGenericMethod
{
@@ -552,10 +647,17 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
[ExpectedWarning ("IL2091",
+ nameof (TOuter),
+ "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>",
+ "TMethods",
+ "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams<TFields, TMethods>()",
+ ProducedBy = ProducedBy.Analyzer)]
+ [ExpectedWarning ("IL2091",
"'TOuter'",
"Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>",
"'TMethods'",
- "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams<TFields,TMethods>()")]
+ "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams<TFields,TMethods>()",
+ ProducedBy = ProducedBy.Trimmer)]
public static void StaticPartialInstantiationUnrecognized ()
{
StaticRequiresMultipleGenericParams<TestType, TOuter> ();
@@ -616,554 +718,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow
}
}
-
- static void TestMultipleGenericParametersOnMethod ()
- {
- MethodMultipleWithDifferentRequirements_TestMultiple<TestType, TestType, TestType, TestType> ();
- MethodMultipleWithDifferentRequirements_TestFields<TestType, TestType, TestType, TestType> ();
- MethodMultipleWithDifferentRequirements_TestMethods<TestType, TestType, TestType, TestType> ();
- MethodMultipleWithDifferentRequirements_TestBoth<TestType, TestType, TestType, TestType> ();
- MethodMultipleWithDifferentRequirements_TestNothing<TestType, TestType, TestType, TestType> ();
- }
-
- static void MethodMultipleWithDifferentRequirements_TestMultiple<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
- TNothing> ()
- {
- typeof (TFields).RequiresPublicFields (); ;
- typeof (TMethods).RequiresPublicMethods ();
- typeof (TBoth).RequiresPublicFields (); ;
- typeof (TBoth).RequiresPublicMethods ();
- typeof (TFields).RequiresNone ();
- typeof (TMethods).RequiresNone ();
- typeof (TBoth).RequiresNone ();
- typeof (TNothing).RequiresNone ();
- }
-
- [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))]
- static void MethodMultipleWithDifferentRequirements_TestFields<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
- TNothing> ()
- {
- typeof (TFields).RequiresPublicFields (); ;
- typeof (TFields).RequiresPublicMethods ();
- typeof (TFields).RequiresNone ();
- }
-
- [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))]
- static void MethodMultipleWithDifferentRequirements_TestMethods<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
- TNothing> ()
- {
- typeof (TMethods).RequiresPublicFields ();
- typeof (TMethods).RequiresPublicMethods ();
- typeof (TMethods).RequiresNone ();
- }
-
- static void MethodMultipleWithDifferentRequirements_TestBoth<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
- TNothing> ()
- {
- typeof (TBoth).RequiresPublicFields ();
- typeof (TBoth).RequiresPublicMethods ();
- typeof (TBoth).RequiresNone ();
- }
-
- [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))]
- [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))]
- static void MethodMultipleWithDifferentRequirements_TestNothing<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth,
- TNothing> ()
- {
- typeof (TNothing).RequiresPublicFields ();
- typeof (TNothing).RequiresPublicMethods ();
- typeof (TNothing).RequiresNone ();
- }
-
-
- class MakeGenericType
- {
- public static void Test ()
- {
- TestNullType ();
- TestUnknownInput (null);
- TestWithUnknownTypeArray (null);
- TestWithArrayUnknownIndexSet (0);
- TestWithArrayUnknownLengthSet (1);
- TestNoArguments ();
-
- TestWithRequirements ();
- TestWithRequirementsFromParam (null);
- TestWithRequirementsFromParamWithMismatch (null);
- TestWithRequirementsFromGenericParam<TestType> ();
- TestWithRequirementsFromGenericParamWithMismatch<TestType> ();
-
- TestWithNoRequirements ();
- TestWithNoRequirementsFromParam (null);
-
- TestWithMultipleArgumentsWithRequirements ();
-
- TestWithNewConstraint ();
- TestWithStructConstraint ();
- TestWithUnmanagedConstraint ();
- TestWithNullable ();
- }
-
- // This is OK since we know it's null, so MakeGenericType is effectively a no-op (will throw)
- // so no validation necessary.
- static void TestNullType ()
- {
- Type nullType = null;
- nullType.MakeGenericType (typeof (TestType));
- }
-
- [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
- static void TestUnknownInput (Type inputType)
- {
- inputType.MakeGenericType (typeof (TestType));
- }
-
- [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
- static void TestWithUnknownTypeArray (Type[] types)
- {
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
- }
-
- [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
- static void TestWithArrayUnknownIndexSet (int indexToSet)
- {
- Type[] types = new Type[1];
- types[indexToSet] = typeof (TestType);
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
- }
-
- [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
- static void TestWithArrayUnknownLengthSet (int arrayLen)
- {
- Type[] types = new Type[arrayLen];
- types[0] = typeof (TestType);
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
- }
-
- static void TestNoArguments ()
- {
- typeof (TypeMakeGenericNoArguments).MakeGenericType ();
- }
-
- class TypeMakeGenericNoArguments
- {
- }
-
- static void TestWithRequirements ()
- {
- // Currently this is not analyzable since we don't track array elements.
- // Would be really nice to support this kind of code in the future though.
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (typeof (TestType));
- }
-
- static void TestWithRequirementsFromParam (
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type)
- {
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (type);
- }
-
- // https://github.com/dotnet/linker/issues/2428
- // [ExpectedWarning ("IL2071", "'T'")]
- [ExpectedWarning ("IL2070", "'this'")]
- static void TestWithRequirementsFromParamWithMismatch (
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type)
- {
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (type);
- }
-
- static void TestWithRequirementsFromGenericParam<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> ()
- {
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (typeof (T));
- }
-
- // https://github.com/dotnet/linker/issues/2428
- // [ExpectedWarning ("IL2091", "'T'")]
- [ExpectedWarning ("IL2090", "'this'")] // Note that this actually produces a warning which should not be possible to produce right now
- static void TestWithRequirementsFromGenericParamWithMismatch<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TInput> ()
- {
- typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (typeof (TInput));
- }
-
- class GenericWithPublicFieldsArgument<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
- {
- }
-
- static void TestWithNoRequirements ()
- {
- typeof (GenericWithNoRequirements<>).MakeGenericType (typeof (TestType));
- }
-
- static void TestWithNoRequirementsFromParam (Type type)
- {
- typeof (GenericWithNoRequirements<>).MakeGenericType (type);
- }
-
- class GenericWithNoRequirements<T>
- {
- }
-
- static void TestWithMultipleArgumentsWithRequirements ()
- {
- typeof (GenericWithMultipleArgumentsWithRequirements<,>).MakeGenericType (typeof (TestType), typeof (TestType));
- }
-
- class GenericWithMultipleArgumentsWithRequirements<
- TOne,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TTwo>
- {
- }
-
- static void TestWithNewConstraint ()
- {
- typeof (GenericWithNewConstraint<>).MakeGenericType (typeof (TestType));
- }
-
- class GenericWithNewConstraint<T> where T : new()
- {
- }
-
- static void TestWithStructConstraint ()
- {
- typeof (GenericWithStructConstraint<>).MakeGenericType (typeof (TestType));
- }
-
- class GenericWithStructConstraint<T> where T : struct
- {
- }
-
- static void TestWithUnmanagedConstraint ()
- {
- typeof (GenericWithUnmanagedConstraint<>).MakeGenericType (typeof (TestType));
- }
-
- class GenericWithUnmanagedConstraint<T> where T : unmanaged
- {
- }
-
- static void TestWithNullable ()
- {
- typeof (Nullable<>).MakeGenericType (typeof (TestType));
- }
- }
-
- class MakeGenericMethod
- {
- public static void Test ()
- {
- TestNullMethod ();
- TestUnknownMethod (null);
- TestUnknownMethodButNoTypeArguments (null);
- TestWithUnknownTypeArray (null);
- TestWithArrayUnknownIndexSet (0);
- TestWithArrayUnknownIndexSetByRef (0);
- TestWithArrayUnknownLengthSet (1);
- TestWithArrayPassedToAnotherMethod ();
- TestWithNoArguments ();
- TestWithArgumentsButNonGenericMethod ();
-
- TestWithRequirements ();
- TestWithRequirementsFromParam (null);
- TestWithRequirementsFromGenericParam<TestType> ();
- TestWithRequirementsViaRuntimeMethod ();
- TestWithRequirementsButNoTypeArguments ();
-
- TestWithMultipleKnownGenericParameters ();
- TestWithOneUnknownGenericParameter (null);
- TestWithPartiallyInitializedGenericTypeArray ();
- TestWithConditionalGenericTypeSet (true);
-
- TestWithNoRequirements ();
- TestWithNoRequirementsFromParam (null);
- TestWithNoRequirementsViaRuntimeMethod ();
- TestWithNoRequirementsUnknownType (null);
- TestWithNoRequirementsWrongNumberOfTypeParameters ();
- TestWithNoRequirementsUnknownArrayElement ();
-
- TestWithMultipleArgumentsWithRequirements ();
-
- TestWithNewConstraint ();
- TestWithStructConstraint ();
- TestWithUnmanagedConstraint ();
- }
-
- static void TestNullMethod ()
- {
- MethodInfo mi = null;
- mi.MakeGenericMethod (typeof (TestType));
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestUnknownMethod (MethodInfo mi)
- {
- mi.MakeGenericMethod (typeof (TestType));
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestUnknownMethodButNoTypeArguments (MethodInfo mi)
- {
- // Thechnically linker could figure this out, but it's not worth the complexity - such call will always fail at runtime.
- mi.MakeGenericMethod (Type.EmptyTypes);
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithUnknownTypeArray (Type[] types)
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (types);
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithArrayUnknownIndexSet (int indexToSet)
- {
- Type[] types = new Type[1];
- types[indexToSet] = typeof (TestType);
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (types);
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithArrayUnknownIndexSetByRef (int indexToSet)
- {
- Type[] types = new Type[1];
- types[0] = typeof (TestType);
- ref Type t = ref types[indexToSet];
- t = typeof (TestType);
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (types);
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithArrayUnknownLengthSet (int arrayLen)
- {
- Type[] types = new Type[arrayLen];
- types[0] = typeof (TestType);
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (types);
- }
-
- static void MethodThatTakesArrayParameter (Type[] types)
- {
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithArrayPassedToAnotherMethod ()
- {
- Type[] types = new Type[1];
- types[0] = typeof (TestType);
- MethodThatTakesArrayParameter (types);
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (types);
- }
-
- static void TestWithNoArguments ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (NonGenericMethod), BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod ();
- }
-
- // This should not warn since we can't be always sure about the exact overload as we don't support
- // method parameter signature matching, and thus the GetMethod may return multiple potential methods.
- // It can happen that some are generic and some are not. The analysis should not fail on this.
- static void TestWithArgumentsButNonGenericMethod ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (NonGenericMethod), BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod (typeof (TestType));
- }
-
- static void NonGenericMethod ()
- {
- }
-
- static void TestWithRequirements ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (typeof (TestType));
- }
-
- static void TestWithRequirementsFromParam (
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type)
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (type);
- }
-
- static void TestWithRequirementsFromGenericParam<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (typeof (T));
- }
-
-
- static void TestWithRequirementsViaRuntimeMethod ()
- {
- typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithRequirements), Type.EmptyTypes)
- .MakeGenericMethod (typeof (TestType));
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithRequirementsButNoTypeArguments ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
- .MakeGenericMethod (Type.EmptyTypes);
- }
-
- public static void GenericWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> ()
- {
- }
-
- static void TestWithMultipleKnownGenericParameters ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
- .MakeGenericMethod (typeof (TestType), typeof (TestType), typeof (TestType));
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithOneUnknownGenericParameter (Type[] types)
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
- .MakeGenericMethod (typeof (TestType), typeof (TestStruct), types[0]);
- }
-
- [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
- static void TestWithPartiallyInitializedGenericTypeArray ()
- {
- Type[] types = new Type[3];
- types[0] = typeof (TestType);
- types[1] = typeof (TestStruct);
- typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
- .MakeGenericMethod (types);
- }
-
- static void TestWithConditionalGenericTypeSet (bool thirdParameterIsStruct)
- {
- Type[] types = new Type[3];
- types[0] = typeof (TestType);
- types[1] = typeof (TestStruct);
- if (thirdParameterIsStruct) {
- types[2] = typeof (TestStruct);
- } else {
- types[2] = typeof (TestType);
- }
- typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
- .MakeGenericMethod (types);
- }
-
- public static void GenericMultipleParameters<
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] U,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] V> ()
- {
- }
-
- static void TestWithNoRequirements ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements), BindingFlags.Static)
- .MakeGenericMethod (typeof (TestType));
- }
-
- static void TestWithNoRequirementsFromParam (Type type)
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements), BindingFlags.Static)
- .MakeGenericMethod (type);
- }
-
- static void TestWithNoRequirementsViaRuntimeMethod ()
- {
- typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithNoRequirements), Type.EmptyTypes)
- .MakeGenericMethod (typeof (TestType));
- }
-
- // There are no requirements, so no warnings
- static void TestWithNoRequirementsUnknownType (Type type)
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements))
- .MakeGenericMethod (type);
- }
-
- // There are no requirements, so no warnings
- static void TestWithNoRequirementsWrongNumberOfTypeParameters ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements))
- .MakeGenericMethod (typeof (TestType), typeof (TestType));
- }
-
- // There are no requirements, so no warnings
- static void TestWithNoRequirementsUnknownArrayElement ()
- {
- Type[] types = new Type[1];
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements))
- .MakeGenericMethod (types);
- }
-
- public static void GenericWithNoRequirements<T> ()
- {
- }
-
-
- static void TestWithMultipleArgumentsWithRequirements ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithMultipleArgumentsWithRequirements), BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod (typeof (TestType), typeof (TestType));
- }
-
- static void GenericWithMultipleArgumentsWithRequirements<
- TOne,
- [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TTwo> ()
- {
- }
-
- static void TestWithNewConstraint ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNewConstraint), BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod (typeof (TestType));
- }
-
- static void GenericWithNewConstraint<T> () where T : new()
- {
- var t = new T ();
- }
-
- static void TestWithStructConstraint ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithStructConstraint), BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod (typeof (TestType));
- }
-
- static void GenericWithStructConstraint<T> () where T : struct
- {
- var t = new T ();
- }
-
- static void TestWithUnmanagedConstraint ()
- {
- typeof (MakeGenericMethod).GetMethod (nameof (GenericWithUnmanagedConstraint), BindingFlags.Static | BindingFlags.NonPublic)
- .MakeGenericMethod (typeof (TestType));
- }
-
- static void GenericWithUnmanagedConstraint<T> () where T : unmanaged
- {
- var t = new T ();
- }
- }
-
static void TestNewConstraintSatisfiesParameterlessConstructor<T> () where T : new()
{
RequiresParameterlessConstructor<T> ();
@@ -1173,7 +727,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
RequiresParameterlessConstructor<T> ();
}
-
static void TestUnmanagedConstraintSatisfiesParameterlessConstructor<T> () where T : unmanaged
{
RequiresParameterlessConstructor<T> ();
@@ -1183,12 +736,17 @@ namespace Mono.Linker.Tests.Cases.DataFlow
{
}
- public class TestType
+ static void TestGenericParameterFlowsToField ()
{
+ TypeRequiresPublicFields<TestType>.TestFields ();
}
+ public class TestType
+ {
+ }
public struct TestStruct
{
}
+
}
}
diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs
new file mode 100644
index 000000000..3d3f2551b
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/DataFlow/MakeGenericDataFlow.cs
@@ -0,0 +1,501 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Helpers;
+using BindingFlags = System.Reflection.BindingFlags;
+
+namespace Mono.Linker.Tests.Cases.DataFlow
+{
+ [SkipKeptItemsValidation]
+ [ExpectedNoWarnings]
+ public class MakeGenericDataFlow
+ {
+ public static void Main ()
+ {
+ MakeGenericType.Test ();
+ MakeGenericMethod.Test ();
+ }
+
+ class MakeGenericType
+ {
+ public static void Test ()
+ {
+ TestNullType ();
+ TestUnknownInput (null);
+ TestWithUnknownTypeArray (null);
+ TestWithArrayUnknownIndexSet (0);
+ TestWithArrayUnknownLengthSet (1);
+ TestNoArguments ();
+
+ TestWithRequirements ();
+ TestWithRequirementsFromParam (null);
+ TestWithRequirementsFromParamWithMismatch (null);
+ TestWithRequirementsFromGenericParam<TestType> ();
+ TestWithRequirementsFromGenericParamWithMismatch<TestType> ();
+
+ TestWithNoRequirements ();
+ TestWithNoRequirementsFromParam (null);
+
+ TestWithMultipleArgumentsWithRequirements ();
+
+ TestWithNewConstraint ();
+ TestWithStructConstraint ();
+ TestWithUnmanagedConstraint ();
+ TestWithNullable ();
+ }
+
+ // This is OK since we know it's null, so MakeGenericType is effectively a no-op (will throw)
+ // so no validation necessary.
+ static void TestNullType ()
+ {
+ Type nullType = null;
+ nullType.MakeGenericType (typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
+ static void TestUnknownInput (Type inputType)
+ {
+ inputType.MakeGenericType (typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
+ static void TestWithUnknownTypeArray (Type[] types)
+ {
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
+ }
+
+ [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
+ static void TestWithArrayUnknownIndexSet (int indexToSet)
+ {
+ Type[] types = new Type[1];
+ types[indexToSet] = typeof (TestType);
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
+ }
+
+ [ExpectedWarning ("IL2055", nameof (Type.MakeGenericType))]
+ static void TestWithArrayUnknownLengthSet (int arrayLen)
+ {
+ Type[] types = new Type[arrayLen];
+ types[0] = typeof (TestType);
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types);
+ }
+
+ static void TestNoArguments ()
+ {
+ typeof (TypeMakeGenericNoArguments).MakeGenericType ();
+ }
+
+ class TypeMakeGenericNoArguments
+ {
+ }
+
+ static void TestWithRequirements ()
+ {
+ // Currently this is not analyzable since we don't track array elements.
+ // Would be really nice to support this kind of code in the future though.
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (typeof (TestType));
+ }
+
+ static void TestWithRequirementsFromParam (
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type)
+ {
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (type);
+ }
+
+ // https://github.com/dotnet/linker/issues/2428
+ // [ExpectedWarning ("IL2071", "'T'")]
+ [ExpectedWarning ("IL2070", "'this'")]
+ static void TestWithRequirementsFromParamWithMismatch (
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type)
+ {
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (type);
+ }
+
+ static void TestWithRequirementsFromGenericParam<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> ()
+ {
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (typeof (T));
+ }
+
+ // https://github.com/dotnet/linker/issues/2428
+ // [ExpectedWarning ("IL2091", "'T'")]
+ [ExpectedWarning ("IL2090", "'this'")] // Note that this actually produces a warning which should not be possible to produce right now
+ static void TestWithRequirementsFromGenericParamWithMismatch<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TInput> ()
+ {
+ typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (typeof (TInput));
+ }
+
+ class GenericWithPublicFieldsArgument<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T>
+ {
+ }
+
+ static void TestWithNoRequirements ()
+ {
+ typeof (GenericWithNoRequirements<>).MakeGenericType (typeof (TestType));
+ }
+
+ static void TestWithNoRequirementsFromParam (Type type)
+ {
+ typeof (GenericWithNoRequirements<>).MakeGenericType (type);
+ }
+
+ class GenericWithNoRequirements<T>
+ {
+ }
+
+ static void TestWithMultipleArgumentsWithRequirements ()
+ {
+ typeof (GenericWithMultipleArgumentsWithRequirements<,>).MakeGenericType (typeof (TestType), typeof (TestType));
+ }
+
+ class GenericWithMultipleArgumentsWithRequirements<
+ TOne,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TTwo>
+ {
+ }
+
+ static void TestWithNewConstraint ()
+ {
+ typeof (GenericWithNewConstraint<>).MakeGenericType (typeof (TestType));
+ }
+
+ class GenericWithNewConstraint<T> where T : new()
+ {
+ }
+
+ static void TestWithStructConstraint ()
+ {
+ typeof (GenericWithStructConstraint<>).MakeGenericType (typeof (TestType));
+ }
+
+ class GenericWithStructConstraint<T> where T : struct
+ {
+ }
+
+ static void TestWithUnmanagedConstraint ()
+ {
+ typeof (GenericWithUnmanagedConstraint<>).MakeGenericType (typeof (TestType));
+ }
+
+ class GenericWithUnmanagedConstraint<T> where T : unmanaged
+ {
+ }
+
+ static void TestWithNullable ()
+ {
+ typeof (Nullable<>).MakeGenericType (typeof (TestType));
+ }
+ }
+
+ class MakeGenericMethod
+ {
+ public static void Test ()
+ {
+ TestNullMethod ();
+ TestUnknownMethod (null);
+ TestUnknownMethodButNoTypeArguments (null);
+ TestWithUnknownTypeArray (null);
+ TestWithArrayUnknownIndexSet (0);
+ TestWithArrayUnknownIndexSetByRef (0);
+ TestWithArrayUnknownLengthSet (1);
+ TestWithArrayPassedToAnotherMethod ();
+ TestWithNoArguments ();
+ TestWithArgumentsButNonGenericMethod ();
+
+ TestWithRequirements ();
+ TestWithRequirementsFromParam (null);
+ TestWithRequirementsFromGenericParam<TestType> ();
+ TestWithRequirementsViaRuntimeMethod ();
+ TestWithRequirementsButNoTypeArguments ();
+
+ TestWithMultipleKnownGenericParameters ();
+ TestWithOneUnknownGenericParameter (null);
+ TestWithPartiallyInitializedGenericTypeArray ();
+ TestWithConditionalGenericTypeSet (true);
+
+ TestWithNoRequirements ();
+ TestWithNoRequirementsFromParam (null);
+ TestWithNoRequirementsViaRuntimeMethod ();
+ TestWithNoRequirementsUnknownType (null);
+ TestWithNoRequirementsWrongNumberOfTypeParameters ();
+ TestWithNoRequirementsUnknownArrayElement ();
+
+ TestWithMultipleArgumentsWithRequirements ();
+
+ TestWithNewConstraint ();
+ TestWithStructConstraint ();
+ TestWithUnmanagedConstraint ();
+ }
+
+ static void TestNullMethod ()
+ {
+ MethodInfo mi = null;
+ mi.MakeGenericMethod (typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestUnknownMethod (MethodInfo mi)
+ {
+ mi.MakeGenericMethod (typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestUnknownMethodButNoTypeArguments (MethodInfo mi)
+ {
+ // Thechnically linker could figure this out, but it's not worth the complexity - such call will always fail at runtime.
+ mi.MakeGenericMethod (Type.EmptyTypes);
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithUnknownTypeArray (Type[] types)
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithArrayUnknownIndexSet (int indexToSet)
+ {
+ Type[] types = new Type[1];
+ types[indexToSet] = typeof (TestType);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithArrayUnknownIndexSetByRef (int indexToSet)
+ {
+ Type[] types = new Type[1];
+ types[0] = typeof (TestType);
+ ref Type t = ref types[indexToSet];
+ t = typeof (TestType);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithArrayUnknownLengthSet (int arrayLen)
+ {
+ Type[] types = new Type[arrayLen];
+ types[0] = typeof (TestType);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ static void MethodThatTakesArrayParameter (Type[] types)
+ {
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithArrayPassedToAnotherMethod ()
+ {
+ Type[] types = new Type[1];
+ types[0] = typeof (TestType);
+ MethodThatTakesArrayParameter (types);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ static void TestWithNoArguments ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (NonGenericMethod), BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod ();
+ }
+
+ // This should not warn since we can't be always sure about the exact overload as we don't support
+ // method parameter signature matching, and thus the GetMethod may return multiple potential methods.
+ // It can happen that some are generic and some are not. The analysis should not fail on this.
+ static void TestWithArgumentsButNonGenericMethod ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (NonGenericMethod), BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ static void NonGenericMethod ()
+ {
+ }
+
+ static void TestWithRequirements ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ static void TestWithRequirementsFromParam (
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type)
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (type);
+ }
+
+ static void TestWithRequirementsFromGenericParam<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (typeof (T));
+ }
+
+
+ static void TestWithRequirementsViaRuntimeMethod ()
+ {
+ typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithRequirements), Type.EmptyTypes)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithRequirementsButNoTypeArguments ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static)
+ .MakeGenericMethod (Type.EmptyTypes);
+ }
+
+ public static void GenericWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> ()
+ {
+ }
+
+ static void TestWithMultipleKnownGenericParameters ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (typeof (TestType), typeof (TestType), typeof (TestType));
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithOneUnknownGenericParameter (Type[] types)
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (typeof (TestType), typeof (TestStruct), types[0]);
+ }
+
+ [ExpectedWarning ("IL2060", nameof (MethodInfo.MakeGenericMethod))]
+ static void TestWithPartiallyInitializedGenericTypeArray ()
+ {
+ Type[] types = new Type[3];
+ types[0] = typeof (TestType);
+ types[1] = typeof (TestStruct);
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ static void TestWithConditionalGenericTypeSet (bool thirdParameterIsStruct)
+ {
+ Type[] types = new Type[3];
+ types[0] = typeof (TestType);
+ types[1] = typeof (TestStruct);
+ if (thirdParameterIsStruct) {
+ types[2] = typeof (TestStruct);
+ } else {
+ types[2] = typeof (TestType);
+ }
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static)
+ .MakeGenericMethod (types);
+ }
+
+ public static void GenericMultipleParameters<
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] U,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] V> ()
+ {
+ }
+
+ static void TestWithNoRequirements ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements), BindingFlags.Static)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ static void TestWithNoRequirementsFromParam (Type type)
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements), BindingFlags.Static)
+ .MakeGenericMethod (type);
+ }
+
+ static void TestWithNoRequirementsViaRuntimeMethod ()
+ {
+ typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithNoRequirements), Type.EmptyTypes)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ // There are no requirements, so no warnings
+ static void TestWithNoRequirementsUnknownType (Type type)
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements))
+ .MakeGenericMethod (type);
+ }
+
+ // There are no requirements, so no warnings
+ static void TestWithNoRequirementsWrongNumberOfTypeParameters ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements))
+ .MakeGenericMethod (typeof (TestType), typeof (TestType));
+ }
+
+ // There are no requirements, so no warnings
+ static void TestWithNoRequirementsUnknownArrayElement ()
+ {
+ Type[] types = new Type[1];
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements))
+ .MakeGenericMethod (types);
+ }
+
+ public static void GenericWithNoRequirements<T> ()
+ {
+ }
+
+
+ static void TestWithMultipleArgumentsWithRequirements ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithMultipleArgumentsWithRequirements), BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod (typeof (TestType), typeof (TestType));
+ }
+
+ static void GenericWithMultipleArgumentsWithRequirements<
+ TOne,
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TTwo> ()
+ {
+ }
+
+ static void TestWithNewConstraint ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNewConstraint), BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ static void GenericWithNewConstraint<T> () where T : new()
+ {
+ var t = new T ();
+ }
+
+ static void TestWithStructConstraint ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithStructConstraint), BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ static void GenericWithStructConstraint<T> () where T : struct
+ {
+ var t = new T ();
+ }
+
+ static void TestWithUnmanagedConstraint ()
+ {
+ typeof (MakeGenericMethod).GetMethod (nameof (GenericWithUnmanagedConstraint), BindingFlags.Static | BindingFlags.NonPublic)
+ .MakeGenericMethod (typeof (TestType));
+ }
+
+ static void GenericWithUnmanagedConstraint<T> () where T : unmanaged
+ {
+ var t = new T ();
+ }
+ }
+
+ public class TestType
+ {
+ }
+
+ public struct TestStruct
+ {
+ }
+ }
+}