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 () { } + } +}