From da244b780a1d1755cb7cb389df599fe650726892 Mon Sep 17 00:00:00 2001 From: Vitek Karas <10670590+vitek-karas@users.noreply.github.com> Date: Fri, 2 Dec 2022 02:24:00 -0800 Subject: [PATCH] Generic warning location tests (#3146) Adds a test which focused on warnings produced due to annotated generic parameters. This is relatively tricky for the product to deal with since it's often part of the type system and not code. So this test focused on all the different situations such warning can occur and the location where the warning is generated. Co-authored-by: Tlakaelel Axayakatl Ceja --- .../DataFlowTests.g.cs | 6 + .../DataFlow/GenericParameterDataFlow.cs | 5 +- .../GenericParameterWarningLocation.cs | 889 ++++++++++++++++++ 3 files changed, 899 insertions(+), 1 deletion(-) create mode 100644 test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs index f46c0bc09916..2dad733fa65c 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs @@ -7,6 +7,12 @@ namespace ILLink.RoslynAnalyzer.Tests public sealed partial class DataFlowTests : LinkerTestBase { + [Fact] + public Task GenericParameterWarningLocation () + { + return RunTest (allowMissingWarnings: true); + } + [Fact] public Task MethodByRefParameterDataFlow () { diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs index e30b6f1d2c98..d860a1abb268 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs @@ -1,4 +1,7 @@ -using System; +// 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; using System.Diagnostics.CodeAnalysis; using System.Reflection; using Mono.Linker.Tests.Cases.Expectations.Assertions; diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs new file mode 100644 index 000000000000..1b82d33abbf8 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs @@ -0,0 +1,889 @@ +// 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; +using System.Diagnostics.CodeAnalysis; +using System.Security.Policy; +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class GenericParameterWarningLocation + { + public static void Main () + { + TypeInheritance.Test (); + TypeImplementingInterface.Test (); + MethodParametersAndReturn.Test (); + FieldDefinition.Test (); + PropertyDefinition.Test (); + MethodBody.Test (); + } + + class TypeInheritance + { + class BaseWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + { } + + class BaseWithTwo< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + { } + + // No warning - annotations applied + class DerivedWithSpecificType : BaseWithPublicMethods { } + + // No warning - annotations match + class DerivedWithMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] TAllMethods> + : BaseWithPublicMethods + { } + + [ExpectedWarning ("IL2091")] + class DerivedWithNoAnnotations + : BaseWithPublicMethods + { } + + [ExpectedWarning ("IL2091")] + class DerivedWithMismatchAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + : BaseWithPublicMethods + { } + + [ExpectedWarning ("IL2091", nameof (DynamicallyAccessedMemberTypes.PublicMethods))] + class DerivedWithOneMismatch<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + : BaseWithTwo + { } + + class DerivedWithTwoMatching< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + : BaseWithTwo + { } + + public static void Test () + { + Type t; + t = typeof (DerivedWithSpecificType); + t = typeof (DerivedWithMatchingAnnotation<>); + t = typeof (DerivedWithNoAnnotations<>); + t = typeof (DerivedWithMismatchAnnotation<>); + t = typeof (DerivedWithOneMismatch<>); + t = typeof (DerivedWithTwoMatching<,>); + } + } + + class TypeImplementingInterface + { + interface IWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> { } + + interface IWithPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> { } + + // No warning - annotations applied + class ImplementsWithSpecificType : IWithPublicMethods, IWithPublicFields { } + + // No warning - matching annotations + class ImplementsWithMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] TAll> + : IWithPublicMethods, IWithPublicFields + { } + + [ExpectedWarning ("IL2091", nameof (DynamicallyAccessedMemberTypes.PublicFields))] + class ImplementsWithOneMismatch<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + : IWithPublicMethods, IWithPublicFields + { } + + [ExpectedWarning ("IL2091", nameof (DynamicallyAccessedMemberTypes.PublicMethods))] + [ExpectedWarning ("IL2091", nameof (DynamicallyAccessedMemberTypes.PublicFields))] + class ImplementsWithTwoMismatches< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + : IWithPublicMethods, IWithPublicFields + { } + + public static void Test () + { + // Instantiate the types + new ImplementsWithSpecificType (); + new ImplementsWithMatchingAnnotation (); + new ImplementsWithOneMismatch (); + new ImplementsWithTwoMismatches (); + + // Also reference the interfaces, otherwise they could be trimmed + Type t; + t = typeof (IWithPublicMethods<>); + t = typeof (IWithPublicFields<>); + } + } + + class MethodParametersAndReturn + { + class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + { } + + interface IWithTwo< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + { } + + static void MethodWithSpecificType (TypeWithPublicMethods one, IWithTwo two) { } + + [ExpectedWarning ("IL2091")] + static void MethodWithOneMismatch (TypeWithPublicMethods one) { } + + [ExpectedWarning ("IL2091", nameof (IWithTwo))] + [ExpectedWarning ("IL2091", nameof (TypeWithPublicMethods))] + static void MethodWithTwoMismatches< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + (IWithTwo two, TypeWithPublicMethods one) + { } + + static TypeWithPublicMethods MethodWithSpecificReturnType () => null; + + static TypeWithPublicMethods MethodWithMatchingReturn<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () => null; + + [ExpectedWarning ("IL2091")] + static TypeWithPublicMethods MethodWithOneMismatchReturn () => null; + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static IWithTwo MethodWithTwoMismatchesInReturn< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () => null; + + public static void Test () + { + MethodWithSpecificType (null, null); + MethodWithOneMismatch (null); + MethodWithTwoMismatches (null, null); + + MethodWithSpecificReturnType (); + MethodWithMatchingReturn (); + MethodWithOneMismatchReturn (); + MethodWithTwoMismatchesInReturn (); + } + } + + class FieldDefinition + { + class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + { } + + interface IWithTwo< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + { } + + class SpecificType + { + static TypeWithPublicMethods _field; + + public static void Test () + { + _field = null; + } + } + + class OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + { + static TypeWithPublicMethods _field; + + public static void Test () + { + _field = null; + } + } + + class MultipleReferencesToTheSameType<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> + { + [ExpectedWarning ("IL2091")] + static TypeWithPublicMethods _field1; + static TypeWithPublicMethods _field2; + [ExpectedWarning ("IL2091")] + static TypeWithPublicMethods _field3; + + public static void Test () + { + _field1 = null; + _field2 = null; + _field3 = null; + } + } + + class TwoMismatchesInOne< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + { + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static IWithTwo _field; + + public static void Test () + { + _field = null; + } + } + + public static void Test () + { + SpecificType.Test (); + OneMatchingAnnotation.Test (); + MultipleReferencesToTheSameType.Test (); + TwoMismatchesInOne.Test (); + } + } + + class PropertyDefinition + { + class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + { } + + interface IWithTwo< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + { } + + class SpecificType + { + static TypeWithPublicMethods Property { get; set; } + + public static void Test () + { + Property = null; + } + } + + class OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + { + static TypeWithPublicMethods Property { get; set; } + + public static void Test () + { + Property = null; + } + } + + class MultipleReferencesToTheSameType<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, TUnknown> + { + // The warning is generated on the backing field + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] + static TypeWithPublicMethods Property1 { + [ExpectedWarning ("IL2091")] + get; + + [ExpectedWarning ("IL2091")] + set; + } + + static TypeWithPublicMethods Property2 { + get; + set; + } + + // The warning is generated on the backing field + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] + static TypeWithPublicMethods Property3 { + [ExpectedWarning ("IL2091")] + get; + + [ExpectedWarning ("IL2091")] + set; + } + + public static void Test () + { + Property1 = Property1; + Property2 = Property2; + Property3 = Property3; + } + } + + class TwoMismatchesInOne< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + { + // The warnings are generated on the backing field + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] + [ExpectedWarning ("IL2091", CompilerGeneratedCode = true)] + static IWithTwo Property { + // Getter is trimmed and doesn't produce any warning + get; + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + set; + } + + public static void Test () + { + Property = null; + } + } + + public static void Test () + { + SpecificType.Test (); + OneMatchingAnnotation.Test (); + MultipleReferencesToTheSameType.Test (); + TwoMismatchesInOne.Test (); + } + } + + class MethodBody + { + class TypeWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> : Exception + { + public static void Method () { } + } + + interface IWithTwo< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> + { + public static void Method () { } + } + + class TypeWithTwo< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> : Exception + { } + + static void MethodWithPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () { } + + static void MethodWithTwo< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields> () + { } + + class TypeOf + { + static void SpecificType () + { + Type t = typeof (TypeWithPublicMethods); + t = typeof (IWithTwo); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + Type t = typeof (TypeWithPublicMethods); + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameType< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + Type t = typeof (TypeWithPublicMethods); // Warn + t = typeof (TypeWithPublicMethods); // No warn + t = typeof (TypeWithPublicMethods); // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + Type t = typeof (IWithTwo); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameType (); + TwoMismatchesInOneStatement (); + } + } + + class MethodCallOnGenericMethod + { + static void SpecificType () + { + MethodWithPublicMethods (); + MethodWithTwo (); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + MethodWithPublicMethods (); + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + MethodWithPublicMethods (); // Warn + MethodWithPublicMethods (); // No warn + MethodWithPublicMethods (); // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + MethodWithTwo (); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class MethodCallOnGenericType + { + static void SpecificType () + { + TypeWithPublicMethods.Method (); + IWithTwo.Method (); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + TypeWithPublicMethods.Method (); + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + TypeWithPublicMethods.Method (); // Warn + TypeWithPublicMethods.Method (); // No warn + TypeWithPublicMethods.Method (); // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + IWithTwo.Method (); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class LocalVariable + { + static void SpecificType () + { + TypeWithPublicMethods t = null; + IWithTwo i = null; + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + TypeWithPublicMethods t = null; + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameType< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + TypeWithPublicMethods t1 = null; // Warn + TypeWithPublicMethods t2 = null; // No warn + TypeWithPublicMethods t3 = null; // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + IWithTwo i = null; + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameType (); + TwoMismatchesInOneStatement (); + } + } + + class DelegateUsageOnGenericMethod + { + static void SpecificType () + { + var a = new Action (MethodWithPublicMethods); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + var a = new Action (MethodWithPublicMethods); + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + var a1 = new Action (MethodWithPublicMethods); // Warn + var a2 = new Action (MethodWithPublicMethods); // No warn + var a3 = new Action (MethodWithPublicMethods); // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + var a = new Action (MethodWithTwo); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class DelegateUsageOnGenericType + { + static void SpecificType () + { + var a = new Action (TypeWithPublicMethods.Method); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + var a = new Action (TypeWithPublicMethods.Method); + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + var a1 = new Action (TypeWithPublicMethods.Method); // Warn + var a2 = new Action (TypeWithPublicMethods.Method); // No warn + var a3 = new Action (TypeWithPublicMethods.Method); // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + var a = new Action (IWithTwo.Method); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class CreateInstance + { + static void SpecificType () + { + object a = new TypeWithPublicMethods (); + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + object a = new TypeWithPublicMethods (); + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + object a1 = new TypeWithPublicMethods (); // Warn + object a2 = new TypeWithPublicMethods (); // No warn + object a3 = new TypeWithPublicMethods (); // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + object a = new TypeWithTwo (); + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class IsInstance + { + static object _value = null; + + static void SpecificType () + { + bool a = _value is TypeWithPublicMethods; + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + bool a = _value is TypeWithPublicMethods; + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + bool a1 = _value is TypeWithPublicMethods; // Warn + bool a2 = _value is TypeWithPublicMethods; // No warn + bool a3 = _value is TypeWithPublicMethods; // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + bool a = _value is TypeWithTwo; + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class AsType + { + static object _value = null; + + static void SpecificType () + { + object a = _value as TypeWithPublicMethods; + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + object a = _value as TypeWithPublicMethods; + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameMethod< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + object a1 = _value as TypeWithPublicMethods; // Warn + object a2 = _value as TypeWithPublicMethods; // No warn + object a3 = _value as TypeWithPublicMethods; // Warn + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + object a = _value as TypeWithTwo; + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameMethod (); + TwoMismatchesInOneStatement (); + } + } + + class ExceptionCatch + { + static void SpecificType () + { + try { + DoNothing (); + } catch (TypeWithPublicMethods) { + } + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + try { + DoNothing (); + } catch (TypeWithPublicMethods) { + } + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameType< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + try { + DoNothing (); + } catch (TypeWithPublicMethods) { // Warn + } + + try { + DoNothing (); + } catch (TypeWithPublicMethods) { // No warn + } + + try { + DoNothing (); + } catch (TypeWithPublicMethods) { // Warn + } + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + try { + DoNothing (); + } catch (TypeWithTwo) { // Warn x2 + } + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameType (); + TwoMismatchesInOneStatement (); + } + } + + class ExceptionFilter + { + static void SpecificType () + { + try { + DoNothing (); + } catch (Exception ex) when (ex is TypeWithPublicMethods) { + } + } + + static void OneMatchingAnnotation<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> () + { + try { + DoNothing (); + } catch (Exception ex) when (ex is TypeWithPublicMethods) { + } + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void MultipleReferencesToTheSameType< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods, + TUnknown> () + { + try { + DoNothing (); + } catch (Exception ex) when (ex is TypeWithPublicMethods) { // Warn + } + + try { + DoNothing (); + } catch (Exception ex) when (ex is TypeWithPublicMethods) { // No warn + } + + try { + DoNothing (); + } catch (Exception ex) when (ex is TypeWithPublicMethods) { // Warn + } + } + + [ExpectedWarning ("IL2091")] + [ExpectedWarning ("IL2091")] + static void TwoMismatchesInOneStatement< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TPublicFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TPublicMethods> + () + { + try { + DoNothing (); + } catch (Exception ex) when (ex is TypeWithTwo) { // Warn x2 + } + } + + public static void Test () + { + SpecificType (); + OneMatchingAnnotation (); + MultipleReferencesToTheSameType (); + TwoMismatchesInOneStatement (); + } + } + + public static void Test () + { + TypeOf.Test (); + MethodCallOnGenericMethod.Test (); + MethodCallOnGenericType.Test (); + LocalVariable.Test (); + DelegateUsageOnGenericMethod.Test (); + DelegateUsageOnGenericType.Test (); + CreateInstance.Test (); + IsInstance.Test (); + AsType.Test (); + ExceptionCatch.Test (); + ExceptionFilter.Test (); + } + } + + class TestType { } + + static void DoNothing () { } + } +}