diff options
author | Sven Boemer <sbomer@gmail.com> | 2022-02-05 01:12:26 +0300 |
---|---|---|
committer | Sven Boemer <sbomer@gmail.com> | 2022-02-08 02:10:43 +0300 |
commit | 30df1e13ba39c92e178d096b1a0916334d755a8c (patch) | |
tree | 624eaa78a1b44b08ec235fd5cb2b46813d8aacfd /test | |
parent | cdd4079a338a2d5a71c5334946d218c427a8869c (diff) | |
parent | 917830d2d4a502b9f2c1cf47d8229a76ee48624e (diff) |
Merge remote-tracking branch 'origin/feature/damAnalyzer' into mergeFromMain
Diffstat (limited to 'test')
159 files changed, 8987 insertions, 2454 deletions
diff --git a/test/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.Generator.csproj b/test/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.Generator.csproj new file mode 100644 index 000000000..095efe39a --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.Generator.csproj @@ -0,0 +1,12 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netstandard2.0</TargetFramework> + <Nullable>enable</Nullable> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisVersion)" /> + </ItemGroup> + +</Project> diff --git a/test/ILLink.RoslynAnalyzer.Tests.Generator/TestCaseGenerator.cs b/test/ILLink.RoslynAnalyzer.Tests.Generator/TestCaseGenerator.cs new file mode 100644 index 000000000..f514a93f8 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests.Generator/TestCaseGenerator.cs @@ -0,0 +1,208 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection.Metadata; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public readonly struct TestCases + { + // Maps from suite name to a set of testcase names. + // Suite name is: + // - The namespace of the test class, minus "Mono.Linker.Tests.Cases", for linker tests + // - The namespace + test class name, minus "ILLink.RoslynAnalyzer.Tests", for analyzer tests + // Testcase name is: + // - The test class name, for linker tests + // - The test fact method name, minus "Tests", for analyzer tests + // For example: + // | Testcase | Suite name | Linker | Analyzer | + // |-------------------------+----------------------+--------------------------------------------+-----------------------------------------| + // | RequiresCapability | RequiresCapability | RequiresCapability class in namespcae | RequiresCapability method in class | + // | | | Mono.Linker.Tests.Cases.RequiresCapability | RequiresCapabilityTests in namespace | + // | | | | ILLink.RoslynAnalyzer.Tests | + // |-------------------------+----------------------+--------------------------------------------+-----------------------------------------| + // | RequiresOnAttributeCtor | RequiresCapability | RequiresOnAttributeCtor class in namespace | RequiresOnAttributeCtor method in class | + // | | | Mono.Linker.Tests.Cases.RequiresCapability | RequiresCapabilityTests in namespace | + // | | | | ILlink.RoslynAnalyzer.Tests | + // |-------------------------+----------------------+--------------------------------------------+-----------------------------------------| + // | UnusedPInvoke | Interop.PInvokeTests | UnusedPInvoke class in namespace | UnusedPInvoke method in class | + // | | | Mono.Linker.Tests.Cases.Interop.PInvoke | PinvokeTests in namespace | + // | | | | ILLink.RoslynAnalyzer.Tests.Interop | + public readonly Dictionary<string, HashSet<string>> Suites = new (); + + public void Add (string suiteName, string name) + { + if (!Suites.TryGetValue (suiteName, out var testCases)) { + testCases = new HashSet<string> (); + Suites.Add (suiteName, testCases); + } + + testCases.Add (name); + } + } + + public static class TestClassGenerator + { + public const string TestNamespace = "ILLink.RoslynAnalyzer.Tests"; + + public static string GenerateClassHeader (string suiteName, bool newTestSuite) { + int idx = suiteName.LastIndexOf ('.'); + // Test suite class from innermost namespace part + var suiteClassName = suiteName.Substring (idx + 1); + // Namespace from outer namespaces, or empty + var suiteNamespacePart = suiteClassName.Length < suiteName.Length ? + $".{suiteName.Substring (0, idx)}" : string.Empty; + + string header = $@"using System; +using System.Threading.Tasks; +using Xunit; + +namespace {TestNamespace}{suiteNamespacePart} +{{ + public sealed partial class {suiteClassName}Tests : LinkerTestBase + {{ +"; + if (newTestSuite) + header += $@" + protected override string TestSuiteName => ""{suiteName}""; +"; + return header; + } + + public static string GenerateFact (string testCase) { + return $@" + [Fact] + public Task {testCase} () + {{ + return RunTest (allowMissingWarnings: true); + }} +"; + } + + public static string GenerateClassFooter () { + return $@" + }} +}}"; + } + } + + [Generator] + public class TestCaseGenerator : ISourceGenerator + { + public const string TestCaseAssembly = "Mono.Linker.Tests.Cases"; + + public void Execute (GeneratorExecutionContext context) + { + IAssemblySymbol? assemblySymbol = null; + + // Find testcase assembly + foreach (var reference in context.Compilation.References) { + ISymbol? assemblyOrModule = context.Compilation.GetAssemblyOrModuleSymbol (reference); + if (assemblyOrModule is IAssemblySymbol asmSym && asmSym.Name == TestCaseAssembly) { + assemblySymbol = asmSym; + break; + } + } + if (assemblySymbol is null || assemblySymbol.GetMetadata () is not AssemblyMetadata assemblyMetadata) + return; + + ModuleMetadata moduleMetadata = assemblyMetadata.GetModules ().Single (); + MetadataReader metadataReader = moduleMetadata.GetMetadataReader (); + TestCases testCases = new (); + string suiteName; + + // Find test classes + foreach (var typeDefHandle in metadataReader.TypeDefinitions) { + TypeDefinition typeDef = metadataReader.GetTypeDefinition (typeDefHandle); + // Must not be a nested type + if (typeDef.IsNested) + continue; + + string ns = metadataReader.GetString (typeDef.Namespace); + // Must be in the testcases namespace + if (!ns.StartsWith (TestCaseAssembly)) + continue; + + // Must have a Main method + bool hasMain = false; + foreach (var methodDefHandle in typeDef.GetMethods ()) { + MethodDefinition methodDef = metadataReader.GetMethodDefinition (methodDefHandle); + if (metadataReader.GetString (methodDef.Name) == "Main") { + hasMain = true; + break; + } + } + if (!hasMain) + continue; + + string testName = metadataReader.GetString (typeDef.Name); + suiteName = ns.Substring (TestCaseAssembly.Length + 1); + + testCases.Add (suiteName, testName); + } + + TestCases existingTestCases = ((ExistingTestCaseDiscoverer) context.SyntaxContextReceiver!).ExistingTestCases; + + // Generate test facts + foreach (var kvp in testCases.Suites) { + suiteName = kvp.Key; + var cases = kvp.Value; + + bool newTestSuite = !existingTestCases.Suites.TryGetValue (suiteName, out HashSet<string> existingCases); + var newCases = newTestSuite ? cases : cases.Except (existingCases); + // Skip generating a test class if all testcases in the suite already exist. + if (!newCases.Any ()) + continue; + + StringBuilder sourceBuilder = new (); + sourceBuilder.Append (TestClassGenerator.GenerateClassHeader (suiteName, newTestSuite)); + // Generate facts for all testcases that don't already exist + foreach (var testCase in newCases) + sourceBuilder.Append (TestClassGenerator.GenerateFact (testCase)); + sourceBuilder.Append (TestClassGenerator.GenerateClassFooter ()); + + context.AddSource ($"{suiteName}Tests.g.cs", sourceBuilder.ToString ()); + } + } + + public void Initialize (GeneratorInitializationContext context) + { + context.RegisterForSyntaxNotifications (() => new ExistingTestCaseDiscoverer ()); + } + } + + class ExistingTestCaseDiscoverer : ISyntaxContextReceiver + { + public readonly TestCases ExistingTestCases = new (); + + public void OnVisitSyntaxNode (GeneratorSyntaxContext context) + { + if (context.Node is not ClassDeclarationSyntax classSyntax) + return; + + if (context.SemanticModel.GetDeclaredSymbol (classSyntax) is not INamedTypeSymbol typeSymbol) + return; + + var displayFormat = new SymbolDisplayFormat( + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces); + string typeFullName = typeSymbol.ToDisplayString (displayFormat); + + // Ignore types not in the testcase namespace or that don't end with "Tests" + if (!typeFullName.StartsWith (TestClassGenerator.TestNamespace)) + return; + if (!typeFullName.EndsWith ("Tests")) + return; + + string suiteName = typeFullName.Substring (TestClassGenerator.TestNamespace.Length + 1); + suiteName = suiteName.Substring (0, suiteName.Length - 5); + foreach (var memberSymbol in typeSymbol.GetMembers ()) { + if (memberSymbol is not IMethodSymbol methodSymbol) + continue; + ExistingTestCases.Add (suiteName, methodSymbol.Name); + } + } + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/AdvancedTests.cs b/test/ILLink.RoslynAnalyzer.Tests/AdvancedTests.cs new file mode 100644 index 000000000..aae7de9d7 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/AdvancedTests.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class AdvancedTests : LinkerTestBase + { + protected override string TestSuiteName => "Advanced"; + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2415")] + public Task TypeCheckRemoval () + { + return RunTest (allowMissingWarnings: true); + } + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs b/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs new file mode 100644 index 000000000..107267288 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/DataFlowTests.cs @@ -0,0 +1,215 @@ +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class DataFlowTests : LinkerTestBase + { + protected override string TestSuiteName => "DataFlow"; + + [Fact] + public Task AnnotatedMembersAccessedViaReflection () + { + return RunTest (nameof (AnnotatedMembersAccessedViaReflection)); + } + + [Fact] + public Task ApplyTypeAnnotations () + { + return RunTest (nameof (ApplyTypeAnnotations)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task AssemblyQualifiedNameDataflow () + { + return RunTest (nameof (AssemblyQualifiedNameDataflow)); + } + + [Fact] + public Task AttributeConstructorDataflow () + { + return RunTest (nameof (AttributeConstructorDataflow)); + } + + [Fact] + public Task AttributeFieldDataflow () + { + return RunTest (nameof (AttributeFieldDataflow)); + } + + [Fact] + public Task AttributePropertyDataflow () + { + return RunTest (nameof (AttributePropertyDataflow)); + } + + [Fact] + public Task ByRefDataflow () + { + return RunTest (nameof (ByRefDataflow)); + } + + [Fact] + public Task ComplexTypeHandling () + { + return RunTest (nameof (ComplexTypeHandling)); + } + + [Fact] + public Task DynamicDependencyDataflow () + { + return RunTest (nameof (DynamicDependencyDataflow)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task EmptyArrayIntrinsicsDataFlow () + { + return RunTest (nameof (EmptyArrayIntrinsicsDataFlow)); + } + + [Fact] + public Task FieldDataFlow () + { + return RunTest (nameof (FieldDataFlow)); + } + + [Fact] + public Task GenericParameterDataFlow () + { + return RunTest (nameof (GenericParameterDataFlow)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task MakeGenericDataFlow () + { + return RunTest (nameof (MakeGenericDataFlow)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task GetInterfaceDataFlow () + { + return RunTest (nameof (GetInterfaceDataFlow)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task GetNestedTypeOnAllAnnotatedType () + { + return RunTest (nameof (GetNestedTypeOnAllAnnotatedType)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task GetTypeDataFlow () + { + return RunTest (nameof (GetTypeDataFlow)); + } + + [Fact] + public Task GetTypeInfoDataFlow () + { + return RunTest (nameof (GetTypeInfoDataFlow)); + } + + [Fact] + public Task TypeInfoAsTypeDataFlow () + { + return RunTest (nameof (TypeInfoAsTypeDataFlow)); + } + + [Fact] + public Task IReflectDataflow () + { + return RunTest (nameof (IReflectDataflow)); + } + + [Fact] + public Task LocalDataFlow () + { + return RunTest (nameof (LocalDataFlow)); + } + + + [Fact] + public Task ExceptionalDataFlow () + { + return RunTest (nameof (ExceptionalDataFlow)); + } + + [Fact] + public Task LocalDataFlowKeptMembers () + { + return RunTest (nameof (LocalDataFlowKeptMembers)); + } + + [Fact] + public Task MemberTypes () + { + return RunTest (nameof (MemberTypes)); + } + + [Fact] + public Task MemberTypesAllOnCopyAssembly () + { + return RunTest (nameof (MemberTypesAllOnCopyAssembly)); + } + + [Fact] + public Task MemberTypesRelationships () + { + return RunTest (nameof (MemberTypesRelationships)); + } + + [Fact] + public Task MethodParametersDataFlow () + { + return RunTest (nameof (MethodParametersDataFlow)); + } + + [Fact] + public Task MethodReturnParameterDataFlow () + { + return RunTest (nameof (MethodReturnParameterDataFlow)); + } + + [Fact] + public Task MethodThisDataFlow () + { + return RunTest (nameof (MethodThisDataFlow)); + } + + [Fact] + public Task PropertyDataFlow () + { + return RunTest (nameof (PropertyDataFlow)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task SuppressWarningWithLinkAttributes () + { + return RunTest (nameof (SuppressWarningWithLinkAttributes)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task TypeBaseTypeDataFlow () + { + return RunTest (nameof (TypeBaseTypeDataFlow)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task UnresolvedMembers () + { + return RunTest (nameof (UnresolvedMembers)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task VirtualMethodHierarchyDataflowAnnotationValidation () + { + return RunTest (nameof (VirtualMethodHierarchyDataflowAnnotationValidation)); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2273")] + public Task XmlAnnotations () + { + return RunTest (nameof (XmlAnnotations)); + } + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs new file mode 100644 index 000000000..24f0f1d3e --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/DynamicallyAccessedMembersAnalyzerTests.cs @@ -0,0 +1,1161 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using ILLink.Shared; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using VerifyCS = ILLink.RoslynAnalyzer.Tests.CSharpAnalyzerVerifier< + ILLink.RoslynAnalyzer.DynamicallyAccessedMembersAnalyzer>; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public class DynamicallyAccessedMembersAnalyzerTests + { + static Task VerifyDynamicallyAccessedMembersAnalyzer (string source, params DiagnosticResult[] expected) + { + return VerifyCS.VerifyAnalyzerAsync (source, + TestCaseUtils.UseMSBuildProperties (MSBuildPropertyOptionNames.EnableTrimAnalyzer), + expected: expected); + } + + #region SourceParameter + [Fact] + public Task SourceParameterDoesNotMatchTargetParameterAnnotations () + { + var TargetParameterWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type parameter) + { + } + + private static void M(Type type) + { + NeedsPublicMethodsOnParameter(type); + } +}"; + // (23,3): warning IL2067: 'parameter' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. + // The parameter 'type' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetParameterWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsParameter) + .WithSpan (23, 3, 23, 38) + .WithArguments ("parameter", + "C.NeedsPublicMethodsOnParameter(Type)", + "type", + "C.M(Type)", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceParameterDoesNotMatchTargetMethodReturnTypeAnnotations () + { + var TargetMethodReturnTypeWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M(Type type) + { + return type; + } +}"; + + // (19,9): warning IL2068: 'C.M(Type)' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The parameter 'type' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodReturnTypeWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsMethodReturnType) + .WithSpan (19, 16, 19, 20) + .WithArguments ("C.M(Type)", + "type", + "C.M(Type)", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceParameterDoesNotMatchTargetFieldAnnotations () + { + var TargetFieldWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + private static void M(Type type) + { + f = type; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(Foo); +}"; + + // (18,9): warning IL2069: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The parameter 'type' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetFieldWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsField) + .WithSpan (18, 9, 18, 17) + .WithArguments ("C.f", + "type", + "C.M(Type)", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceParameterDoesNotMatchTargetMethodAnnotations () + { + var TargetMethodWithAnnotations = @" +using System; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + private static void M(Type type) + { + type.GetMethod(""Bar""); + } +}"; + // The warning will be generated once dataflow is able to handle GetMethod intrinsic + + // (17,9): warning IL2070: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + // The parameter 'type' of method 'C.M(Type)' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodWithAnnotations); + /*, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchParameterTargetsThisParameter) + .WithSpan (17, 9, 17, 30) + .WithArguments ("System.Type.GetMethod(String)", + "type", + "C.M(Type)", + "'DynamicallyAccessedMemberTypes.PublicMethods'")*/ + } + #endregion + + #region SourceMethodReturnType + [Fact] + public Task SourceMethodReturnTypeDoesNotMatchTargetParameterAnnotations () + { + var TargetParameterWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class T +{ +} + +class C +{ + public static void Main() + { + NeedsPublicMethodsOnParameter(GetT()); + } + + private static void NeedsPublicMethodsOnParameter( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + private static Type GetT() + { + return typeof(T); + } +}"; + + // (13,9): warning IL2072: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethodsOnParameter(Type)'. + // The return value of method 'C.GetT()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetParameterWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) + .WithSpan (13, 9, 13, 46) + .WithArguments ("type", "C.NeedsPublicMethodsOnParameter(Type)", "C.GetT()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceMethodReturnTypeDoesNotMatchTargetMethodReturnTypeAnnotations () + { + var TargetMethodReturnTypeWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M() + { + return GetFoo(); + } + + private static Type GetFoo() + { + return typeof(Foo); + } +}"; + + // (19,9): warning IL2073: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The return value of method 'C.GetT()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodReturnTypeWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsMethodReturnType) + .WithSpan (19, 16, 19, 24) + .WithArguments ("C.M()", "C.GetFoo()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceMethodReturnTypeDoesNotMatchTargetFieldAnnotations () + { + var TargetFieldWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + f = M(); + } + + private static Type M() + { + return typeof(Foo); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; +}"; + + // (13,9): warning IL2074: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The return value of method 'C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetFieldWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsField) + .WithSpan (13, 9, 13, 16) + .WithArguments ("C.f", + "C.M()", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceMethodReturnTypeDoesNotMatchTargetMethod () + { + var TargetMethodWithAnnotations = @" +using System; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + GetFoo().GetMethod(""Bar""); + + } + + private static Type GetFoo () + { + return typeof (Foo); + } +}"; + // The warning will be generated once dataflow is able to handle GetMethod intrinsic + + // (12,9): warning IL2075: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + // The return value of method 'C.GetT()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodWithAnnotations + /*, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsThisParameter) + .WithSpan (12, 9, 12, 34) + .WithArguments ("System.Type.GetMethod(String)", "C.GetFoo()", "'DynamicallyAccessedMemberTypes.PublicMethods'")*/); + } + #endregion + + #region SourceField + [Fact] + public Task SourceFieldDoesNotMatchTargetParameterAnnotations () + { + var TargetParameterWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + private static Type f = typeof(Foo); + + public static void Main() + { + NeedsPublicMethods(f); + } + + private static void NeedsPublicMethods( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } +}"; + + // (15,9): warning IL2077: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.NeedsPublicMethods(Type)'. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetParameterWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsParameter) + .WithSpan (15, 9, 15, 30) + .WithArguments ("type", + "C.NeedsPublicMethods(Type)", + "C.f", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceFieldDoesNotMatchTargetMethodReturnTypeAnnotations () + { + var TargetMethodReturnTypeWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + private static Type f = typeof(Foo); + + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M() + { + return f; + } +}"; + + // (21,9): warning IL2078: 'C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodReturnTypeWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsMethodReturnType) + .WithSpan (21, 16, 21, 17) + .WithArguments ("C.M()", "C.f", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceFieldDoesNotMatchTargetFieldAnnotations () + { + var TargetFieldWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + private static Type f1 = typeof(Foo); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f2 = typeof(Foo); + + public static void Main() + { + f2 = f1; + } +}"; + // (18,9): warning IL2079: value stored in field 'C.f2' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The field 'C.f1' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetFieldWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsField) + .WithSpan (18, 9, 18, 16) + .WithArguments ("C.f2", + "C.f1", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceFieldDoesNotMatchTargetMethodAnnotations () + { + var TargetMethodWithAnnotations = @" +using System; + +public class Foo +{ +} + +class C +{ + private static Type f = typeof(Foo); + + public static void Main() + { + f.GetMethod(""Bar""); + } +}"; + // The warning will be generated once dataflow is able to handle GetMethod intrinsic + + // (14,9): warning IL2080: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. + // The field 'C.f' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodWithAnnotations); + /*, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchFieldTargetsThisParameter) + .WithSpan (14, 9, 14, 27) + .WithArguments ("System.Type.GetMethod(String)", + "C.f", + "'DynamicallyAccessedMemberTypes.PublicMethods'")*/ + } + #endregion + + #region SourceMethod + + static string GetSystemTypeBase () + { + return @" +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Globalization; +using System.Reflection; + +namespace System +{ + public class TestSystemTypeBase : Type + { + public override Assembly Assembly => throw new NotImplementedException (); + + public override string AssemblyQualifiedName => throw new NotImplementedException (); + + public override Type BaseType => throw new NotImplementedException (); + + public override string FullName => throw new NotImplementedException (); + + public override Guid GUID => throw new NotImplementedException (); + + public override Module Module => throw new NotImplementedException (); + + public override string Namespace => throw new NotImplementedException (); + + public override Type UnderlyingSystemType => throw new NotImplementedException (); + + public override string Name => throw new NotImplementedException (); + + public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override object[] GetCustomAttributes (bool inherit) + { + throw new NotImplementedException (); + } + + public override object[] GetCustomAttributes (Type attributeType, bool inherit) + { + throw new NotImplementedException (); + } + + public override Type GetElementType () + { + throw new NotImplementedException (); + } + + public override EventInfo GetEvent (string name, BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override EventInfo[] GetEvents (BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override FieldInfo GetField (string name, BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override FieldInfo[] GetFields (BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override Type GetInterface (string name, bool ignoreCase) + { + throw new NotImplementedException (); + } + + public override Type[] GetInterfaces () + { + throw new NotImplementedException (); + } + + public override MemberInfo[] GetMembers (BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override MethodInfo[] GetMethods (BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override Type GetNestedType (string name, BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override Type[] GetNestedTypes (BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override PropertyInfo[] GetProperties (BindingFlags bindingAttr) + { + throw new NotImplementedException (); + } + + public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) + { + throw new NotImplementedException (); + } + + public override bool IsDefined (Type attributeType, bool inherit) + { + throw new NotImplementedException (); + } + + protected override TypeAttributes GetAttributeFlagsImpl () + { + throw new NotImplementedException (); + } + + protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException (); + } + + protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException (); + } + + protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) + { + throw new NotImplementedException (); + } + + protected override bool HasElementTypeImpl () + { + throw new NotImplementedException (); + } + + protected override bool IsArrayImpl () + { + throw new NotImplementedException (); + } + + protected override bool IsByRefImpl () + { + throw new NotImplementedException (); + } + + protected override bool IsCOMObjectImpl () + { + throw new NotImplementedException (); + } + + protected override bool IsPointerImpl () + { + throw new NotImplementedException (); + } + + protected override bool IsPrimitiveImpl () + { + throw new NotImplementedException (); + } + } +}"; + } + + [Fact] + public Task SourceMethodDoesNotMatchTargetParameterAnnotations () + { + var TargetParameterWithAnnotations = @" +namespace System +{ + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(this); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } +}"; + + // (178,16): warning IL2082: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.C.M2(Type)'. + // The implicit 'this' argument of method 'System.C.M1()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetParameterWithAnnotations), + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsParameter) + .WithSpan (178, 13, 178, 21) + .WithArguments ("type", "System.C.M2(Type)", "System.C.M1()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task ConversionOperation () + { + var ConversionOperation = @" +namespace System +{ + class ConvertsToType + { + public static implicit operator Type(ConvertsToType value) => typeof (ConvertsToType); + } + + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(new ConvertsToType()); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } +}"; + + return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), ConversionOperation), + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) + .WithSpan (183, 13, 183, 37) + .WithArguments ("type", "System.C.M2(Type)", "System.ConvertsToType.implicit operator Type(ConvertsToType)", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + + [Fact] + public Task ConversionOperationAnnotationDoesNotMatch () + { + var AnnotatedConversionOperation = @" +namespace System +{ + class ConvertsToType + { + [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] + public static implicit operator Type(ConvertsToType value) => null; + } + + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(new ConvertsToType()); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } +}"; + + return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), AnnotatedConversionOperation), + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchMethodReturnTypeTargetsParameter) + .WithSpan (185, 13, 185, 37) + .WithArguments ("type", "System.C.M2(Type)", "System.ConvertsToType.implicit operator Type(ConvertsToType)", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task ConversionOperationAnnotationMatches () + { + var AnnotatedConversionOperation = @" +namespace System +{ + class ConvertsToType + { + [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] + public static implicit operator Type(ConvertsToType value) => null; + } + + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M1(); + } + + private void M1() + { + M2(new ConvertsToType()); + } + + private static void M2( + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + } +}"; + + return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), AnnotatedConversionOperation)); + } + + + [Fact] + public Task SourceMethodDoesNotMatchTargetMethodReturnTypeAnnotations () + { + var TargetMethodReturnTypeWithAnnotations = @" +namespace System +{ + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + [return: System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] + private Type M() + { + return this; + } + } +}"; + + // (180,13): warning IL2083: 'System.C.M()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetMethodReturnTypeWithAnnotations), + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsMethodReturnType) + .WithSpan (180, 20, 180, 24) + .WithArguments ("System.C.M()", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceMethodDoesNotMatchTargetFieldAnnotations () + { + var TargetFieldWithAnnotations = @" +namespace System +{ + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + private void M() + { + f = this; + } + + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers( + System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + } +}"; + + // (178,13): warning IL2084: value stored in field 'System.C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetFieldWithAnnotations), + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsField) + .WithSpan (178, 13, 178, 21) + .WithArguments ("System.C.f", + "System.C.M()", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceMethodDoesNotMatchTargetMethodAnnotations () + { + var TargetMethodWithAnnotations = @" +namespace System +{ + class C : TestSystemTypeBase + { + public static void Main() + { + new C().M(); + } + + private void M() + { + this.GetMethods(); + } + } +}"; + + // (178,13): warning IL2085: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethods()'. + // The implicit 'this' argument of method 'System.C.M()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (string.Concat (GetSystemTypeBase (), TargetMethodWithAnnotations), + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchThisParameterTargetsThisParameter) + .WithSpan (178, 13, 178, 30) + .WithArguments ("System.Type.GetMethods()", "System.C.M()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + #endregion + + [Fact] + public Task SourceGenericParameterDoesNotMatchTargetParameterAnnotations () + { + var TargetParameterWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +class C +{ + public static void Main() + { + M2<int>(); + } + + private static void M1( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + private static void M2<T>() + { + M1(typeof(T)); + } +}"; + + // (19,9): warning IL2087: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'C.M1(Type)'. + // The generic parameter 'T' of 'C.M2<T>()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetParameterWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsParameter) + .WithSpan (19, 9, 19, 22) + .WithArguments ("type", "C.M1(Type)", "T", "C.M2<T>()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceGenericParameterDoesNotMatchTargetMethodReturnTypeAnnotations () + { + var TargetMethodReturnTypeWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +class C +{ + public static void Main() + { + M<int>(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + private static Type M<T>() + { + return typeof(T); + } +}"; + + // (15,9): warning IL2088: 'C.M<T>()' method return value does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' requirements. + // The generic parameter 'T' of 'C.M<T>()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodReturnTypeWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsMethodReturnType) + .WithSpan (15, 16, 15, 25) + .WithArguments ("C.M<T>()", "T", "C.M<T>()", "'DynamicallyAccessedMemberTypes.PublicConstructors'")); + } + + [Fact] + public Task SourceGenericParameterDoesNotMatchTargetFieldAnnotations () + { + var TargetFieldWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +class C +{ + public static void Main() + { + M<int>(); + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f; + + private static void M<T>() + { + f = typeof(T); + } +}"; + + // (17,9): warning IL2089: value stored in field 'C.f' does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' requirements. + // The generic parameter 'T' of 'C.M<T>()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetFieldWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsField) + .WithSpan (17, 9, 17, 22) + .WithArguments ("C.f", + "T", + "C.M<T>()", + "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceGenericParameterDoesNotMatchTargetGenericParameterAnnotations () + { + var TargetGenericParameterWithAnnotations = @" +using System.Diagnostics.CodeAnalysis; + +class C +{ + public static void Main() + { + M2<int>(); + } + + private static void M1<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] T>() + { + } + + private static void M2<S>() + { + M1<S>(); + } +}"; + + // (17,9): warning IL2091: 'T' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' + // in 'C.M1<T>()'. The generic parameter 'S' of 'C.M2<S>()' does not have matching annotations. + // The source value must declare at least the same requirements as those declared on the target location it is assigned to. + return VerifyDynamicallyAccessedMembersAnalyzer (TargetGenericParameterWithAnnotations, + VerifyCS.Diagnostic (DiagnosticId.DynamicallyAccessedMembersMismatchTypeArgumentTargetsGenericParameter) + .WithSpan (17, 9, 17, 14) + .WithArguments ("T", "C.M1<T>()", "S", "C.M2<S>()", "'DynamicallyAccessedMemberTypes.PublicMethods'")); + } + + [Fact] + public Task SourceTypeofFlowsIntoTargetParameterAnnotations () + { + var TargetParameterWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } +}"; + return VerifyDynamicallyAccessedMembersAnalyzer (TargetParameterWithAnnotations); + } + + [Fact] + public Task SourceTypeofFlowsIntoTargetMethodReturnTypeAnnotation () + { + var TargetMethodReturnTypeWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M() + { + return typeof(Foo); + } +}"; + + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodReturnTypeWithAnnotations); + } + + [Fact] + public Task SourceParameterFlowsInfoTargetMethodReturnTypeAnnotations () + { + var TargetMethodReturnTypeWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + return type; + } +}"; + + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodReturnTypeWithAnnotations); + } + + [Fact] + public Task SourceParameterFlowsIntoTargetFieldAnnotations () + { + var TargetFieldWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + f = type; + } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + private static Type f = typeof(Foo); +}"; + + return VerifyDynamicallyAccessedMembersAnalyzer (TargetFieldWithAnnotations); + } + + [Fact] + public Task SourceParameterFlowsIntoTargetMethodAnnotations () + { + var TargetMethodWithAnnotations = @" +using System; +using System.Diagnostics.CodeAnalysis; + +public class Foo +{ +} + +class C +{ + public static void Main() + { + M(typeof(Foo)); + } + + private static void M([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + type.GetMethod(""Bar""); + } +}"; + + return VerifyDynamicallyAccessedMembersAnalyzer (TargetMethodWithAnnotations); + } + } +} diff --git a/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj b/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj index c943d7558..e6b2bff3e 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj +++ b/test/ILLink.RoslynAnalyzer.Tests/ILLink.RoslynAnalyzer.Tests.csproj @@ -1,17 +1,24 @@ -<Project Sdk="Microsoft.NET.Sdk"> +<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <Nullable>enable</Nullable> <DeterministicSourcePaths>false</DeterministicSourcePaths> + <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> + <CompilerGeneratedFilesOutputPath>generated</CompilerGeneratedFilesOutputPath> </PropertyGroup> <ItemGroup> + <Compile Remove="$(CompilerGeneratedFilesOutputPath)" /> + </ItemGroup> + + <ItemGroup> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="$(MicrosoftCodeAnalysisCSharpAnalyzerTestingXunitVersion)" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="$(MicrosoftCodeAnalysisCSharpAnalyzerTestingXunitVersion)" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisVersion)" /> <ProjectReference Include="..\..\src\ILLink.CodeFix\ILLink.CodeFixProvider.csproj" /> <ProjectReference Include="..\..\src\ILLink.RoslynAnalyzer\ILLink.RoslynAnalyzer.csproj" /> <ProjectReference Include="../Mono.Linker.Tests.Cases\Mono.Linker.Tests.Cases.csproj" /> + <ProjectReference Include="../ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> </ItemGroup> </Project> diff --git a/test/ILLink.RoslynAnalyzer.Tests/LinkAttributesTests.cs b/test/ILLink.RoslynAnalyzer.Tests/LinkAttributesTests.cs index ea7d9d528..03da6c87b 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/LinkAttributesTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/LinkAttributesTests.cs @@ -4,7 +4,7 @@ using Xunit; namespace ILLink.RoslynAnalyzer.Tests { - public sealed class LinkAttributesTests : LinkerTestBase + public sealed partial class LinkAttributesTests : LinkerTestBase { protected override string TestSuiteName => "LinkAttributes"; diff --git a/test/ILLink.RoslynAnalyzer.Tests/LinkerTestBase.cs b/test/ILLink.RoslynAnalyzer.Tests/LinkerTestBase.cs index 78b334d47..8950236ad 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/LinkerTestBase.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/LinkerTestBase.cs @@ -13,9 +13,9 @@ namespace ILLink.RoslynAnalyzer.Tests MSBuildPropertyOptionNames.EnableSingleFileAnalyzer, MSBuildPropertyOptionNames.EnableAOTAnalyzer); - protected Task RunTest ([CallerMemberName] string testName = "") + protected Task RunTest ([CallerMemberName] string testName = "", bool allowMissingWarnings = false) { - return RunTestFile (TestSuiteName, testName, MSBuildProperties); + return RunTestFile (TestSuiteName, testName, allowMissingWarnings, MSBuildProperties); } } }
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/ReflectionTests.cs b/test/ILLink.RoslynAnalyzer.Tests/ReflectionTests.cs new file mode 100644 index 000000000..dd394aeb5 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/ReflectionTests.cs @@ -0,0 +1,124 @@ +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class ReflectionTests : LinkerTestBase + { + protected override string TestSuiteName => "Reflection"; + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task ActivatorCreateInstance () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task AssemblyImportedViaReflectionWithSweptReferences () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task ConstructorsUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task ConstructorUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task EventsUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task ExpressionCallString () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task ExpressionNewType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task ExpressionPropertyMethodInfo () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task FieldsUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task MembersUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task MemberUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task MethodsUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task NestedTypesUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task ObjectGetType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task PropertiesUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task TypeHierarchyReflectionWarnings () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task TypeHierarchySuppressions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task TypeUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2578")] + public Task TypeUsedViaReflectionTypeDoesntExist () + { + return RunTest (allowMissingWarnings: true); + } + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs index 386279369..a23fd9872 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresAssemblyFilesAnalyzerTests.cs @@ -253,7 +253,7 @@ class C }"; return VerifyRequiresAssemblyFilesAnalyzer (src, // (8,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. - VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (8, 13, 8, 41).WithArguments ("System.Reflection.Assembly.GetFile(string)"), + VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (8, 13, 8, 41).WithArguments ("System.Reflection.Assembly.GetFile(String)"), // (9,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest. VerifyCS.Diagnostic (DiagnosticId.AvoidAssemblyGetFilesInSingleFile).WithSpan (9, 13, 9, 25).WithArguments ("System.Reflection.Assembly.GetFiles()") ); diff --git a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs index 31b94d94e..a201cdbb2 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs @@ -404,7 +404,7 @@ class C return VerifyRequiresUnreferencedCodeAnalyzer (source); } - [Fact] + [Fact (Skip = "https://github.com/dotnet/linker/issues/2557")] public Task TestMakeGenericTypeUsage () { var source = @" diff --git a/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs b/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs index 52643bd22..fe7a9ec0e 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/TestCaseCompilation.cs @@ -19,7 +19,8 @@ namespace ILLink.RoslynAnalyzer.Tests new RequiresDynamicCodeAnalyzer (), new COMAnalyzer (), new RequiresAssemblyFilesAnalyzer (), - new RequiresUnreferencedCodeAnalyzer ()); + new RequiresUnreferencedCodeAnalyzer (), + new DynamicallyAccessedMembersAnalyzer ()); public static Task<(CompilationWithAnalyzers Compilation, SemanticModel SemanticModel, List<Diagnostic> ExceptionDiagnostics)> CreateCompilation ( string src, diff --git a/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs b/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs index 3c42b8d0e..0ebb36a93 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -40,17 +41,34 @@ namespace ILLink.RoslynAnalyzer.Tests return s_net6Refs; } - public static async Task RunTestFile (string suiteName, string testName, params (string, string)[] msbuildProperties) + public static string FindTestDir (string rootDir, string suiteName) + { + string[] suiteParts = suiteName.Split ('.'); + string currentDir = rootDir; + foreach (var suitePart in suiteParts) { + string dirCandidate = Path.Combine (currentDir, suitePart); + if (currentDir == rootDir || Directory.Exists (dirCandidate)) + currentDir = dirCandidate; + else + currentDir += $".{suitePart}"; + } + + return currentDir; + } + + public static async Task RunTestFile (string suiteName, string testName, bool allowMissingWarnings, params (string, string)[] msbuildProperties) { GetDirectoryPaths (out string rootSourceDir, out string testAssemblyPath); Debug.Assert (Path.GetFileName (rootSourceDir) == MonoLinkerTestsCases); - var testPath = Path.Combine (rootSourceDir, suiteName, $"{testName}.cs"); + var testDir = FindTestDir (rootSourceDir, suiteName); + var testPath = Path.Combine (testDir, $"{testName}.cs"); Assert.True (File.Exists (testPath)); var tree = SyntaxFactory.ParseSyntaxTree ( SourceText.From (File.OpenRead (testPath), Encoding.UTF8), path: testPath); - var testDependenciesSource = GetTestDependencies (rootSourceDir, tree) + var testDependenciesSource = GetTestDependencies (testDir, tree) + .Where (f => Path.GetExtension (f) == ".cs") .Select (f => SyntaxFactory.ParseSyntaxTree (SourceText.From (File.OpenRead (f)))); var additionalFiles = GetAdditionalFiles (rootSourceDir, tree); @@ -65,19 +83,47 @@ namespace ILLink.RoslynAnalyzer.Tests var diags = (await comp.GetAnalyzerDiagnosticsAsync ()).AddRange (exceptionDiagnostics); var testChecker = new TestChecker ((CSharpSyntaxTree) tree, model, diags); - testChecker.Check (); + testChecker.Check (allowMissingWarnings); } - private static IEnumerable<string> GetTestDependencies (string rootSourceDir, SyntaxTree testSyntaxTree) + private static IEnumerable<string> GetTestDependencies (string testDir, SyntaxTree testSyntaxTree) { foreach (var attribute in testSyntaxTree.GetRoot ().DescendantNodes ().OfType<AttributeSyntax> ()) { - if (attribute.Name.ToString () != "SetupCompileBefore") + var attributeName = attribute.Name.ToString (); + if (attributeName != "SetupCompileBefore" && attributeName != "SandboxDependency") continue; - var testNamespace = testSyntaxTree.GetRoot ().DescendantNodes ().OfType<NamespaceDeclarationSyntax> ().Single ().Name.ToString (); - var testSuiteName = testNamespace.Substring (testNamespace.LastIndexOf ('.') + 1); var args = LinkerTestBase.GetAttributeArguments (attribute); - foreach (var sourceFile in ((ImplicitArrayCreationExpressionSyntax) args["#1"]).DescendantNodes ().OfType<LiteralExpressionSyntax> ()) - yield return Path.Combine (rootSourceDir, testSuiteName, LinkerTestBase.GetStringFromExpression (sourceFile)); + + switch (attributeName) { + case "SetupCompileBefore": { + var arrayExpression = args["#1"]; + if (arrayExpression is not (ArrayCreationExpressionSyntax or ImplicitArrayCreationExpressionSyntax)) + throw new InvalidOperationException (); + foreach (var sourceFile in ((ExpressionSyntax) args["#1"]).DescendantNodes ().OfType<LiteralExpressionSyntax> ()) + yield return Path.Combine (testDir, LinkerTestBase.GetStringFromExpression (sourceFile)); + break; + } + case "SandboxDependency": { + var argExpression = args["#0"]; + string sourceFile; + if (argExpression is TypeOfExpressionSyntax typeOfSyntax) { + // If the argument is a Type, assume the dependency is located in a file with the + // outermost declaring type's name in the Dependencies subdirectory. + var typeNameSyntax = typeOfSyntax.Type; + while (typeNameSyntax is QualifiedNameSyntax qualifiedNameSyntax) + typeNameSyntax = qualifiedNameSyntax.Left; + sourceFile = Path.Combine ("Dependencies", $"{typeNameSyntax.ToString ()}.cs"); + } else { + sourceFile = LinkerTestBase.GetStringFromExpression (args["#0"]); + } + if (!sourceFile.EndsWith (".cs")) + throw new NotSupportedException (); + yield return Path.Combine (testDir, sourceFile); + break; + } + default: + throw new InvalidOperationException (); + } } } @@ -85,16 +131,24 @@ namespace ILLink.RoslynAnalyzer.Tests { var resolver = new XmlFileResolver (rootSourceDir); foreach (var attribute in tree.GetRoot ().DescendantNodes ().OfType<AttributeSyntax> ()) { - if (attribute.Name.ToString () == nameof (SetupLinkAttributesFile) - || (attribute.Name.ToString ().Contains ("SetupCompileResource") - && (attribute.ArgumentList?.Arguments[1].ToString ()) == "\"ILLink.LinkAttributes.xml\"")) { - var xmlFileName = attribute.ArgumentList?.Arguments[0].ToString ().Trim ('"') ?? ""; - var resolvedPath = resolver.ResolveReference (xmlFileName, rootSourceDir); - if (resolvedPath != null) { - var stream = resolver.OpenRead (resolvedPath); - XmlText text = new ("ILLink.LinkAttributes.xml", stream); - yield return text; - } + switch (attribute.Name.ToString ()) { + case nameof (SetupLinkAttributesFile): + break; + case nameof (SetupCompileResourceAttribute): + var args = attribute.ArgumentList?.Arguments; + if (args?.Count == 2 && args?[1].ToString () == "\"ILLink.LinkAttributes.xml\"") + break; + continue; + default: + continue; + } + + var xmlFileName = attribute.ArgumentList?.Arguments[0].ToString ().Trim ('"') ?? ""; + var resolvedPath = resolver.ResolveReference (xmlFileName, rootSourceDir); + if (resolvedPath != null) { + var stream = resolver.OpenRead (resolvedPath); + XmlText text = new ("ILLink.LinkAttributes.xml", stream); + yield return text; } } } @@ -119,6 +173,13 @@ namespace ILLink.RoslynAnalyzer.Tests testAssemblyPath = Path.GetFullPath (Path.Combine (artifactsBinDir, "ILLink.RoslynAnalyzer.Tests", configDirectoryName, tfm)); } + // Accepts typeof expressions, with a format specifier + public static string GetStringFromExpression (TypeOfExpressionSyntax expr, SemanticModel semanticModel, SymbolDisplayFormat displayFormat) + { + var typeSymbol = semanticModel.GetSymbolInfo (expr.Type).Symbol; + return typeSymbol?.ToDisplayString (displayFormat) ?? throw new InvalidOperationException (); + } + // Accepts string literal expressions or binary expressions concatenating strings public static string GetStringFromExpression (ExpressionSyntax expr, SemanticModel? semanticModel = null) { @@ -143,11 +204,6 @@ namespace ILLink.RoslynAnalyzer.Tests Assert.Equal (SyntaxKind.StringLiteralToken, token.Kind ()); return token.ValueText; - case SyntaxKind.TypeOfExpression: - var typeofExpression = (TypeOfExpressionSyntax) expr; - var typeSymbol = semanticModel.GetSymbolInfo (typeofExpression.Type).Symbol; - return typeSymbol?.GetDisplayName () ?? string.Empty; - default: Assert.True (false, "Unsupported expr kind " + expr.Kind ()); return null!; diff --git a/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs b/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs index e6a9dfc83..515c24372 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/TestChecker.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -23,6 +22,7 @@ namespace ILLink.RoslynAnalyzer.Tests private readonly IReadOnlyList<Diagnostic> _diagnostics; private readonly List<Diagnostic> _unmatched; private readonly List<(AttributeSyntax Attribute, string Message)> _missing; + private readonly List<AttributeSyntax> _expectedNoWarnings; public TestChecker ( CSharpSyntaxTree tree, @@ -38,26 +38,30 @@ namespace ILLink.RoslynAnalyzer.Tests // Filled in later _unmatched = new List<Diagnostic> (); _missing = new List<(AttributeSyntax Attribute, string Message)> (); + _expectedNoWarnings = new List<AttributeSyntax> (); } - public void Check () + public void Check (bool allowMissingWarnings) { _unmatched.Clear (); _unmatched.AddRange (_diagnostics); _missing.Clear (); + _expectedNoWarnings.Clear (); Visit (_tree.GetRoot ()); string message = ""; - if (_missing.Any ()) { + if (!allowMissingWarnings && _missing.Any ()) { var missingLines = string.Join ( Environment.NewLine, - _missing.Select (md => $"({md.Attribute.GetLocation ().GetLineSpan ()}) {md.Message}")); + _missing.Select (md => $"({md.Attribute.Parent?.Parent?.GetLocation ().GetLineSpan ()}) {md.Message}")); message += $@"Expected warnings were not generated:{Environment.NewLine}{missingLines}{Environment.NewLine}"; } - if (_unmatched.Any ()) { - - message += $"Unexpected warnings were generated:{Environment.NewLine}{string.Join (Environment.NewLine, _unmatched)}"; + var unexpected = _unmatched.Where (diag => + diag.Location.SourceTree == null || + _expectedNoWarnings.Any (attr => attr.Parent?.Parent?.Span.Contains (diag.Location.SourceSpan) == true)); + if (unexpected.Any ()) { + message += $"Unexpected warnings were generated:{Environment.NewLine}{string.Join (Environment.NewLine, unexpected)}"; } if (message.Length > 0) { @@ -145,8 +149,14 @@ namespace ILLink.RoslynAnalyzer.Tests foreach (var attrList in attrLists) { foreach (var attribute in attrList.Attributes) { - if (attribute.Name.ToString () == "LogDoesNotContain") + switch (attribute.Name.ToString ()) { + case "LogDoesNotContain": ValidateLogDoesNotContainAttribute (attribute, memberDiagnostics); + break; + case "ExpectedNoWarnings": + _expectedNoWarnings.Add (attribute); + break; + } if (!IsExpectedDiagnostic (attribute)) continue; @@ -176,8 +186,6 @@ namespace ILLink.RoslynAnalyzer.Tests } return true; - case "UnrecognizedReflectionAccessPattern": - return true; default: return false; } @@ -214,8 +222,6 @@ namespace ILLink.RoslynAnalyzer.Tests return TryValidateExpectedWarningAttribute (attribute!, diagnostics, out matchIndex, out missingDiagnosticMessage); case "LogContains": return TryValidateLogContainsAttribute (attribute!, diagnostics, out matchIndex, out missingDiagnosticMessage); - case "UnrecognizedReflectionAccessPattern": - return TryValidateUnrecognizedReflectionAccessPatternAttribute (attribute!, diagnostics, out matchIndex, out missingDiagnosticMessage); default: throw new InvalidOperationException ($"Unsupported attribute type {attribute.Name}"); } @@ -226,7 +232,7 @@ namespace ILLink.RoslynAnalyzer.Tests missingDiagnosticMessage = null; matchIndex = null; var args = LinkerTestBase.GetAttributeArguments (attribute); - string expectedWarningCode = LinkerTestBase.GetStringFromExpression (args["#0"]); + string expectedWarningCode = LinkerTestBase.GetStringFromExpression (args["#0"], _semanticModel); if (!expectedWarningCode.StartsWith ("IL")) throw new InvalidOperationException ($"Expected warning code should start with \"IL\" prefix."); @@ -249,6 +255,9 @@ namespace ILLink.RoslynAnalyzer.Tests bool Matches (Diagnostic diagnostic) { + if (!attribute.Parent?.Parent?.Span.Contains (diagnostic.Location.SourceSpan) == true) + return false; + if (diagnostic.Id != expectedWarningCode) return false; @@ -265,7 +274,7 @@ namespace ILLink.RoslynAnalyzer.Tests missingDiagnosticMessage = null; matchIndex = null; var args = LinkerTestBase.GetAttributeArguments (attribute); - var text = LinkerTestBase.GetStringFromExpression (args["#0"]); + var text = LinkerTestBase.GetStringFromExpression (args["#0"], _semanticModel); // If the text starts with `warning IL...` then it probably follows the pattern // 'warning <diagId>: <location>:' @@ -293,89 +302,12 @@ namespace ILLink.RoslynAnalyzer.Tests return false; } - private static void ValidateLogDoesNotContainAttribute (AttributeSyntax attribute, IReadOnlyList<Diagnostic> diagnosticMessages) + private void ValidateLogDoesNotContainAttribute (AttributeSyntax attribute, IReadOnlyList<Diagnostic> diagnosticMessages) { var arg = Assert.Single (LinkerTestBase.GetAttributeArguments (attribute)); - var text = LinkerTestBase.GetStringFromExpression (arg.Value); + var text = LinkerTestBase.GetStringFromExpression (arg.Value, _semanticModel); foreach (var diagnostic in diagnosticMessages) Assert.DoesNotContain (text, diagnostic.GetMessage ()); } - - private bool TryValidateUnrecognizedReflectionAccessPatternAttribute (AttributeSyntax attribute, List<Diagnostic> diagnostics, out int? matchIndex, out string? missingDiagnosticMessage) - { - missingDiagnosticMessage = null; - matchIndex = null; - var args = LinkerTestBase.GetAttributeArguments (attribute); - - MemberDeclarationSyntax sourceMember = attribute.Ancestors ().OfType<MemberDeclarationSyntax> ().First (); - if (_semanticModel.GetDeclaredSymbol (sourceMember) is not ISymbol memberSymbol) - return false; - - string sourceMemberName = memberSymbol!.GetDisplayName (); - string expectedReflectionMemberMethodType = LinkerTestBase.GetStringFromExpression (args["#0"], _semanticModel); - string expectedReflectionMemberMethodName = LinkerTestBase.GetStringFromExpression (args["#1"], _semanticModel); - - var reflectionMethodParameters = new List<string> (); - if (args.TryGetValue ("#2", out var reflectionMethodParametersExpr) || args.TryGetValue ("reflectionMethodParameters", out reflectionMethodParametersExpr)) { - if (reflectionMethodParametersExpr is ArrayCreationExpressionSyntax arrayReflectionMethodParametersExpr) { - foreach (var rmp in arrayReflectionMethodParametersExpr.Initializer!.Expressions) - reflectionMethodParameters.Add (LinkerTestBase.GetStringFromExpression (rmp, _semanticModel)); - } - } - - var expectedStringsInMessage = new List<string> (); - if (args.TryGetValue ("#3", out var messageExpr) || args.TryGetValue ("message", out messageExpr)) { - if (messageExpr is ArrayCreationExpressionSyntax arrayMessageExpr) { - foreach (var m in arrayMessageExpr.Initializer!.Expressions) - expectedStringsInMessage.Add (LinkerTestBase.GetStringFromExpression (m, _semanticModel)); - } - } - - string expectedWarningCode = string.Empty; - if (args.TryGetValue ("#4", out var messageCodeExpr) || args.TryGetValue ("messageCode", out messageCodeExpr)) { - expectedWarningCode = LinkerTestBase.GetStringFromExpression (messageCodeExpr); - Assert.True (expectedWarningCode.StartsWith ("IL"), - $"The warning code specified in {messageCodeExpr.ToString ()} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'"); - } - - // Don't validate the return type becasue this is not included in the diagnostic messages. - - var sb = new StringBuilder (); - - // Format the member signature the same way Roslyn would since this is what will be included in the warning message. - sb.Append (expectedReflectionMemberMethodType).Append (".").Append (expectedReflectionMemberMethodName); - if (!expectedReflectionMemberMethodName.EndsWith (".get") && - !expectedReflectionMemberMethodName.EndsWith (".set") && - reflectionMethodParameters is not null) - sb.Append ("(").Append (string.Join (", ", reflectionMethodParameters)).Append (")"); - - var reflectionAccessPattern = sb.ToString (); - - for (int i = 0; i < diagnostics.Count; i++) { - if (Matches (diagnostics[i])) { - matchIndex = i; - return true; - } - } - - missingDiagnosticMessage = $"Expected to find unrecognized reflection access pattern '{(expectedWarningCode == string.Empty ? "" : expectedWarningCode + " ")}" + - $"{sourceMemberName}: Usage of {reflectionAccessPattern} unrecognized."; - return false; - - bool Matches (Diagnostic diagnostic) - { - if (!string.IsNullOrEmpty (expectedWarningCode) && diagnostic.Id != expectedWarningCode) - return false; - - // Don't check whether the message contains the source member name. Roslyn's diagnostics don't include the source - // member as part of the message. - - foreach (var expectedString in expectedStringsInMessage) - if (!diagnostic.GetMessage ().Contains (expectedString)) - return false; - - return diagnostic.GetMessage ().Contains (reflectionAccessPattern); - } - } } } diff --git a/test/ILLink.RoslynAnalyzer.Tests/UnreachableBlockTests.cs b/test/ILLink.RoslynAnalyzer.Tests/UnreachableBlockTests.cs new file mode 100644 index 000000000..67eac2546 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/UnreachableBlockTests.cs @@ -0,0 +1,16 @@ +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class UnreachableBlockTests : LinkerTestBase + { + protected override string TestSuiteName => "UnreachableBlock"; + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2415")] + public Task TryFilterBlocks () + { + return RunTest (allowMissingWarnings: true); + } + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs index 37c7ae4f9..2f0aba69e 100644 --- a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs +++ b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs @@ -32,6 +32,9 @@ namespace ILLink.RoslynAnalyzer.Tests public static DiagnosticResult Diagnostic (DiagnosticDescriptor descriptor) => CSharpAnalyzerVerifier<TAnalyzer, XUnitVerifier>.Diagnostic (descriptor); + public static DiagnosticResult Diagnostic (DiagnosticId diagnosticId) + => CSharpAnalyzerVerifier<TAnalyzer, XUnitVerifier>.Diagnostic (DiagnosticDescriptors.GetDiagnosticDescriptor (diagnosticId)); + /// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/> public static async Task VerifyAnalyzerAsync (string src, (string, string)[]? analyzerOptions = null, IEnumerable<MetadataReference>? additionalReferences = null, params DiagnosticResult[] expected) { diff --git a/test/ILLink.RoslynAnalyzer.Tests/Warnings.WarningSuppressionTests.cs b/test/ILLink.RoslynAnalyzer.Tests/Warnings.WarningSuppressionTests.cs new file mode 100644 index 000000000..3f0750edc --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/Warnings.WarningSuppressionTests.cs @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Warnings +{ + public sealed partial class WarningSuppressionTests : LinkerTestBase + { + protected override string TestSuiteName => "Warnings.WarningSuppression"; + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2579")] + public Task SuppressWarningsInCompilerGeneratedCode () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2579")] + public Task SuppressWarningsInMembersAndTypesUsingTarget () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact (Skip = "https://github.com/dotnet/linker/issues/2579")] + public Task SuppressWarningsViaXml () + { + return RunTest (allowMissingWarnings: true); + } + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AdvancedTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AdvancedTests.g.cs new file mode 100644 index 000000000..cb377751d --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AdvancedTests.g.cs @@ -0,0 +1,29 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class AdvancedTests : LinkerTestBase + { + + [Fact] + public Task DeadCodeElimination1 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FieldThatOnlyGetsSetIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeCheckRemovalDisabled () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.CscTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.CscTests.g.cs new file mode 100644 index 000000000..19c50663c --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.CscTests.g.cs @@ -0,0 +1,121 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Attributes +{ + public sealed partial class CscTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.Csc"; + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeArrayOnAttributeCtorOnType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnAssemblyOtherTypesInAttributeAssemblyUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnEvent () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnProperty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeCtorOnType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnEvent () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnProperty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributeFieldOnType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnEvent () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnProperty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyIsTypeOnAttributePropertyOnType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnlyTypeUsedInAssemblyWithReferenceIsTypeOnAttributeCtorOnType () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.Debugger.KeepDebugMembersTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.Debugger.KeepDebugMembersTests.g.cs new file mode 100644 index 000000000..f9b9045f6 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.Debugger.KeepDebugMembersTests.g.cs @@ -0,0 +1,91 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Attributes.Debugger +{ + public sealed partial class KeepDebugMembersTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.Debugger.KeepDebugMembers"; + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTarget () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetOnUnusedType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInOtherAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInSameAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfGenericTypeInOtherAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameOfNestedTypeInOtherAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnGenerics () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeThatIsNotUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayOnTypeWithCallToExtensionMethodOnFieldType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayOnTypeWithCallToMethodOnFieldType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnAssemblyUsingTarget () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnType () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.DebuggerTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.DebuggerTests.g.cs new file mode 100644 index 000000000..ce49d1c03 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.DebuggerTests.g.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Attributes +{ + public sealed partial class DebuggerTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.Debugger"; + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTarget () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetOnUnusedType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnAssemblyUsingTargetTypeNameInOtherAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeCopy () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeThatIsNotUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerDisplayAttributeOnTypeWithNonExistentMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnAssemblyUsingTarget () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DebuggerTypeProxyAttributeOnType () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.NoSecurityTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.NoSecurityTests.g.cs new file mode 100644 index 000000000..0b1237f30 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.NoSecurityTests.g.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Attributes +{ + public sealed partial class NoSecurityTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.NoSecurity"; + + [Fact] + public Task CoreLibrarySecurityAttributeTypesAreRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.OnlyKeepUsedTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.OnlyKeepUsedTests.g.cs new file mode 100644 index 000000000..120333111 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.OnlyKeepUsedTests.g.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Attributes +{ + public sealed partial class OnlyKeepUsedTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.OnlyKeepUsed"; + + [Fact] + public Task ComAttributesArePreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ComAttributesAreRemovedWhenFeatureExcluded () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ContextStaticIsPreservedOnField () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CoreLibraryUnusedAssemblyAttributesAreRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CoreLibraryUsedAssemblyAttributesAreKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FixedLengthArrayAttributesArePreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithUnmanagedConstraint () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NullableOnConstraints () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ThreadStaticIsPreservedOnField () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.StructLayoutTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.StructLayoutTests.g.cs new file mode 100644 index 000000000..93c54e738 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Attributes.StructLayoutTests.g.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Attributes +{ + public sealed partial class StructLayoutTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes.StructLayout"; + + [Fact] + public Task AutoClass () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ExplicitClass () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SequentialClass () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AttributesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AttributesTests.g.cs new file mode 100644 index 000000000..672db426f --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/AttributesTests.g.cs @@ -0,0 +1,97 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class AttributesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Attributes"; + + [Fact] + public Task AttributeOnPreservedTypeIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInConstructorIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInDifferentNamespaceIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInFieldIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithTypeUsedInPropertySetterIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnPreservedTypeWithUsedSetter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnUsedFieldIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnUsedMethodIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AttributeOnUsedPropertyIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CoreLibraryAssemblyAttributesAreKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FixedLengthArrayAttributesArePreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MarshalAsCustomMarshalerInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeUsedInObjectArrayConstructorArgumentOnAttributeIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithDynamicInterfaceCastableImplementationAttributeIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeatures.ETWTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeatures.ETWTests.g.cs new file mode 100644 index 000000000..d2168dda9 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeatures.ETWTests.g.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.BCLFeatures +{ + public sealed partial class ETWTests : LinkerTestBase + { + + protected override string TestSuiteName => "BCLFeatures.ETW"; + + [Fact] + public Task BaseRemovedEventSource () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task BaseRemovedEventSourceEmptyBody () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task BaseRemovedEventSourceNonVoidReturn () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CustomEventSource () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CustomLibraryEventSource () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task Excluded () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalsOfModifiedMethodAreRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NonEventWithLog () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StubbedMethodWithExceptionHandlers () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeaturesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeaturesTests.g.cs new file mode 100644 index 000000000..85b1703fe --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BCLFeaturesTests.g.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class BCLFeaturesTests : LinkerTestBase + { + + protected override string TestSuiteName => "BCLFeatures"; + + [Fact] + public Task SerializationCtors () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs new file mode 100644 index 000000000..a6fd75c94 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs @@ -0,0 +1,139 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class BasicTests : LinkerTestBase + { + + protected override string TestSuiteName => "Basic"; + + [Fact] + public Task ComplexNestedClassesHasUnusedRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DelegateBeginInvokeEndInvokePair () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InitializerForArrayIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InstantiatedTypeWithOverridesFromObject () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMethodImplementedOnBaseClassDoesNotGetStripped () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MultiLevelNestedClassesAllRemovedWhenNonUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithOverridesFromObject () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UninvokedInterfaceMemberGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedClassGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedEventGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedFieldGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedFieldsOfStructsAreKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedMethodGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedNestedClassGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedPropertyGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedPropertySetterRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedEventIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedGenericInterfaceIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedInterfaceIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedPropertyIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedStructIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CodegenAnnotationTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CodegenAnnotationTests.g.cs new file mode 100644 index 000000000..18ed8a752 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CodegenAnnotationTests.g.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class CodegenAnnotationTests : LinkerTestBase + { + + protected override string TestSuiteName => "CodegenAnnotation"; + + [Fact] + public Task ReflectionBlockedTest () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLine.MvidTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLine.MvidTests.g.cs new file mode 100644 index 000000000..961c8056d --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLine.MvidTests.g.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.CommandLine +{ + public sealed partial class MvidTests : LinkerTestBase + { + + protected override string TestSuiteName => "CommandLine.Mvid"; + + [Fact] + public Task DefaultMvidBehavior () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DeterministicMvidWorks () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NewMvidWorks () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RetainMvid () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLineTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLineTests.g.cs new file mode 100644 index 000000000..acdcc1c58 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CommandLineTests.g.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class CommandLineTests : LinkerTestBase + { + + protected override string TestSuiteName => "CommandLine"; + + [Fact] + public Task AddCustomStep () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CustomStepData () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InvalidArguments () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ResponseFilesWork () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ComponentModelTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ComponentModelTests.g.cs new file mode 100644 index 000000000..969ad87db --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ComponentModelTests.g.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class ComponentModelTests : LinkerTestBase + { + + protected override string TestSuiteName => "ComponentModel"; + + [Fact] + public Task CustomTypeConvertor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeConverterOnMembers () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeDescriptionProviderAttributeOnType () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CoreLinkTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CoreLinkTests.g.cs new file mode 100644 index 000000000..748b04491 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CoreLinkTests.g.cs @@ -0,0 +1,79 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class CoreLinkTests : LinkerTestBase + { + + protected override string TestSuiteName => "CoreLink"; + + [Fact] + public Task CanOverrideIsTrimmableAttribute () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanUseIsTrimmableAttribute () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CopyOfCoreLibrariesKeepsUnusedTypes () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DelegateAndMulticastDelegateKeepInstantiatedReqs () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InstantiatedStructWithOverridesFromObject () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InstantiatedTypeWithOverridesFromObject () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InvalidIsTrimmableAttribute () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LinkingOfCoreLibrariesRemovesUnusedMethods () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LinkingOfCoreLibrariesRemovesUnusedTypes () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithOverridesFromObject () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoSecurityPlusOnlyKeepUsedRemovesAllSecurityAttributesFromCoreLibraries () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CppCLITests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CppCLITests.g.cs new file mode 100644 index 000000000..e31558f42 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/CppCLITests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class CppCLITests : LinkerTestBase + { + + protected override string TestSuiteName => "CppCLI"; + + [Fact] + public Task CppCLIAssemblyIsAnalyzed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NonCopyActionWarnOnCppCLI () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file 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 new file mode 100644 index 000000000..2b4129600 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DataFlowTests.g.cs @@ -0,0 +1,23 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class DataFlowTests : LinkerTestBase + { + + [Fact] + public Task MethodByRefParameterDataFlow () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodByRefReturnDataFlow () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DynamicDependenciesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DynamicDependenciesTests.g.cs new file mode 100644 index 000000000..d512c99c9 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/DynamicDependenciesTests.g.cs @@ -0,0 +1,115 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class DynamicDependenciesTests : LinkerTestBase + { + + protected override string TestSuiteName => "DynamicDependencies"; + + [Fact] + public Task DynamicDependencyField () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyFromAttributeXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyFromAttributeXmlOnNonReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyFromCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyKeptOption () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMemberSignatureWildcard () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMemberTypes () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyChained () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyChainedReference () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyWithEmbeddedXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyMethodInNonReferencedAssemblyWithSweptReferences () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyOnUnusedMethodInNonReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithCopyUsedAction () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs new file mode 100644 index 000000000..809796a7c --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ExtensibilityTests.g.cs @@ -0,0 +1,61 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class ExtensibilityTests : LinkerTestBase + { + + protected override string TestSuiteName => "Extensibility"; + + [Fact] + public Task CustomStepCanPreserveMethodsAfterMark () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CustomStepCanPreserveMethodsBeforeMark () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CustomStepCanResolveTypesAfterSweep () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CustomStepsCanShareState () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MarkHandlerUsage () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MarkSubStepsDispatcherUsage () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SubStepDispatcherFields () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SubStepDispatcherUsage () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FeatureSettingsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FeatureSettingsTests.g.cs new file mode 100644 index 000000000..a50554a30 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FeatureSettingsTests.g.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class FeatureSettingsTests : LinkerTestBase + { + + protected override string TestSuiteName => "FeatureSettings"; + + [Fact] + public Task FeatureDescriptors () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FeatureSubstitutions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FeatureSubstitutionsInvalid () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FeatureSubstitutionsNested () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FunctionPointersTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FunctionPointersTests.g.cs new file mode 100644 index 000000000..9d1e196a5 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/FunctionPointersTests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class FunctionPointersTests : LinkerTestBase + { + + protected override string TestSuiteName => "FunctionPointers"; + + [Fact] + public Task CanCompileInterfaceWithFunctionPointerParameter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileMethodWithFunctionPointerParameter () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/GenericsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/GenericsTests.g.cs new file mode 100644 index 000000000..dbee243e2 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/GenericsTests.g.cs @@ -0,0 +1,97 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class GenericsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Generics"; + + [Fact] + public Task ArrayVariantCasting () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CorrectOverloadedMethodGetsStrippedInGenericClass () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DerivedClassWithMethodOfSameNameAsBaseButDifferentNumberOfGenericParametersUnusedBaseWillGetStripped () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInstanceInterfaceMethodImplementedWithDifferentGenericArgumentNameDoesNotGetStripped () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MdArrayVariantCasting () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameterNestedCase () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParameterWhichHasGenericParametersAndOverrideUsesADifferentNameForGenericParameterNestedCase2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NewConstraintOnClass () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideWithAnotherVirtualMethodOfSameNameWithDifferentParameterType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverloadedGenericMethodInGenericClassIsNotStripped () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverloadedGenericMethodInstanceInGenericClassIsNotStripped () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverloadedGenericMethodWithNoParametersIsNotStripped () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task VariantCasting () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NoKeptCtor.OverrideRemovalTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NoKeptCtor.OverrideRemovalTests.g.cs new file mode 100644 index 000000000..138d16fdd --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NoKeptCtor.OverrideRemovalTests.g.cs @@ -0,0 +1,67 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.AbstractClasses.NoKeptCtor +{ + public sealed partial class OverrideRemovalTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.AbstractClasses.NoKeptCtor.OverrideRemoval"; + + [Fact] + public Task CanDisableOverrideRemoval () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractIsKeptNonEmpty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfVirtualCanBeRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfVirtualCanBeRemoved2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfVirtualCanBeRemoved3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideThatAlsoFulfilsInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreservesOverriddenMethodOverrideOfUsedVirtualStillRemoved2 () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NotKeptCtorTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NotKeptCtorTests.g.cs new file mode 100644 index 000000000..32fc3e8a8 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClasses.NotKeptCtorTests.g.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.AbstractClasses +{ + public sealed partial class NotKeptCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.AbstractClasses.NotKeptCtor"; + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly4 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly5 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly6 () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClassesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClassesTests.g.cs new file mode 100644 index 000000000..4191d3324 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.AbstractClassesTests.g.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance +{ + public sealed partial class AbstractClassesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.AbstractClasses"; + + [Fact] + public Task TypeWithBaseInCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithBaseInCopiedAssembly2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithBaseInCopiedAssembly3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithBaseInCopiedAssembly4 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithBaseInCopiedAssembly5 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithBaseInCopiedAssembly6 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAbstractMethodRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedVirtualMethodRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverrideOfAbstractMethodIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverrideOfVirtualMethodIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Complex.NoKeptCtorTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Complex.NoKeptCtorTests.g.cs new file mode 100644 index 000000000..67595e32f --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Complex.NoKeptCtorTests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Complex +{ + public sealed partial class NoKeptCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Complex.NoKeptCtor"; + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved2 () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs new file mode 100644 index 000000000..47d8e64e2 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.DefaultInterfaceMethodsTests.g.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces +{ + public sealed partial class DefaultInterfaceMethodsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.DefaultInterfaceMethods"; + + [Fact] + public Task DefaultInterfaceMethodCallIntoClass () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericDefaultInterfaceMethods () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleDefaultInterfaceMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedDefaultInterfaceImplementation () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMemberTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMemberTests.g.cs new file mode 100644 index 000000000..235f16b06 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMemberTests.g.cs @@ -0,0 +1,187 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType +{ + public sealed partial class BaseProvidesInterfaceMemberTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.BaseProvidesInterfaceMember"; + + [Fact] + public Task GenericInterfaceWithEvent () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericBaseMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericBaseMethodWithExplicit () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericMethod2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithGenericMethod3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethod2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethod3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodComplex () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodComplex2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBaseInterfaces () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBases () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBases2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyBases3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodManyVariations () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodNested () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodOnNoInstanceCtor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithMethodOnNoInstanceCtor2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertyGetter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertyGetter2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertySetter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericInterfaceWithPropertySetter2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceRemovedWhenMethodUsedDirectly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleEvent () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethodOnNoInstanceCtor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethodOnNoInstanceCtor2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleProperty () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoInstanceCtorTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoInstanceCtorTests.g.cs new file mode 100644 index 000000000..d66b16fd1 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoInstanceCtorTests.g.cs @@ -0,0 +1,55 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType +{ + public sealed partial class NoInstanceCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoInstanceCtor"; + + [Fact] + public Task NoInstanceCtorAndAssemblyPreserveAll () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveAll () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveFields () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveFieldsWithInterfacesMarked () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveMethods () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveMethodsWithInterfacesMarked () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoInstanceCtorAndTypePreserveNone () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeededTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeededTests.g.cs new file mode 100644 index 000000000..df070b8d8 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeededTests.g.cs @@ -0,0 +1,151 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType +{ + public sealed partial class NoKeptCtorButInterfaceNeededTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoKeptCtorButInterfaceNeeded"; + + [Fact] + public Task ArrayWithIndexAssignedToReturnValue () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FieldDowncastedToInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericTypeWithConstraint () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericTypeWithConstraint2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericTypeWithConstraint3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceOnMultipleBases () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalAndNestedInterfaces () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalArrayPassedAsParameter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalDowncastedToInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameterToGeneric () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameterToGenericWithConstraint () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalPassedAsParameterToGenericWithConstraint2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfaces1 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfaces2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfaces3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfacesWithExplicit1 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NestedInterfacesWithExplicitAndNormal1 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ParameterAndLocal () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ParameterOutAndLocal () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ParameterRefAndLocal () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ReturnValueDowncastedToInterface () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorTests.g.cs new file mode 100644 index 000000000..06c86462c --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceType.NoKeptCtorTests.g.cs @@ -0,0 +1,127 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnReferenceType +{ + public sealed partial class NoKeptCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType.NoKeptCtor"; + + [Fact] + public Task ComInterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DynamicDependencyPreservesInterfaceMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ExplicitInterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task GenericWithConstraintDoesNotCauseOtherTypesToKeepInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsedWithCctor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceFromCopiedAssemblyCanBeRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethodMultiple () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LocalDowncastDoesNotCuaseOtherTypesToKeepInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ObjectHardCastedToInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyPreservesInterfaceMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeHasExplicitInterfaceMethodPreservedViaXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeHasExplicitInterfacePropertyPreservedViaXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeHasInterfaceMethodPreservedViaXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveFields () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveMethods () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveMethodsAndInterfaceTypeMarked () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceTypeTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceTypeTests.g.cs new file mode 100644 index 000000000..b61435b86 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnReferenceTypeTests.g.cs @@ -0,0 +1,181 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces +{ + public sealed partial class OnReferenceTypeTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnReferenceType"; + + [Fact] + public Task ClassImplementingInterfaceMethodsNested () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplementingInterfaceMethodsNested2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass4 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass5 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassImplemtingInterfaceMethodsThroughBaseClass6 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassUsedFromConcreteTypeHasInterfaceMethodRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassUsedFromConcreteTypeHasInterfaceMethodRemoved2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ClassUsedFromInterfaceHasInterfaceMethodKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ExplicitInterfaceMethodWhichCreatesInstanceOfParentType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMarkOrderingDoesNotMatter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMarkOrderingDoesNotMatter2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMarkOrderingDoesNotMatter3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeInOtherUsedOnlyByCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeInOtherUsedOnlyByCopiedAssemblyExplicit () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeOnlyUsedHasInterfacesRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceUsedOnlyAsConstraintIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceWithInterfaceFromOtherAssemblyWhenExplicitMethodUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ObjectCastedToSecondInterfaceHasMemberRemovedButInterfaceKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeGetsMarkedThatImplementsAlreadyMarkedInterfaceMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedComInterfaceIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedComInterfaceIsRemovedWhenComFeatureExcluded () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedExplicitInterfaceHasMethodPreservedViaXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedExplicitInterfaceIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedGenericInterfaceIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceHasMethodPreservedViaXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceTypeIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueType.NoKeptCtorTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueType.NoKeptCtorTests.g.cs new file mode 100644 index 000000000..263fad8af --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueType.NoKeptCtorTests.g.cs @@ -0,0 +1,37 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces.OnValueType +{ + public sealed partial class NoKeptCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnValueType.NoKeptCtor"; + + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceCanBeRemovedFromClassWithOnlyStaticMethodUsedWithCctor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceTypeRemovedWhenOnlyUsedByClassWithOnlyStaticMethodMultiple () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueTypeTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueTypeTests.g.cs new file mode 100644 index 000000000..01e332c18 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.Interfaces.OnValueTypeTests.g.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.Interfaces +{ + public sealed partial class OnValueTypeTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces.OnValueType"; + + [Fact] + public Task StructImplementingInterfaceMethodsNested () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StructImplementingInterfaceMethodsNested2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StructUsedFromConcreteTypeHasInterfaceMethodRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StructUsedFromConcreteTypeHasInterfaceMethodRemoved2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StructUsedFromInterfaceHasInterfaceMethodKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StructWithNestedStructImplementingInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedExplicitInterfaceHasMethodPreservedViaXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedExplicitInterfaceIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceHasMethodPreservedViaXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceTypeIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs new file mode 100644 index 000000000..7b604a38a --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.InterfacesTests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance +{ + public sealed partial class InterfacesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.Interfaces"; + + [Fact] + public Task CanDisableUnusedInterfaces () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceOnUninstantiatedTypeRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethods.NotKeptCtorTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethods.NotKeptCtorTests.g.cs new file mode 100644 index 000000000..dc97758ff --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethods.NotKeptCtorTests.g.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance.VirtualMethods +{ + public sealed partial class NotKeptCtorTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.VirtualMethods.NotKeptCtor"; + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs new file mode 100644 index 000000000..6f2e15f67 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Inheritance.VirtualMethodsTests.g.cs @@ -0,0 +1,61 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Inheritance +{ + public sealed partial class VirtualMethodsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Inheritance.VirtualMethods"; + + [Fact] + public Task HarderToDetectUnusedVirtualMethodGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NeverInstantiatedTypeWithBaseInCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithOverrideOfVirtualMethodIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedVirtualMethodRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedOverrideOfVirtualMethodIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedTypeWithOverrideOfVirtualMethodHasOverrideKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task VirtualMethodGetsPreservedIfBaseMethodGetsInvoked () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task VirtualMethodGetsStrippedIfImplementingMethodGetsInvokedDirectly () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LibrariesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LibrariesTests.g.cs new file mode 100644 index 000000000..e58a4cd91 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LibrariesTests.g.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class LibrariesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Libraries"; + + [Fact] + public Task CanLinkPublicApisOfLibrary () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CopyUsedAssemblyWithMainEntryRoot () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CopyUsedAssemblyWithPublicRoots () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DefaultLibraryLinkBehavior () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RootLibrary () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryInternalsWithIVT () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryVisibleAndDescriptor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryVisibleForwarders () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RootLibraryVisibleForwardersWithoutReference () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UserAssemblyActionWorks () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkAttributesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkAttributesTests.g.cs new file mode 100644 index 000000000..170c8b8d3 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkAttributesTests.g.cs @@ -0,0 +1,53 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class LinkAttributesTests : LinkerTestBase + { + + [Fact] + public Task AssemblyLevelLinkerAttributeRemoval () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkAttributesInReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkAttributesInReferencedAssembly_AssemblyLevel () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LinkAttributeErrorCases () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LinkerAttributeRemovalAndPreserveAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideAttributeRemoval () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypedArgumentsErrors () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXml.FeatureExcludeTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXml.FeatureExcludeTests.g.cs new file mode 100644 index 000000000..9411cbbaa --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXml.FeatureExcludeTests.g.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.LinkXml +{ + public sealed partial class FeatureExcludeTests : LinkerTestBase + { + + protected override string TestSuiteName => "LinkXml.FeatureExclude"; + + [Fact] + public Task OnAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnEvent () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnField () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnProperty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OnType () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXmlTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXmlTests.g.cs new file mode 100644 index 000000000..35a0cdea8 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinkXmlTests.g.cs @@ -0,0 +1,229 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class LinkXmlTests : LinkerTestBase + { + + protected override string TestSuiteName => "LinkXml"; + + [Fact] + public Task AssemblyWithPreserveAll () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveAnExportedType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveExcludedFeatureCom () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveExportedTypesUsingRegex () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveTypesUsingRegex () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFromCopyAssemblyIsProcessed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlUnresolvedReferencesAreReported () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LinkXmlErrorCases () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveIndividualMembersOfNonRequiredType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveSecondLevelMethodsOfNonRequiredType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeWithPreserveFieldsHasBackingFieldsOfPropertiesRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedAssemblyWithNoDefinedPreserveHasAllTypesPreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedEventPreservedByLinkXmlIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedFieldPreservedByLinkXmlIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedGenericTypeWithPreserveAllHasAllMembersPreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceTypeOnTypeWithPreserveAllIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedInterfaceTypeOnTypeWithPreserveNothingIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedMethodPreservedByLinkXmlIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedNestedTypePreservedByLinkXmlIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedNonRequiredTypeIsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedPropertyPreservedByLinkXmlIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeDeclarationPreservedByLinkXmlIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeIsPresservedWhenEntireAssemblyIsPreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypePreservedByLinkXmlIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypePreservedByLinkXmlWithCommentIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithNoDefinedPreserveHasAllMembersPreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveAllHasAllMembersPreserved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveFieldsHasMethodsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveMethodsHasFieldsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveNothingAndPreserveMembers () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedTypeWithPreserveNothingHasMembersRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredExportedTypeIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredExportedTypeIsKeptWhenRooted () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredTypeIsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedNonRequiredTypeIsKeptWithSingleMethod () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinqExpressionsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinqExpressionsTests.g.cs new file mode 100644 index 000000000..00167c732 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LinqExpressionsTests.g.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class LinqExpressionsTests : LinkerTestBase + { + + protected override string TestSuiteName => "LinqExpressions"; + + [Fact] + public Task CanDisableOperatorDiscovery () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveCustomOperators () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanPreserveNullableCustomOperators () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanRemoveMethodsNamedLikeCustomOperators () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanRemoveOperatorsWhenNotUsingLinqExpressions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CustomOperatorsWithUnusedArgumentTypes () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LoggingTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LoggingTests.g.cs new file mode 100644 index 000000000..ab1504ace --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/LoggingTests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class LoggingTests : LinkerTestBase + { + + protected override string TestSuiteName => "Logging"; + + [Fact] + public Task CommonLogs () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SourceLines () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MetadataTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MetadataTests.g.cs new file mode 100644 index 000000000..6c87b91fa --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MetadataTests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class MetadataTests : LinkerTestBase + { + + protected override string TestSuiteName => "Metadata"; + + [Fact] + public Task NamesAreKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NamesAreRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/PreserveDependenciesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/PreserveDependenciesTests.g.cs new file mode 100644 index 000000000..1181beffa --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/PreserveDependenciesTests.g.cs @@ -0,0 +1,103 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class PreserveDependenciesTests : LinkerTestBase + { + + protected override string TestSuiteName => "PreserveDependencies"; + + [Fact] + public Task PreserveDependencyDeprecated () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyErrorCases () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyField () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyFromCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyKeptOption () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMemberSignatureWildcard () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssemblyChained () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssemblyChainedReference () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyMethodInNonReferencedAssemblyWithEmbeddedXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyOnUnusedMethodInNonReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithCopyUsedAction () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.DependenciesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.DependenciesTests.g.cs new file mode 100644 index 000000000..77d6e43cf --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/References.DependenciesTests.g.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.References +{ + public sealed partial class DependenciesTests : LinkerTestBase + { + + protected override string TestSuiteName => "References.Dependencies"; + + [Fact] + public Task ReferenceWithEntryPoint_Lib () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs new file mode 100644 index 000000000..5c91dd7ca --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReferencesTests.g.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class ReferencesTests : LinkerTestBase + { + + protected override string TestSuiteName => "References"; + + [Fact] + public Task AssemblyOnlyUsedByUsingWithCsc () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyOnlyUsedByUsingWithCscWithKeepFacades () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyReferenceIsRemovedWhenUnused () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CopyAreKeptFully () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CopyUsedAreKeptFully () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CopyWithLinkedWillHaveAttributeDepsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CopyWithLinkedWillHaveMethodDepsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ReferencesAreRemovedWhenAllUsagesAreRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ReferenceWithEntryPoint () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UserAssembliesAreLinkedByDefault () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReflectionTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReflectionTests.g.cs new file mode 100644 index 000000000..486718f26 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ReflectionTests.g.cs @@ -0,0 +1,185 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class ReflectionTests : LinkerTestBase + { + + [Fact] + public Task AssemblyImportedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyImportedViaReflectionWithDerivedType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AssemblyImportedViaReflectionWithReference () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task AsType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CoreLibMessages () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EventUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ExpressionCallStringAndLocals () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ExpressionFieldString () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ExpressionPropertyString () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task FieldUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodUsedViaReflectionAndLocal () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodUsedViaReflectionWithDefaultBindingFlags () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NestedTypeUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ObjectGetTypeLibraryMode () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ParametersUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task PropertyUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RunClassConstructorUsedViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RuntimeReflectionExtensionsCalls () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeBaseTypeUseViaReflection () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeDelegator () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeHierarchyLibraryModeSuppressions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeUsedViaReflectionAssemblyDoesntExist () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeUsedViaReflectionInDifferentAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeUsedViaReflectionLdstrIncomplete () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeUsedViaReflectionLdstrValidButChanged () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeUsedViaReflectionTypeNameIsSymbol () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnderlyingSystemType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedViaReflectionIntegrationTest () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ResourcesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ResourcesTests.g.cs new file mode 100644 index 000000000..3df794cd5 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/ResourcesTests.g.cs @@ -0,0 +1,79 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class ResourcesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Resources"; + + [Fact] + public Task EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileIsNotProcessedIfNameDoesNotMatchAnAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileIsNotProcessedWithIgnoreDescriptors () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileIsNotProcessedWithIgnoreDescriptorsAndRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileIsProcessed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileIsProcessedAndKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileIsProcessedIfNameMatchesAnAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedLinkXmlFileWithTypePreserve () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NonLinkerEmbeddedResourceHasNoImpact () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SealerTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SealerTests.g.cs new file mode 100644 index 000000000..8d3835b9c --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SealerTests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class SealerTests : LinkerTestBase + { + + protected override string TestSuiteName => "Sealer"; + + [Fact] + public Task MethodsDevirtualization () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypesCanBeSealed () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SerializationTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SerializationTests.g.cs new file mode 100644 index 000000000..2453a3936 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SerializationTests.g.cs @@ -0,0 +1,55 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class SerializationTests : LinkerTestBase + { + + protected override string TestSuiteName => "Serialization"; + + [Fact] + public Task CanDisableSerializationDiscovery () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DataContractJsonSerialization () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DataContractSerialization () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DataContractSerializationUnused () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SerializationTypeRecursion () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task XmlSerialization () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task XmlSerializationUnused () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Statics.DisableBeforeFieldInitTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Statics.DisableBeforeFieldInitTests.g.cs new file mode 100644 index 000000000..02cf25b21 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Statics.DisableBeforeFieldInitTests.g.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Statics +{ + public sealed partial class DisableBeforeFieldInitTests : LinkerTestBase + { + + protected override string TestSuiteName => "Statics.DisableBeforeFieldInit"; + + [Fact] + public Task UnusedStaticFieldInitializer () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/StaticsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/StaticsTests.g.cs new file mode 100644 index 000000000..1fafded79 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/StaticsTests.g.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class StaticsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Statics"; + + [Fact] + public Task ExplicitStaticCtor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MixedStaticFieldInitializerAndCtor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StaticFieldInitializer () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedStaticConstructorGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedStaticFieldInitializer () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UnusedStaticMethodGetsRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SubstitutionsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SubstitutionsTests.g.cs new file mode 100644 index 000000000..91298ba52 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/SubstitutionsTests.g.cs @@ -0,0 +1,103 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class SubstitutionsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Substitutions"; + + [Fact] + public Task EmbeddedFieldSubstitutionsInReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedMethodSubstitutionsInReferencedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutionsKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutionsNotProcessedWithIgnoreSubstitutions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EmbeddedSubstitutionsNotProcessedWithIgnoreSubstitutionsAndRemoved () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InitField () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InitFieldExistingCctor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task RemoveBody () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ResourceSubstitutions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StubBody () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StubBodyInvalidSyntax () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StubBodyUnsafe () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task StubBodyWithValue () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SubstitutionsErrorCases () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TestFrameworkTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TestFrameworkTests.g.cs new file mode 100644 index 000000000..76279e066 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TestFrameworkTests.g.cs @@ -0,0 +1,79 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class TestFrameworkTests : LinkerTestBase + { + + protected override string TestSuiteName => "TestFramework"; + + [Fact] + public Task CanCheckInitializersByIndex () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesUsingTypes () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesWithResources () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesWithResourcesWithCsc () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanCompileReferencesWithResourcesWithMcs () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSandboxDependenciesUsingType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanVerifyInterfacesOnTypesInAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task VerifyAttributesInAssemblyWorks () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task VerifyAttributesInAssemblyWorksWithStrings () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task VerifyExpectModifiedAttributesWork () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task VerifyResourceInAssemblyAttributesBehavior () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.DependencyRecorderTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.DependencyRecorderTests.g.cs new file mode 100644 index 000000000..ede924e3f --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.DependencyRecorderTests.g.cs @@ -0,0 +1,19 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Tracing +{ + public sealed partial class DependencyRecorderTests : LinkerTestBase + { + + protected override string TestSuiteName => "Tracing.DependencyRecorder"; + + [Fact] + public Task BasicDependencies () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.IndividualTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.IndividualTests.g.cs new file mode 100644 index 000000000..e9d7c1695 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Tracing.IndividualTests.g.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Tracing +{ + public sealed partial class IndividualTests : LinkerTestBase + { + + protected override string TestSuiteName => "Tracing.Individual"; + + [Fact] + public Task CanDumpDependenciesToUncompressedXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanEnableDependenciesDump () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanEnableReducedTracing () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TypeForwardingTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TypeForwardingTests.g.cs new file mode 100644 index 000000000..b1400dde9 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/TypeForwardingTests.g.cs @@ -0,0 +1,85 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class TypeForwardingTests : LinkerTestBase + { + + protected override string TestSuiteName => "TypeForwarding"; + + [Fact] + public Task MissingTargetReference () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SecurityAttributeScope () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeForwardedIsUpdatedForMissingType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TypeForwarderOnlyAssembliesKept () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByPreserveDependency () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedCustomAttribute () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedField () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedNestedType () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedProperty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UsedForwarderInCopyAssemblyKeptByUsedTypeAsGenericArg () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBlockTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBlockTests.g.cs new file mode 100644 index 000000000..40110bcea --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBlockTests.g.cs @@ -0,0 +1,95 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class UnreachableBlockTests : LinkerTestBase + { + + [Fact] + public Task BodiesWithSubstitutions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ComplexConditions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DeadVariables () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task EndScopeOnMethoEnd () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InstanceMethodSubstitutions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MethodWithParametersSubstitutions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MultiStageRemoval () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ReplacedReturns () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleConditionalProperty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SizeOfInConditions () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TryCatchBlocks () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TryFinallyBlocks () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task UninitializedLocals () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithDynamicAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBodyTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBodyTests.g.cs new file mode 100644 index 000000000..73fd0baa6 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/UnreachableBodyTests.g.cs @@ -0,0 +1,199 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class UnreachableBodyTests : LinkerTestBase + { + + protected override string TestSuiteName => "UnreachableBody"; + + [Fact] + public Task BodyWithManyVariables () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task BodyWithManyVariablesWithSymbols () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanDisableLazyBodyMarking () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DoesNotApplyToCopiedAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task DoesNotApplyToCopiedAssembly2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task ExplicitInstructionCheck () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InterfaceMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LinkedOtherIncludedLibrary () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task LinkedOtherIncludedLibraryNoInstanceCtor () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task MixOfMethods () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingEmpty () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnDouble () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnFalse () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnFloat () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnInt () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnLong () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnNull () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NotWorthConvertingReturnTrue () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodCalledFromLocal3 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractAndInterfaceMethodWhenInterfaceRemoved2 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractIsStubbed () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAbstractIsStubbedWithUnusedInterface () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task OverrideOfAVirtual () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleGetter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleMethod () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SimpleSetter () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithDynamicDependency () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithLinkXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task WorksWithPreserveDependency () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.DependenciesTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.DependenciesTests.g.cs new file mode 100644 index 000000000..43a1e709c --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.DependenciesTests.g.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Warnings +{ + public sealed partial class DependenciesTests : LinkerTestBase + { + + protected override string TestSuiteName => "Warnings.Dependencies"; + + [Fact] + public Task TriggerWarnings_Lib () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task TriggerWarnings_TrimmableLib () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.IndividualTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.IndividualTests.g.cs new file mode 100644 index 000000000..8bcd66357 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.IndividualTests.g.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Warnings +{ + public sealed partial class IndividualTests : LinkerTestBase + { + + protected override string TestSuiteName => "Warnings.Individual"; + + [Fact] + public Task CanGenerateWarningSuppressionFileCSharp () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanGenerateWarningSuppressionFileXml () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task WarningsAreSorted () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.WarningSuppressionTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.WarningSuppressionTests.g.cs new file mode 100644 index 000000000..10abaf364 --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/Warnings.WarningSuppressionTests.g.cs @@ -0,0 +1,53 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests.Warnings +{ + public sealed partial class WarningSuppressionTests : LinkerTestBase + { + + [Fact] + public Task AddSuppressionsBeforeAttributeRemoval () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInCopyAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInMembersAndTypes () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsInModule () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsUsingTargetViaXmlMono () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task SuppressWarningsUsingTargetViaXmlNetCore () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/WarningsTests.g.cs b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/WarningsTests.g.cs new file mode 100644 index 000000000..d466c9f9c --- /dev/null +++ b/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/WarningsTests.g.cs @@ -0,0 +1,109 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class WarningsTests : LinkerTestBase + { + + protected override string TestSuiteName => "Warnings"; + + [Fact] + public Task CanDisableWarnAsError () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanDisableWarnings () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanNotSingleWarnPerAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanNotWarnAsErrorForDisabledVersion () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSetWarningVersion0 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSetWarningVersion5 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSetWarningVersion9999 () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarn () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnPerAssembly () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnWithIndividualWarnAsError () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnWithNoWarn () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanSingleWarnWithWarnAsError () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task CanWarnAsError () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task InvalidWarningVersion () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task NoWarnRegardlessOfWarnAsError () + { + return RunTest (allowMissingWarnings: true); + } + + [Fact] + public Task WarningsFromTrimmableAssembliesCanSurviveSingleWarn () + { + return RunTest (allowMissingWarnings: true); + } + + } +}
\ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RecognizedReflectionAccessPatternAttribute.cs b/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RecognizedReflectionAccessPatternAttribute.cs deleted file mode 100644 index 4de5de43c..000000000 --- a/test/Mono.Linker.Tests.Cases.Expectations/Assertions/RecognizedReflectionAccessPatternAttribute.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Mono.Linker.Tests.Cases.Expectations.Assertions -{ - [AttributeUsage ( - AttributeTargets.Method | - AttributeTargets.Constructor | - AttributeTargets.Class | - AttributeTargets.Field | - AttributeTargets.Property, - AllowMultiple = true, - Inherited = false)] - public class RecognizedReflectionAccessPatternAttribute : BaseExpectedLinkedBehaviorAttribute - { - // The default .ctor has a special meaning - don't validate any specifically recognized reflection access patterns - // but it will trigger the overall validation that all unrecognized patterns are expected. - public RecognizedReflectionAccessPatternAttribute () - { - } - - public RecognizedReflectionAccessPatternAttribute (Type reflectionMethodType, string reflectionMethodName, Type[] reflectionMethodParameters, - Type accessedItemType, string accessedItemName, Type[] accessedItemParameters) - { - if (reflectionMethodType == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (reflectionMethodType)); - if (reflectionMethodName == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (reflectionMethodName)); - if (reflectionMethodParameters == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (reflectionMethodParameters)); - - if (accessedItemType == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (accessedItemType)); - if (accessedItemName == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (accessedItemName)); - } - - public RecognizedReflectionAccessPatternAttribute (Type reflectionMethodType, string reflectionMethodName, Type[] reflectionMethodParameters, - Type accessedItemType, string accessedItemName, string[] accessedItemParameters = null) - { - if (reflectionMethodType == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (reflectionMethodType)); - if (reflectionMethodName == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (reflectionMethodName)); - if (reflectionMethodParameters == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (reflectionMethodParameters)); - - if (accessedItemType == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (accessedItemType)); - if (accessedItemName == null) - throw new ArgumentException ("Value cannot be null or empty.", nameof (accessedItemName)); - } - } -} diff --git a/test/Mono.Linker.Tests.Cases.Expectations/Assertions/UnrecognizedReflectionAccessPatternAttribute.cs b/test/Mono.Linker.Tests.Cases.Expectations/Assertions/UnrecognizedReflectionAccessPatternAttribute.cs deleted file mode 100644 index a59021e17..000000000 --- a/test/Mono.Linker.Tests.Cases.Expectations/Assertions/UnrecognizedReflectionAccessPatternAttribute.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace Mono.Linker.Tests.Cases.Expectations.Assertions -{ - [AttributeUsage ( - AttributeTargets.Method | - AttributeTargets.Constructor | - AttributeTargets.Class | - AttributeTargets.Field | - AttributeTargets.Property, - AllowMultiple = true, - Inherited = false)] - public class UnrecognizedReflectionAccessPatternAttribute : BaseExpectedLinkedBehaviorAttribute - { - public UnrecognizedReflectionAccessPatternAttribute ( - Type reflectionMethodType, - string reflectionMethodName, - Type[] reflectionMethodParameters, - string[] message = null, - string messageCode = null, - Type returnType = null, - string genericParameter = null) - { - } - - public UnrecognizedReflectionAccessPatternAttribute ( - Type reflectionMethodType, - string reflectionMethodName, - string[] reflectionMethodParameters = null, - string[] message = null, - string messageCode = null, - Type returnType = null, - string genericParameter = null) - { - } - } -} diff --git a/test/Mono.Linker.Tests.Cases.Expectations/Assertions/VerifyAllReflectionAccessPatternsAreHandledAttribute.cs b/test/Mono.Linker.Tests.Cases.Expectations/Assertions/VerifyAllReflectionAccessPatternsAreHandledAttribute.cs deleted file mode 100644 index ae7debb02..000000000 --- a/test/Mono.Linker.Tests.Cases.Expectations/Assertions/VerifyAllReflectionAccessPatternsAreHandledAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Mono.Linker.Tests.Cases.Expectations.Assertions -{ - [AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = false)] - public class VerifyAllReflectionAccessPatternsAreValidatedAttribute : BaseExpectedLinkedBehaviorAttribute - { - public VerifyAllReflectionAccessPatternsAreValidatedAttribute () - { - } - } -} diff --git a/test/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowStringExtensions.cs b/test/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowStringExtensions.cs new file mode 100644 index 000000000..1ff589928 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowStringExtensions.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; + +namespace Mono.Linker.Tests.Cases.Expectations.Helpers +{ + public static class DataFlowStringExtensions + { + public static void RequiresAll ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] this string str) { } + + public static void RequiresPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] this string str) { } + + public static void RequiresPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] this string str) { } + + public static void RequiresPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] this string str) { } + + public static void RequiresPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] this string str) { } + + public static void RequiresPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] this string str) { } + + public static void RequiresPublicParameterlessConstructor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] this string str) { } + + public static void RequiresPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] this string str) { } + + public static void RequiresNonPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] this string str) { } + + public static void RequiresNonPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] this string str) { } + + public static void RequiresNonPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] this string str) { } + + public static void RequiresNonPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] this string str) { } + + public static void RequiresNonPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] this string str) { } + + public static void RequiresNonPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] this string str) { } + + public static void RequiresInterfaces ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] this string str) { } + + public static void RequiresNone (this string str) { } + } +} diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs b/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs index 68b6e5a0f..1bb561160 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/AnnotatedMembersAccessedViaReflection.cs @@ -39,7 +39,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public static Type _annotatedField; - [ExpectedWarning ("IL2110", nameof (_annotatedField))] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = ProducedBy.Trimmer)] static void Reflection () { typeof (AnnotatedField).GetField ("_annotatedField").SetValue (null, typeof (TestType)); @@ -51,13 +52,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedField).GetField ("_annotatedField").SetValue (null, typeof (TestType)); } - [ExpectedWarning ("IL2110", nameof (_annotatedField))] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = ProducedBy.Trimmer)] static void ReflectionReadOnly () { typeof (AnnotatedField).GetField ("_annotatedField").GetValue (null); } - [ExpectedWarning ("IL2110", nameof (_annotatedField))] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = ProducedBy.Trimmer)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicFields, typeof (AnnotatedField))] static void DynamicDependency () { @@ -69,7 +72,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [ExpectedWarning ("IL2110", nameof (_annotatedField))] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 + [ExpectedWarning ("IL2110", nameof (_annotatedField), ProducedBy = ProducedBy.Trimmer)] [DynamicDependency (nameof (_annotatedField), typeof (AnnotatedField))] static void DynamicDependencyByName () { @@ -156,7 +160,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } } - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = ProducedBy.Trimmer)] static void Reflection () { typeof (AnnotatedMethodParameters).GetMethod (nameof (MethodWithSingleAnnotatedParameter)).Invoke (null, null); @@ -174,7 +179,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = ProducedBy.Trimmer)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodParameters))] static void DynamicDependency () { @@ -186,7 +192,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = ProducedBy.Trimmer)] [DynamicDependency (nameof (MethodWithSingleAnnotatedParameter), typeof (AnnotatedMethodParameters))] static void DynamicDependencyByName () { @@ -204,7 +211,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedMethodParameters).RequiresPublicMethods (); } - [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter))] + // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 + [ExpectedWarning ("IL2111", nameof (MethodWithSingleAnnotatedParameter), ProducedBy = ProducedBy.Trimmer)] static void Ldftn () { var _ = new Action<Type> (AnnotatedMethodParameters.MethodWithSingleAnnotatedParameter); @@ -215,7 +223,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow public void AnnotatedMethod ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type); } - [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod))] + // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 + [ExpectedWarning ("IL2111", nameof (IWithAnnotatedMethod.AnnotatedMethod), ProducedBy = ProducedBy.Trimmer)] static void Ldvirtftn () { IWithAnnotatedMethod instance = null; @@ -285,7 +294,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedMethodReturnValue).GetMethod (nameof (InstanceMethodWithAnnotatedReturnValue)).Invoke (null, null); } - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = ProducedBy.Trimmer)] static void ReflectionOnVirtual () { typeof (AnnotatedMethodReturnValue).GetMethod (nameof (VirtualMethodWithAnnotatedReturnValue)).Invoke (null, null); @@ -297,7 +307,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedMethodReturnValue).GetMethod (nameof (VirtualMethodWithAnnotatedReturnValue)).Invoke (null, null); } - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = ProducedBy.Trimmer)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicMethods, typeof (AnnotatedMethodReturnValue))] static void DynamicDependency () { @@ -319,7 +330,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = ProducedBy.Trimmer)] [DynamicDependency (nameof (VirtualMethodWithAnnotatedReturnValue), typeof (AnnotatedMethodReturnValue))] static void DynamicDependencyByNameOnVirtual () { @@ -347,7 +359,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow var _ = new Func<Type> ((new AnnotatedMethodReturnValue ()).InstanceMethodWithAnnotatedReturnValue); } - [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue))] + // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 + [ExpectedWarning ("IL2111", nameof (VirtualMethodWithAnnotatedReturnValue), ProducedBy = ProducedBy.Trimmer)] static void LdftnOnVirtual () { var _ = new Func<Type> ((new AnnotatedMethodReturnValue ()).VirtualMethodWithAnnotatedReturnValue); @@ -376,13 +389,31 @@ namespace Mono.Linker.Tests.Cases.DataFlow class AnnotatedProperty { [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] - public static Type PropertyWithAnnotation { get; set; } + public static Type Property1WithAnnotation { get; set; } + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] + public static Type Property2WithAnnotationGetterOnly { get => null; } [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] - public static Type PropertyWithAnnotationGetterOnly { get => null; } + public virtual Type VirtualProperty3WithAnnotationGetterOnly { get => null; } [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] - public virtual Type VirtualPropertyWithAnnotationGetterOnly { get => null; } + public virtual Type VirtualProperty4WithAnnotation { get => null; set { value.ToString (); } } + + public static Type Property5WithAnnotationOnMembers { + [ExpectedWarning ("IL2078", nameof (Property5WithAnnotationOnMembers) + ".get", ProducedBy = ProducedBy.Trimmer)] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] + get; + [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] + set; + } + + public virtual Type VirtualProperty6WithAnnotationOnMembers { + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] + get => null; + [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] + set { value.ToString (); } + } class AttributeWithPropertyWithAnnotation : Attribute { @@ -392,44 +423,48 @@ namespace Mono.Linker.Tests.Cases.DataFlow public Type PropertyWithAnnotation { get; set; } } - [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation))] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = ProducedBy.Trimmer)] static void ReflectionOnPropertyItself () { - typeof (AnnotatedProperty).GetProperty (nameof (PropertyWithAnnotation)); + typeof (AnnotatedProperty).GetProperty (nameof (Property1WithAnnotation)); } [RequiresUnreferencedCode ("test")] static void ReflectionOnPropertyItselfSuppressedByRUC () { - typeof (AnnotatedProperty).GetProperty (nameof (PropertyWithAnnotation)); + typeof (AnnotatedProperty).GetProperty (nameof (Property1WithAnnotation)); } static void ReflectionOnPropertyWithGetterOnly () { - typeof (AnnotatedProperty).GetProperty (nameof (PropertyWithAnnotationGetterOnly)); + typeof (AnnotatedProperty).GetProperty (nameof (Property2WithAnnotationGetterOnly)); } - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly))] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly), ProducedBy = ProducedBy.Trimmer)] static void ReflectionOnPropertyWithGetterOnlyOnVirtual () { - typeof (AnnotatedProperty).GetProperty (nameof (VirtualPropertyWithAnnotationGetterOnly)); + typeof (AnnotatedProperty).GetProperty (nameof (VirtualProperty3WithAnnotationGetterOnly)); } static void ReflectionOnGetter () { - typeof (AnnotatedProperty).GetMethod ("get_" + nameof (PropertyWithAnnotation)); + typeof (AnnotatedProperty).GetMethod ("get_" + nameof (Property1WithAnnotation)); } - [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = ProducedBy.Trimmer)] static void ReflectionOnSetter () { - typeof (AnnotatedProperty).GetMethod ("set_" + nameof (PropertyWithAnnotation)); + typeof (AnnotatedProperty).GetMethod ("set_" + nameof (Property1WithAnnotation)); } - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", ProducedBy = ProducedBy.Trimmer)] static void ReflectionOnVirtualGetter () { - typeof (AnnotatedProperty).GetMethod ("get_" + nameof (VirtualPropertyWithAnnotationGetterOnly)); + typeof (AnnotatedProperty).GetMethod ("get_" + nameof (VirtualProperty3WithAnnotationGetterOnly)); } // Should not warn - there's nothing wrong with this @@ -438,8 +473,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")] - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] + // DynamicDependency is not supported yet in the analyzer https://github.com/dotnet/linker/issues/2560 + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set", ProducedBy = ProducedBy.Trimmer)] [DynamicDependency (DynamicallyAccessedMemberTypes.PublicProperties, typeof (AnnotatedProperty))] static void DynamicDependency () { @@ -451,8 +492,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [ExpectedWarning ("IL2111", nameof (PropertyWithAnnotation) + ".set")] - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (Property1WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set")] + static void DynamicallyAccessedMembers () { typeof (AnnotatedProperty).RequiresPublicProperties (); @@ -468,12 +515,22 @@ namespace Mono.Linker.Tests.Cases.DataFlow [ExpectedWarning ("IL2026", nameof (DynamicallyAccessedMembersSuppressedByRUC), "test")] [ExpectedWarning ("IL2026", nameof (ReflectionOnPropertyItselfSuppressedByRUC), "test")] // Duplicated warnings for linker and analyzer see bug https://github.com/dotnet/linker/issues/2462 - [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.PropertyWithAnnotation) + ".set")] - [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.PropertyWithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.Property1WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.Property1WithAnnotation) + ".set")] [ExpectedWarning ("IL2111", nameof (AttributeWithPropertyWithAnnotation.PropertyWithAnnotation) + ".set")] [ExpectedWarning ("IL2111", nameof (AttributeWithPropertyWithAnnotation.PropertyWithAnnotation) + ".set")] - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set")] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set")] [UnconditionalSuppressMessage ("Test", "IL2110", Justification = "Suppress warning about backing field of PropertyWithAnnotation")] static void DynamicallyAccessedMembersAll1 () { @@ -484,12 +541,22 @@ namespace Mono.Linker.Tests.Cases.DataFlow [ExpectedWarning ("IL2026", nameof (DynamicallyAccessedMembersSuppressedByRUC), "test")] [ExpectedWarning ("IL2026", nameof (ReflectionOnPropertyItselfSuppressedByRUC), "test")] // Duplicated warnings for linker and analyzer see bug https://github.com/dotnet/linker/issues/2462 - [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.PropertyWithAnnotation) + ".set")] - [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.PropertyWithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.Property1WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (AnnotatedProperty.Property1WithAnnotation) + ".set")] [ExpectedWarning ("IL2111", nameof (AttributeWithPropertyWithAnnotation.PropertyWithAnnotation) + ".set")] [ExpectedWarning ("IL2111", nameof (AttributeWithPropertyWithAnnotation.PropertyWithAnnotation) + ".set")] - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] - [ExpectedWarning ("IL2111", nameof (VirtualPropertyWithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty3WithAnnotationGetterOnly) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty4WithAnnotation) + ".set")] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set")] + [ExpectedWarning ("IL2111", nameof (Property5WithAnnotationOnMembers) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".get")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set")] + [ExpectedWarning ("IL2111", nameof (VirtualProperty6WithAnnotationOnMembers) + ".set")] [UnconditionalSuppressMessage ("Test", "IL2110", Justification = "Suppress warning about backing field of PropertyWithAnnotation")] static void DynamicallyAccessedMembersAll2 () { @@ -541,8 +608,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (AnnotatedGenerics).RequiresPublicMethods (); } + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 // This should produce IL2071 https://github.com/dotnet/linker/issues/2144 - [ExpectedWarning ("IL2070", "MakeGenericMethod")] + [ExpectedWarning ("IL2070", "MakeGenericMethod", ProducedBy = ProducedBy.Trimmer)] static void InstantiateGeneric (Type type = null) { // This should warn due to MakeGenericMethod - in this case the generic parameter is unannotated type @@ -579,13 +647,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { } - [ExpectedWarning ("IL2111", nameof (GenericWithAnnotatedMethod<TestType>.AnnotatedMethod))] + // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 + [ExpectedWarning ("IL2111", nameof (GenericWithAnnotatedMethod<TestType>.AnnotatedMethod), ProducedBy = ProducedBy.Trimmer)] public static void GenericTypeWithStaticMethodViaLdftn () { var _ = new Action<Type> (GenericWithAnnotatedMethod<TestType>.AnnotatedMethod); } - [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation))] + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 + [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation), ProducedBy = ProducedBy.Trimmer)] public static void GenericMethodWithAnnotationReflection () { typeof (AnnotationOnGenerics).GetMethod (nameof (GenericMethodWithAnnotation)); @@ -597,7 +667,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow GenericMethodWithAnnotation<TestType> (typeof (TestType)); } - [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation))] + // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 + [ExpectedWarning ("IL2111", nameof (GenericMethodWithAnnotation), ProducedBy = ProducedBy.Trimmer)] public static void GenericMethodWithAnnotationViaLdftn () { var _ = new Action<Type> (GenericMethodWithAnnotation<TestType>); @@ -643,11 +714,13 @@ namespace Mono.Linker.Tests.Cases.DataFlow public Type _typeField; } - [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField))] + // Analyzer doesnt take into account interop attributes https://github.com/dotnet/linker/issues/2562 + [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), ProducedBy = ProducedBy.Trimmer)] [DllImport ("nonexistent")] static extern ValueWithAnnotatedField GetValueWithAnnotatedField (); - [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField))] + // Analyzer doesnt take into account interop attributes https://github.com/dotnet/linker/issues/2562 + [ExpectedWarning ("IL2110", nameof (ValueWithAnnotatedField._typeField), ProducedBy = ProducedBy.Trimmer)] [DllImport ("nonexistent")] static extern void AcceptValueWithAnnotatedField (ValueWithAnnotatedField value); @@ -667,7 +740,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow } } - [ExpectedWarning ("IL2111", nameof (PropertyWithLdToken))] + // Action delegate is not handled correctly https://github.com/dotnet/linker/issues/2561 + [ExpectedWarning ("IL2111", nameof (PropertyWithLdToken), ProducedBy = ProducedBy.Trimmer)] [ExpectedWarning ("IL2111", nameof (PropertyWithLdToken), ProducedBy = ProducedBy.Trimmer)] public static void Test () { diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs b/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs index 5863cf4a4..5770bdfa4 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/ApplyTypeAnnotations.cs @@ -9,6 +9,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { + [ExpectedNoWarnings] public class ApplyTypeAnnotations { public static void Main () @@ -50,6 +51,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow } [Kept] + // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374 + [ExpectedWarning ("IL2026", "System.Type.GetType(String)", + ProducedBy = ProducedBy.Analyzer)] + // Analyzer doesn't track known types: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2072", "'type'", nameof (ApplyTypeAnnotations) + "." + nameof (RequireCombination) + "(Type)", "System.Type.GetType(String)", + ProducedBy = ProducedBy.Analyzer)] static void TestFromTypeGetTypeOverConstant () { RequireCombination (Type.GetType ("Mono.Linker.Tests.Cases.DataFlow.ApplyTypeAnnotations+FromTypeGetTypeOverConstantTestType")); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs index 8761da610..4a478e2a6 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs @@ -7,8 +7,9 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] + [ExpectedNoWarnings] class AssemblyQualifiedNameDataflow { static void Main () @@ -19,8 +20,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestUnqualifiedTypeNameWarns (); } - [UnrecognizedReflectionAccessPattern (typeof (AssemblyQualifiedNameDataflow), nameof (RequirePublicConstructors), new Type[] { typeof (string) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (AssemblyQualifiedNameDataflow), nameof (RequireNonPublicConstructors), new Type[] { typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (RequirePublicConstructors))] + [ExpectedWarning ("IL2072", nameof (RequireNonPublicConstructors))] static void TestPublicParameterlessConstructor () { string type = GetTypeWithPublicParameterlessConstructor ().AssemblyQualifiedName; @@ -30,7 +31,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow RequireNothing (type); } - [UnrecognizedReflectionAccessPattern (typeof (AssemblyQualifiedNameDataflow), nameof (RequireNonPublicConstructors), new Type[] { typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (RequireNonPublicConstructors))] static void TestPublicConstructors () { string type = GetTypeWithPublicConstructors ().AssemblyQualifiedName; @@ -40,8 +41,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow RequireNothing (type); } - [UnrecognizedReflectionAccessPattern (typeof (AssemblyQualifiedNameDataflow), nameof (RequirePublicParameterlessConstructor), new Type[] { typeof (string) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (AssemblyQualifiedNameDataflow), nameof (RequirePublicConstructors), new Type[] { typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (RequirePublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", nameof (RequirePublicConstructors))] static void TestConstructors () { string type = GetTypeWithNonPublicConstructors ().AssemblyQualifiedName; diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs index 3b5aff228..76e31e833 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/AttributeConstructorDataflow.cs @@ -11,6 +11,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { [Kept] + [ExpectedNoWarnings] class AttributeConstructorDataflow { [KeptAttributeAttribute (typeof (KeepsPublicConstructorAttribute))] @@ -73,7 +74,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow class AllOnSelf { [Kept] - [RecognizedReflectionAccessPattern] public static void Test () { var t = typeof (KeepAllOnSelf); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs index 7da1ed05b..75b619a21 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/AttributeFieldDataflow.cs @@ -11,6 +11,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { [Kept] + [ExpectedNoWarnings] class AttributeFieldDataflow { [KeptAttributeAttribute (typeof (KeepsPublicConstructorsAttribute))] diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs index 8c4dac3b2..4f1e84123 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/AttributePropertyDataflow.cs @@ -11,6 +11,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { [Kept] + [ExpectedNoWarnings] class AttributePropertyDataflow { [KeptAttributeAttribute (typeof (KeepsPublicConstructorsAttribute))] diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs index 6cb0409cf..6b088291e 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/ByRefDataflow.cs @@ -12,6 +12,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow { [SetupCompileArgument ("/langversion:7.3")] [Kept] + [ExpectedNoWarnings] class ByRefDataflow { public static void Main () @@ -40,14 +41,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow static Type s_typeWithPublicParameterlessConstructor; [Kept] - [UnrecognizedReflectionAccessPattern (typeof (ByRefDataflow), nameof (MethodWithRefParameter), new string[] { "Type&" }, messageCode: "IL2077")] + // Trimmer and analyzer use different formats for ref parameters: https://github.com/dotnet/linker/issues/2406 + [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2077", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", ProducedBy = ProducedBy.Analyzer)] public static void PassRefToField () { MethodWithRefParameter (ref s_typeWithPublicParameterlessConstructor); } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (ByRefDataflow), nameof (MethodWithRefParameter), new string[] { "Type&" }, messageCode: "IL2067")] + // Trimmer and analyzer use different formats for ref parameters: https://github.com/dotnet/linker/issues/2406 + [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(Type&)", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2067", nameof (ByRefDataflow) + "." + nameof (MethodWithRefParameter) + "(ref Type)", ProducedBy = ProducedBy.Analyzer)] public static void PassRefToParameter (Type parameter) { MethodWithRefParameter (ref parameter); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs b/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs index 7bcfbc70c..858d40088 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/ComplexTypeHandling.cs @@ -99,6 +99,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow } [Kept] + // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374 + [ExpectedWarning ("IL2072", "'type'", nameof (ComplexTypeHandling) + "." + nameof (RequirePublicMethods) + "(Type)", "System.Object.GetType()", + ProducedBy = ProducedBy.Analyzer)] static void TestArrayGetTypeFromMethodParamHelper (ArrayGetTypeFromMethodParamElement[] p) { RequirePublicMethods (p.GetType ()); @@ -121,6 +124,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow static ArrayGetTypeFromFieldElement[] _arrayGetTypeFromField; [Kept] + // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374 + [ExpectedWarning ("IL2072", "'type'", nameof (ComplexTypeHandling) + "." + nameof (RequirePublicMethods) + "(Type)", "System.Object.GetType()", + ProducedBy = ProducedBy.Analyzer)] static void TestArrayGetTypeFromField () { RequirePublicMethods (_arrayGetTypeFromField.GetType ()); @@ -134,6 +140,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow } [Kept] + // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374 + [ExpectedWarning ("IL2026", "System.Type.GetType(String)", + ProducedBy = ProducedBy.Analyzer)] + // Analyzer doesn't track known types: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2072", "'type'", nameof (ComplexTypeHandling) + "." + nameof (RequirePublicMethods) + "(Type)", "System.Type.GetType(String)", + ProducedBy = ProducedBy.Analyzer)] static void TestArrayTypeGetType () { RequirePublicMethods (Type.GetType ("Mono.Linker.Tests.Cases.DataFlow.ComplexTypeHandling+ArrayTypeGetTypeElement[]")); @@ -148,6 +160,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow } [Kept] + // Analyzer doesn't support intrinsics: https://github.com/dotnet/linker/issues/2374 + [ExpectedWarning ("IL2026", "Activator.CreateInstance(String, String)", + ProducedBy = ProducedBy.Analyzer)] static void TestArrayCreateInstanceByName () { Activator.CreateInstance ("test", "Mono.Linker.Tests.Cases.DataFlow.ComplexTypeHandling+ArrayCreateInstanceByNameElement[]"); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/DynamicDependencyDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/DynamicDependencyDataflow.cs index 1fe9a13be..8237bc4db 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/DynamicDependencyDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/DynamicDependencyDataflow.cs @@ -5,6 +5,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { + [ExpectedNoWarnings] public class DynamicDependencyDataflow { public static void Main () @@ -17,16 +18,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static Type TypeWithPublicMethods; + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), "GetField", new Type[] { typeof (string) }, messageCode: "IL2080")] + [ExpectedWarning ("IL2080", nameof (Type.GetField), ProducedBy = ProducedBy.Trimmer)] [DynamicDependency ("DynamicDependencyTo")] static void DynamicDependencyFrom () { _ = TypeWithPublicMethods.GetField ("f"); } + // Intrinsic is disabled https://github.com/dotnet/linker/issues/2559 [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), "GetProperty", new Type[] { typeof (string) }, messageCode: "IL2080")] + [ExpectedWarning ("IL2080", nameof (Type.GetProperty), ProducedBy = ProducedBy.Trimmer)] static void DynamicDependencyTo () { _ = TypeWithPublicMethods.GetProperty ("p"); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs index 34e524215..2e89e0c7e 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs @@ -8,8 +8,9 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] + [ExpectedNoWarnings] class EmptyArrayIntrinsicsDataFlow { static void Main () @@ -20,27 +21,27 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestGetConstructorOverloads (); } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string) }, messageCode: "IL2080")] + [ExpectedWarning ("IL2080", nameof (Type.GetMethod))] static void TestGetPublicParameterlessConstructorWithEmptyTypes () { s_typeWithKeptPublicParameterlessConstructor.GetConstructor (Type.EmptyTypes); s_typeWithKeptPublicParameterlessConstructor.GetMethod ("Foo"); } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string) }, messageCode: "IL2080")] + [ExpectedWarning ("IL2080", nameof (Type.GetMethod))] static void TestGetPublicParameterlessConstructorWithArrayEmpty () { s_typeWithKeptPublicParameterlessConstructor.GetConstructor (Array.Empty<Type> ()); s_typeWithKeptPublicParameterlessConstructor.GetMethod ("Foo"); } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (Type[]) }, messageCode: "IL2080")] + [ExpectedWarning ("IL2080", nameof (Type.GetConstructor))] static void TestGetPublicParameterlessConstructorWithUnknownArray () { s_typeWithKeptPublicParameterlessConstructor.GetConstructor (s_localEmptyArrayInvisibleToAnalysis); } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string) }, messageCode: "IL2080")] + [ExpectedWarning ("IL2080", nameof (Type.GetMethod))] static void TestGetConstructorOverloads () { s_typeWithKeptPublicParameterlessConstructor.GetConstructor (BindingFlags.Public, null, Type.EmptyTypes, null); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs new file mode 100644 index 000000000..40bf18ca7 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/ExceptionalDataFlow.cs @@ -0,0 +1,814 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + public class ExceptionalDataFlow + { + public static void Main () + { + TryFlowsToFinally (); + TryFlowsToAfterFinally (); + MultipleTryExits (); + MultipleFinallyPaths (); + FinallyChain (); + FinallyChainWithPostFinallyState (); + TryFlowsToCatch (); + CatchFlowsToFinally (); + CatchFlowsToAfterTry (); + CatchFlowsToAfterFinally (); + FinallyFlowsToAfterFinally (); + TryFlowsToMultipleCatchAndFinally (); + NestedWithFinally (); + ControlFlowsOutOfMultipleFinally (); + NestedWithCatch (); + CatchInTry (); + CatchInTryWithFinally (); + TestCatchesHaveSeparateState (); + FinallyWithBranchToFirstBlock (); + FinallyWithBranchToFirstBlockAndEnclosingTryCatchState (); + CatchWithBranchToFirstBlock (); + CatchWithBranchToFirstBlockAndReassignment (); + CatchWithNonSimplePredecessor (); + FinallyWithNonSimplePredecessor (); + FinallyInTryWithPredecessor (); + NestedFinally (); + NestedFinallyWithPredecessor (); + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void TryFlowsToFinally () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + } finally { + // methods/fields/properties + RequireAll (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void TryFlowsToAfterFinally () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + } finally { + // prevent optimizing this away + _ = string.Empty; + } + // properties + RequireAll (t); + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void MultipleTryExits () + { + Type t = GetWithPublicConstructors (); + for (int i = 0; i < 10; i++) { + try { + if (string.Empty.Length == 0) { + t = GetWithPublicMethods (); + return; + } + if (string.Empty.Length == 1) { + t = GetWithPublicFields (); + continue; + } + if (string.Empty.Length == 2) { + t = GetWithPublicProperties (); + break; + } + } finally { + RequireAll (t); + } + } + } + + // There are multiple paths through the finally to different subsequent blocks. + // On each path, only one state is possible, but we conservatively merge the (non-exceptional) + // finally states for each path and expect the warnings to reflect this merged state. + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicEvents) + "()", + ProducedBy = ProducedBy.Analyzer)] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicEvents) + "()")] + + [ExpectedWarning ("IL2073", nameof (MultipleFinallyPaths) + "()", nameof (GetWithPublicEvents) + "()")] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] + public static Type MultipleFinallyPaths () + { + Type t = GetWithPublicMethods (); // reaches RequireAll1 and RequireAll2 + while (true) { + RequireAll1 (t); + try { + if (string.Empty.Length == 1) { + t = GetWithPublicFields (); // reaches RequireAll1 and RequireAll2 + continue; + } + if (string.Empty.Length == 0) { + t = GetWithPublicProperties (); // reaches RequireAll2 only, but the finally mergig means + // the analysis thinks it can reach RequireAll1. + break; + } + if (string.Empty.Length == 2) { + t = GetWithPublicEvents (); // reaches return only, but the finally merging means + // the analysis thinks it can reach RequireAll1 (and hence RequireAll2). + return t; + } + } finally { + _ = string.Empty; + } + } + RequireAll2 (t); // properties + + throw new Exception (); + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void FinallyChain () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + try { + t = GetWithPublicProperties (); + } finally { + RequireAll1 (t); // fields/properties + } + } finally { + RequireAll2 (t); // methods/fields/properties + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void FinallyChainWithPostFinallyState () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + try { + t = GetWithPublicProperties (); + } finally { + // normal: properties + // exception: fields/properties + RequireAll1 (t); // fields/properties + } + RequireAll2 (t); // properties + } finally { + // normal: properties + // exception: methods/fields/properties + RequireAll3 (t); // methods/fields/properties + } + RequireAll4 (t); + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void TryFlowsToCatch () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + } catch { + // methods/fields/properties + RequireAll (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void CatchFlowsToFinally () + { + Type t = GetWithPublicMethods (); + try { + } catch { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + } finally { + // methods/fields/properties + RequireAll (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void CatchFlowsToAfterTry () + { + Type t = GetWithPublicMethods (); + try { + } catch { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + } + // methods/properties, not fields + RequireAll (t); + } + + + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void CatchFlowsToAfterFinally () + { + Type t = GetWithPublicMethods (); + try { + } catch { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + } finally { } + // methods/properties, not fields + RequireAll (t); + } + + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void FinallyFlowsToAfterFinally () + { + Type t = GetWithPublicMethods (); + try { + } finally { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + } + // properties only + RequireAll (t); + } + + public class Exception1 : Exception { } + public class Exception2 : Exception { } + + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll4) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + + [ExpectedWarning ("IL2072", nameof (RequireAll5) + "(Type)", nameof (GetWithPublicEvents) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicProperties) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll6) + "(Type)", nameof (GetWithPublicEvents) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll7) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + + + public static void TryFlowsToMultipleCatchAndFinally () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + RequireAll1 (t); // fields only + } catch (Exception1) { + RequireAll2 (t); // methods/fields + t = GetWithPublicProperties (); + RequireAll3 (t); // properties only + } catch (Exception2) { + RequireAll4 (t); // methods/fields + t = GetWithPublicEvents (); + RequireAll5 (t); // events only + } finally { + RequireAll6 (t); // methods/fields/properties/events + t = GetWithPublicConstructors (); + RequireAll7 (t); // ctors only + } + RequireAll (t); + } + + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicConstructors) + "()", + ProducedBy = ProducedBy.Analyzer)] + + public static void NestedWithFinally () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + try { + // fields + t = GetWithPublicProperties (); + } finally { + // fields/properties + RequireAll1 (t); + t = GetWithPublicEvents (); + t = GetWithPublicConstructors (); + } + // ctors + RequireAll2 (t); + } finally { + // methods/fields/properties/events/constructors + RequireAll3 (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()")] + public static void ControlFlowsOutOfMultipleFinally () + { + Type t = GetWithPublicMethods (); + try { + try { + try { + t = GetWithPublicFields (); + } finally { + // methods/fields + RequireAll1 (t); + t = GetWithPublicProperties (); + } + } finally { + // methods/fields/properties + RequireAll2 (t); + t = GetWithPublicEvents (); + } + } finally { + // methods/fields/propreties/events + RequireAll3 (t); + } + } + + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicEvents) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + + public static void NestedWithCatch () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + try { + // fields + t = GetWithPublicProperties (); + } catch { + // fields/properties + RequireAll1 (t); + t = GetWithPublicEvents (); + t = GetWithPublicConstructors (); + } + // properties/ctors + RequireAll2 (t); + } catch { + // methods/fields/properties/events/constructors + RequireAll3 (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()")] + public static void CatchInTry () + { + try { + Type t = GetWithPublicMethods (); + try { + } catch { + t = GetWithPublicFields (); + RequireAll (t); + } + } catch { + } + } + + // This tests a case where the catch state was being merged with the containing try state incorrectly. + // In the bug, the exceptional catch state, which is used in the finally, had too much in it. + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()")] + // The bug was producing this warning: + // [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicConstructors) + "()")] + public static void CatchInTryWithFinally () + { + Type t = GetWithPublicConstructors (); + try { + t = GetWithPublicMethods (); + // methods + // ex: ctors/methods + try { + // methods + // ex: methods + } catch { + // methods + t = GetWithPublicFields (); + // fields + // ex: methods/fields + RequireAll1 (t); + } finally { + // normal state: fields + // exceptional state: methods/fields + RequireAll2 (t); + } + } catch { + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] + + public static void TestCatchesHaveSeparateState () + { + Type t = GetWithPublicMethods (); + try { + } catch (Exception1) { + t = GetWithPublicFields (); + } catch (Exception2) { + // methods only! + RequireAll (t); + } finally { + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + public static void FinallyWithBranchToFirstBlock () + { + Type t = GetWithPublicMethods (); + try { + } finally { + FinallyStart: + RequireAll (t); + t = GetWithPublicFields (); + goto FinallyStart; + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + public static void FinallyWithBranchToFirstBlockAndEnclosingTryCatchState () + { + try { + Type t = GetWithPublicProperties (); + t = GetWithPublicMethods (); + try { + } finally { + FinallyStart: + // methods/fields + RequireAll (t); + t = GetWithPublicFields (); + goto FinallyStart; + } + } finally { + // An operation just to prevent optimizing away + // the try/finally. + _ = String.Empty; + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + public static void CatchWithBranchToFirstBlock () + { + Type t = GetWithPublicMethods (); + try { + } catch { + CatchStart: + RequireAll (t); + t = GetWithPublicFields (); + goto CatchStart; + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (RequireAll) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + public static void CatchWithBranchToFirstBlockAndReassignment () + { + Type t = GetWithPublicMethods (); + try { + } catch { + CatchStart: + RequireAll (t); // methods/fields, but not properties! + t = GetWithPublicProperties (); + t = GetWithPublicFields (); + goto CatchStart; + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void CatchWithNonSimplePredecessor () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + try { + // properties only + } catch { + // properties only. + RequireAll1 (t); + } + } catch { + // methods/fields/properties + RequireAll2 (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void FinallyWithNonSimplePredecessor () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + try { + // properties only + } catch { + // properties only. + RequireAll1 (t); + } + } finally { + // methods/fields/properties + RequireAll2 (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void FinallyInTryWithPredecessor () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + t = GetWithPublicProperties (); + try { + // properties only + } finally { + // properties only. + RequireAll1 (t); + } + } finally { + // methods/fields/properties + RequireAll2 (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void NestedFinally () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + } finally { + try { + RequireAll1 (t); + t = GetWithPublicProperties (); + } finally { + RequireAll2 (t); + } + RequireAll3 (t); + } + } + + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll1) + "(Type)", nameof (GetWithPublicFields) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (RequireAll2) + "(Type)", nameof (GetWithPublicProperties) + "()")] + + [ExpectedWarning ("IL2072", nameof (RequireAll3) + "(Type)", nameof (GetWithPublicProperties) + "()")] + public static void NestedFinallyWithPredecessor () + { + Type t = GetWithPublicMethods (); + try { + t = GetWithPublicFields (); + } finally { + _ = 0; // add an operation so that the try isn't the start of the finally. + try { + RequireAll1 (t); + t = GetWithPublicProperties (); + } finally { + RequireAll2 (t); + } + RequireAll3 (t); + } + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + public static Type GetWithPublicMethods () + { + return null; + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] + public static Type GetWithPublicFields () + { + return null; + } + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] + public static Type GetWithPublicProperties () + { + return null; + } + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] + public static Type GetWithPublicEvents () + { + return null; + } + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + public static Type GetWithPublicConstructors () + { + return null; + } + + public static void RequirePublicMethods ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] + Type type) + { + } + + public static void RequirePublicFields ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] + Type type) + { + } + public static void RequirePublicProperties ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] + Type type) + { + } + + + public static void RequireFieldsAndProperties ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] + Type type) + { + } + + public static void RequireAll ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + public static void RequireAll1 ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + public static void RequireAll2 ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + public static void RequireAll3 ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + public static void RequireAll4 ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + public static void RequireAll5 ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + public static void RequireAll6 ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + public static void RequireAll7 ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + Type type) + { + } + } +}
\ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs index cb36d87a3..51d21f1f2 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/FieldDataFlow.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -10,8 +10,9 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] + [ExpectedNoWarnings] public class FieldDataFlow { public static void Main () @@ -43,13 +44,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow static Type _staticTypeWithoutRequirements; - [ExpectedWarning ("IL2097", nameof (_annotationOnWrongType))] + // TODO: warn about annotation on wrong type in analyzer: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2097", nameof (_annotationOnWrongType), + ProducedBy = ProducedBy.Trimmer)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] static object _annotationOnWrongType; - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, - messageCode: "IL2077", message: new string[] { "_typeWithPublicParameterlessConstructor", "type", "RequirePublicConstructors(Type)" })] - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] + [ExpectedWarning ("IL2077", nameof (RequirePublicConstructors), + "_typeWithPublicParameterlessConstructor", "type", "RequirePublicConstructors(Type)")] + [ExpectedWarning ("IL2077", nameof (RequireNonPublicConstructors))] private void ReadFromInstanceField () { RequirePublicParameterlessConstructor (_typeWithPublicParameterlessConstructor); @@ -58,22 +61,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow RequireNothing (_typeWithPublicParameterlessConstructor); } - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_typeWithPublicParameterlessConstructor), - messageCode: "IL2074", message: new string[] { - nameof (GetUnkownType), - nameof (_typeWithPublicParameterlessConstructor) - })] - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_typeWithPublicParameterlessConstructor), messageCode: "IL2074")] + [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_typeWithPublicParameterlessConstructor), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_typeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))] private void WriteToInstanceField () { _typeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor (); _typeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors (); _typeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors (); - _typeWithPublicParameterlessConstructor = GetUnkownType (); + _typeWithPublicParameterlessConstructor = GetUnknownType (); } - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] + [ExpectedWarning ("IL2077", nameof (RequirePublicConstructors))] + [ExpectedWarning ("IL2077", nameof (RequireNonPublicConstructors))] private void ReadFromInstanceFieldOnADifferentClass () { var store = new TypeStore (); @@ -84,8 +83,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow RequireNothing (store._typeWithPublicParameterlessConstructor); } - [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._typeWithPublicParameterlessConstructor), messageCode: "IL2074")] - [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._typeWithPublicParameterlessConstructor), messageCode: "IL2074")] + [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._typeWithPublicParameterlessConstructor), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._typeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))] private void WriteToInstanceFieldOnADifferentClass () { var store = new TypeStore (); @@ -93,11 +92,11 @@ namespace Mono.Linker.Tests.Cases.DataFlow store._typeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor (); store._typeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors (); store._typeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors (); - store._typeWithPublicParameterlessConstructor = GetUnkownType (); + store._typeWithPublicParameterlessConstructor = GetUnknownType (); } - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] + [ExpectedWarning ("IL2077", nameof (RequirePublicConstructors))] + [ExpectedWarning ("IL2077", nameof (RequireNonPublicConstructors))] private void ReadFromStaticField () { RequirePublicParameterlessConstructor (_staticTypeWithPublicParameterlessConstructor); @@ -106,24 +105,20 @@ namespace Mono.Linker.Tests.Cases.DataFlow RequireNothing (_staticTypeWithPublicParameterlessConstructor); } - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")] - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")] - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (_staticTypeWithPublicParameterlessConstructor), - messageCode: "IL2079", message: new string[] { - nameof(_staticTypeWithoutRequirements), - nameof(_staticTypeWithPublicParameterlessConstructor) - })] + [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_staticTypeWithPublicParameterlessConstructor), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (FieldDataFlow) + "." + nameof (_staticTypeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))] + [ExpectedWarning ("IL2079", nameof (FieldDataFlow) + "." + nameof (_staticTypeWithPublicParameterlessConstructor), nameof (_staticTypeWithoutRequirements))] private void WriteToStaticField () { _staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor (); _staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors (); _staticTypeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors (); - _staticTypeWithPublicParameterlessConstructor = GetUnkownType (); + _staticTypeWithPublicParameterlessConstructor = GetUnknownType (); _staticTypeWithPublicParameterlessConstructor = _staticTypeWithoutRequirements; } - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] - [UnrecognizedReflectionAccessPattern (typeof (FieldDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] + [ExpectedWarning ("IL2077", nameof (RequirePublicConstructors))] + [ExpectedWarning ("IL2077", nameof (RequireNonPublicConstructors))] private void ReadFromStaticFieldOnADifferentClass () { RequirePublicParameterlessConstructor (TypeStore._staticTypeWithPublicParameterlessConstructor); @@ -132,17 +127,19 @@ namespace Mono.Linker.Tests.Cases.DataFlow RequireNothing (TypeStore._staticTypeWithPublicParameterlessConstructor); } - [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")] - [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), messageCode: "IL2074")] + [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), nameof (GetUnknownType))] + [ExpectedWarning ("IL2074", nameof (TypeStore) + "." + nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), nameof (GetTypeWithNonPublicConstructors))] private void WriteToStaticFieldOnADifferentClass () { TypeStore._staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicParameterlessConstructor (); TypeStore._staticTypeWithPublicParameterlessConstructor = GetTypeWithPublicConstructors (); TypeStore._staticTypeWithPublicParameterlessConstructor = GetTypeWithNonPublicConstructors (); - TypeStore._staticTypeWithPublicParameterlessConstructor = GetUnkownType (); + TypeStore._staticTypeWithPublicParameterlessConstructor = GetUnknownType (); } - [UnrecognizedReflectionAccessPattern (typeof (TypeStore), nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), messageCode: "IL2064", message: new string[] { nameof (TypeStore._staticTypeWithPublicParameterlessConstructor) })] + // TODO: warn about unknown types in analyzer: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2064", nameof (TypeStore) + "." + nameof (TypeStore._staticTypeWithPublicParameterlessConstructor), + ProducedBy = ProducedBy.Trimmer)] private void WriteUnknownValue () { var array = new object[1]; @@ -191,7 +188,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow return null; } - private static Type GetUnkownType () + private static Type GetUnknownType () { return null; } diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterDataFlow.cs index 979275897..fb31e7800 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> (); @@ -48,11 +45,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow TypeRequiresNothingPassThrough<TestType>.Test (); } - static void TestGenericParameterFlowsToField () - { - TypeRequiresPublicFields<TestType>.TestFields (); - } - static void TestGenericParameterFlowsToReturnValue () { _ = TypeRequiresPublicFields<TestType>.ReturnRequiresPublicFields (); @@ -68,15 +60,11 @@ namespace Mono.Linker.Tests.Cases.DataFlow static Type FieldRequiresNothing; + class TypeRequiresPublicFields< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> { - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, - messageCode: "IL2087", message: new string[] { - nameof (T), - nameof (TypeRequiresPublicFields <T>), - nameof (DataFlowTypeExtensions.RequiresPublicMethods) - })] + [ExpectedWarning ("IL2087", "'" + nameof (T) + "'", nameof (TypeRequiresPublicFields<T>), nameof (DataFlowTypeExtensions.RequiresPublicMethods))] public static void Test () { typeof (T).RequiresPublicFields (); @@ -90,12 +78,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (T).RequiresPublicMethods (); } - [UnrecognizedReflectionAccessPattern (typeof (GenericParameterDataFlow), nameof (FieldRequiresPublicMethods), - messageCode: "IL2089", message: new string[] { - nameof (T), - nameof (TypeRequiresPublicFields <T>), - nameof (FieldRequiresPublicMethods) - })] + [ExpectedWarning ("IL2089", "'" + nameof (T) + "'", nameof (TypeRequiresPublicFields<T>), nameof (FieldRequiresPublicMethods))] public static void TestFields () { FieldRequiresPublicFields = typeof (T); @@ -103,27 +86,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow FieldRequiresNothing = typeof (T); } - - [RecognizedReflectionAccessPattern] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] public static Type ReturnRequiresPublicFields () { return typeof (T); } - - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicFields<>), nameof (ReturnRequiresPublicMethods), new Type[] { }, returnType: typeof (Type), - messageCode: "IL2088", message: new string[] { - nameof (T), - nameof (TypeRequiresPublicFields<T>), - nameof (ReturnRequiresPublicMethods) - })] + [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); @@ -133,7 +107,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow class TypeRequiresPublicMethods< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> { - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] public static void Test () { typeof (T).RequiresPublicFields (); @@ -144,8 +118,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow class TypeRequiresNothing<T> { - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] public static void Test () { typeof (T).RequiresPublicFields (); @@ -157,12 +131,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow class TypeRequiresPublicFieldsPassThrough< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TSource> { - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", - messageCode: "IL2091", message: new string[] { - nameof(TSource), + [ExpectedWarning ("IL2091", nameof (TSource), "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeRequiresPublicFieldsPassThrough<TSource>", "T", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeRequiresPublicMethods<T>" })] + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeRequiresPublicMethods<T>")] public static void Test () { TypeRequiresPublicFields<TSource>.Test (); @@ -173,8 +145,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow class TypeRequiresNothingPassThrough<T> { - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicFields<>), null, genericParameter: "T", messageCode: "IL2091")] - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicFields<T>))] + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<T>))] public static void Test () { TypeRequiresPublicFields<T>.Test (); @@ -183,6 +155,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 (); @@ -198,7 +241,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicMethods)] TBoth, TNothing> { - [RecognizedReflectionAccessPattern] public static void TestMultiple () { typeof (TFields).RequiresPublicFields (); @@ -211,7 +253,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TNothing).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] public static void TestFields () { typeof (TFields).RequiresPublicFields (); @@ -219,7 +261,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TFields).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] public static void TestMethods () { typeof (TMethods).RequiresPublicFields (); @@ -227,7 +269,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TMethods).RequiresNone (); } - [RecognizedReflectionAccessPattern] public static void TestBoth () { typeof (TBoth).RequiresPublicFields (); @@ -235,8 +276,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TBoth).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] public static void TestNothing () { typeof (TNothing).RequiresPublicFields (); @@ -245,51 +286,27 @@ namespace Mono.Linker.Tests.Cases.DataFlow } } - [RecognizedReflectionAccessPattern] - 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> { - [RecognizedReflectionAccessPattern] - 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 (); + } } } - [RecognizedReflectionAccessPattern] - class DerivedTypeWithInstantiatedGenericOnBase : GenericBaseTypeWithRequirements<TestType> - { - } - - class GenericBaseTypeWithRequiresAll<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] T> - { - } - - [RecognizedReflectionAccessPattern] - class DerivedTypeWithInstantiationOverSelfOnBase : GenericBaseTypeWithRequirements<DerivedTypeWithInstantiationOverSelfOnBase> - { - } - - [UnrecognizedReflectionAccessPattern (typeof (GenericBaseTypeWithRequirements<>), null, genericParameter: "T", messageCode: "IL2091")] - class DerivedTypeWithOpenGenericOnBase<T> : GenericBaseTypeWithRequirements<T> - { - [UnrecognizedReflectionAccessPattern (typeof (GenericBaseTypeWithRequirements<>), null, genericParameter: "T", messageCode: "IL2091")] - public DerivedTypeWithOpenGenericOnBase () { } - } - - [RecognizedReflectionAccessPattern] - class DerivedTypeWithOpenGenericOnBaseWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> - : GenericBaseTypeWithRequirements<T> - { - } - static void TestInterfaceTypeGenericRequirements () { IGenericInterfaceTypeWithRequirements<TestType> instance = new InterfaceImplementationTypeWithInstantiatedGenericOnBase (); @@ -302,7 +319,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [RecognizedReflectionAccessPattern] class InterfaceImplementationTypeWithInstantiatedGenericOnBase : IGenericInterfaceTypeWithRequirements<TestType> { } @@ -311,49 +327,19 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [RecognizedReflectionAccessPattern] class InterfaceImplementationTypeWithInstantiationOverSelfOnBase : IGenericInterfaceTypeWithRequiresAll<InterfaceImplementationTypeWithInstantiationOverSelfOnBase> { } - [UnrecognizedReflectionAccessPattern (typeof (IGenericInterfaceTypeWithRequirements<>), null, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (IGenericInterfaceTypeWithRequirements<T>))] class InterfaceImplementationTypeWithOpenGenericOnBase<T> : IGenericInterfaceTypeWithRequirements<T> { } - - [RecognizedReflectionAccessPattern] class InterfaceImplementationTypeWithOpenGenericOnBaseWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> : IGenericInterfaceTypeWithRequirements<T> { } - [RecognizedReflectionAccessPattern] - 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. - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, - messageCode: "IL2087", message: new string[] { - 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 (); - } - } - } - - [RecognizedReflectionAccessPattern] static void TestTypeGenericRequirementsOnMembers () { // Basically just root everything we need to test @@ -379,50 +365,46 @@ namespace Mono.Linker.Tests.Cases.DataFlow class TypeGenericRequirementsOnMembers<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TOuter> { - [RecognizedReflectionAccessPattern] public TypeRequiresPublicFields<TOuter> PublicFieldsField; - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))] public TypeRequiresPublicMethods<TOuter> PublicMethodsField; public TypeRequiresPublicFields<TOuter> PublicFieldsProperty { - [RecognizedReflectionAccessPattern] get; - [RecognizedReflectionAccessPattern] set; } + [ExpectedWarning ("IL2091", nameof (TypeGenericRequirementsOnMembers<TOuter>), ProducedBy = ProducedBy.Analyzer)] public TypeRequiresPublicMethods<TOuter> PublicMethodsProperty { - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>), ProducedBy = ProducedBy.Trimmer)] get => null; - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>), ProducedBy = ProducedBy.Trimmer)] set { } } - [RecognizedReflectionAccessPattern] public void PublicFieldsMethodParameter (TypeRequiresPublicFields<TOuter> param) { } - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))] public void PublicMethodsMethodParameter (TypeRequiresPublicMethods<TOuter> param) { } - [RecognizedReflectionAccessPattern] public TypeRequiresPublicFields<TOuter> PublicFieldsMethodReturnValue () { return null; } - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] // Return value - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] // Compiler generated local variable + + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>), ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))] public TypeRequiresPublicMethods<TOuter> PublicMethodsMethodReturnValue () { return null; } - [RecognizedReflectionAccessPattern] public void PublicFieldsMethodLocalVariable () { TypeRequiresPublicFields<TOuter> t = null; } - [UnrecognizedReflectionAccessPattern (typeof (TypeRequiresPublicMethods<>), null, genericParameter: "T", messageCode: "IL2091")] + + [ExpectedWarning ("IL2091", nameof (TypeRequiresPublicMethods<TOuter>))] public void PublicMethodsMethodLocalVariable () { TypeRequiresPublicMethods<TOuter> t = null; } } - [RecognizedReflectionAccessPattern] static void TestPartialInstantiationTypes () { _ = new PartialyInstantiatedFields<TestType> (); @@ -437,27 +419,25 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } - [RecognizedReflectionAccessPattern] class PartialyInstantiatedFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TOuter> : BaseForPartialInstantiation<TOuter, TestType> { } - [RecognizedReflectionAccessPattern] class FullyInstantiatedOverPartiallyInstantiatedFields : PartialyInstantiatedFields<TestType> { } - [UnrecognizedReflectionAccessPattern (typeof (BaseForPartialInstantiation<,>), null, genericParameter: "TMethods", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (BaseForPartialInstantiation<TestType, TOuter>), "'TMethods'")] class PartialyInstantiatedMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TOuter> : BaseForPartialInstantiation<TestType, TOuter> { - [UnrecognizedReflectionAccessPattern (typeof (BaseForPartialInstantiation<,>), null, genericParameter: "TMethods", messageCode: "IL2091")] + // Analyzer does not see the base class constructor + [ExpectedWarning ("IL2091", nameof (BaseForPartialInstantiation<TestType, TOuter>), "'TMethods'", ProducedBy = ProducedBy.Trimmer)] public PartialyInstantiatedMethods () { } } - [RecognizedReflectionAccessPattern] class FullyInstantiatedOverPartiallyInstantiatedMethods : PartialyInstantiatedMethods<TestType> { @@ -472,7 +452,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow MethodRequiresNothingPassThrough<TestType> (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] static void MethodRequiresPublicFields< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () { @@ -481,7 +461,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (T).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] static void MethodRequiresPublicMethods< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { @@ -497,8 +477,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (T).RequiresPublicFields (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] static void MethodRequiresNothing<T> () { typeof (T).RequiresPublicFields (); @@ -506,7 +486,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (T).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (GenericParameterDataFlow), nameof (MethodRequiresPublicMethods) + "<T>", new Type[0] { }, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (MethodRequiresPublicMethods), "'T'")] static void MethodRequiresPublicFieldsPassThrough< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () { @@ -515,8 +495,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow MethodRequiresNothing<T> (); } - [UnrecognizedReflectionAccessPattern (typeof (GenericParameterDataFlow), nameof (MethodRequiresPublicFields) + "<T>", new Type[0] { }, genericParameter: "T", messageCode: "IL2091")] - [UnrecognizedReflectionAccessPattern (typeof (GenericParameterDataFlow), nameof (MethodRequiresPublicMethods) + "<T>", new Type[0] { }, genericParameter: "T", messageCode: "IL2091")] + [ExpectedWarning ("IL2091", nameof (MethodRequiresPublicFields), "'T'")] + [ExpectedWarning ("IL2091", nameof (MethodRequiresPublicMethods), "'T'")] static void MethodRequiresNothingPassThrough<T> () { MethodRequiresPublicFields<T> (); @@ -524,174 +504,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow MethodRequiresNothing<T> (); } - static void TestMethodGenericParametersViaInheritance () - { - TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticRequiresPublicFields<TestType> (); - TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticRequiresPublicFieldsNonGeneric (); - - TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticPartialInstantiation (); - TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticPartialInstantiationUnrecognized (); - - var instance = new TypeWithInstantiatedGenericMethodViaGenericParameter<TestType> (); - - instance.InstanceRequiresPublicFields<TestType> (); - instance.InstanceRequiresPublicFieldsNonGeneric (); - - instance.VirtualRequiresPublicFields<TestType> (); - instance.VirtualRequiresPublicMethods<TestType> (); - - instance.CallInterface (); - - IInterfaceWithGenericMethod interfaceInstance = (IInterfaceWithGenericMethod) instance; - interfaceInstance.InterfaceRequiresPublicFields<TestType> (); - interfaceInstance.InterfaceRequiresPublicMethods<TestType> (); - } - - class BaseTypeWithGenericMethod - { - [RecognizedReflectionAccessPattern] - public static void StaticRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () - => typeof (T).RequiresPublicFields (); - [RecognizedReflectionAccessPattern] - public void InstanceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () - => typeof (T).RequiresPublicFields (); - [RecognizedReflectionAccessPattern] - public virtual void VirtualRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () - => typeof (T).RequiresPublicFields (); - - [RecognizedReflectionAccessPattern] - public static void StaticRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () - => typeof (T).RequiresPublicMethods (); - [RecognizedReflectionAccessPattern] - public void InstanceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]T> () - => typeof (T).RequiresPublicMethods (); - [RecognizedReflectionAccessPattern] - public virtual void VirtualRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)]T> () - => typeof (T).RequiresPublicMethods (); - - [RecognizedReflectionAccessPattern] - public static void StaticRequiresMultipleGenericParams< - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods> () - { - typeof (TFields).RequiresPublicFields (); - typeof (TMethods).RequiresPublicMethods (); - } - } - - interface IInterfaceWithGenericMethod - { - void InterfaceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> (); - void InterfaceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> (); - } - - class TypeWithInstantiatedGenericMethodViaGenericParameter<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TOuter> - : BaseTypeWithGenericMethod, IInterfaceWithGenericMethod - { - [UnrecognizedReflectionAccessPattern (typeof (BaseTypeWithGenericMethod), nameof (BaseTypeWithGenericMethod.StaticRequiresPublicMethods) + "<T>", new Type[0] { }, genericParameter: "T", - messageCode: "IL2091", message: new string[] { - "TInner", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>.StaticRequiresPublicFields<TInner>()", - "T", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresPublicMethods<T>()" })] - public static void StaticRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TInner> () - { - StaticRequiresPublicFields<TInner> (); - StaticRequiresPublicMethods<TInner> (); - } - - [UnrecognizedReflectionAccessPattern (typeof (BaseTypeWithGenericMethod), nameof (BaseTypeWithGenericMethod.StaticRequiresPublicMethods) + "<T>", new Type[0] { }, genericParameter: "T", - messageCode: "IL2091", message: new string[] { - "TOuter", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>", - "T", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresPublicMethods<T>()" })] - public static void StaticRequiresPublicFieldsNonGeneric () - { - StaticRequiresPublicFields<TOuter> (); - StaticRequiresPublicMethods<TOuter> (); - } - - [RecognizedReflectionAccessPattern] - public static void StaticPartialInstantiation () - { - StaticRequiresMultipleGenericParams<TOuter, TestType> (); - } - - [UnrecognizedReflectionAccessPattern (typeof (BaseTypeWithGenericMethod), nameof (BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams) + "<TFields,TMethods>", new Type[0] { }, genericParameter: "TMethods", - messageCode: "IL2091", message: new string[] { - "TOuter", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>", - "TMethods", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresMultipleGenericParams<TFields,TMethods>()" })] - public static void StaticPartialInstantiationUnrecognized () - { - StaticRequiresMultipleGenericParams<TestType, TOuter> (); - } - - [UnrecognizedReflectionAccessPattern (typeof (BaseTypeWithGenericMethod), nameof (BaseTypeWithGenericMethod.InstanceRequiresPublicMethods) + "<T>", new Type[0] { }, genericParameter: "T", - messageCode: "IL2091", message: new string[] { - "TInner", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>.InstanceRequiresPublicFields<TInner>()", - "T", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.InstanceRequiresPublicMethods<T>()" })] - public void InstanceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TInner> () - { - InstanceRequiresPublicFields<TInner> (); - InstanceRequiresPublicMethods<TInner> (); - } - - [UnrecognizedReflectionAccessPattern (typeof (BaseTypeWithGenericMethod), nameof (BaseTypeWithGenericMethod.InstanceRequiresPublicMethods) + "<T>", new Type[0] { }, genericParameter: "T", - messageCode: "IL2091", message: new string[] { - "TOuter", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>", - "T", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.InstanceRequiresPublicMethods<T>()" })] - public void InstanceRequiresPublicFieldsNonGeneric () - { - InstanceRequiresPublicFields<TOuter> (); - InstanceRequiresPublicMethods<TOuter> (); - } - - [RecognizedReflectionAccessPattern] - public override void VirtualRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () - { - typeof (T).RequiresPublicFields (); - } - - [RecognizedReflectionAccessPattern] - public override void VirtualRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () - { - typeof (T).RequiresPublicMethods (); - } - - [RecognizedReflectionAccessPattern] - public void InterfaceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () - { - typeof (T).RequiresPublicFields (); ; - } - - [RecognizedReflectionAccessPattern] - public void InterfaceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () - { - typeof (T).RequiresPublicMethods (); - } - - [UnrecognizedReflectionAccessPattern (typeof (IInterfaceWithGenericMethod), nameof (IInterfaceWithGenericMethod.InterfaceRequiresPublicMethods) + "<T>", new Type[0] { }, genericParameter: "T", - messageCode: "IL2091", message: new string[] { - "TOuter", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>", - "T", - "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.IInterfaceWithGenericMethod.InterfaceRequiresPublicMethods<T>()" })] - public void CallInterface () - { - IInterfaceWithGenericMethod interfaceInstance = (IInterfaceWithGenericMethod) this; - interfaceInstance.InterfaceRequiresPublicFields<TOuter> (); - interfaceInstance.InterfaceRequiresPublicMethods<TOuter> (); - } - } - - static void TestMultipleGenericParametersOnMethod () { MethodMultipleWithDifferentRequirements_TestMultiple<TestType, TestType, TestType, TestType> (); @@ -701,7 +513,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow MethodMultipleWithDifferentRequirements_TestNothing<TestType, TestType, TestType, TestType> (); } - [RecognizedReflectionAccessPattern] static void MethodMultipleWithDifferentRequirements_TestMultiple< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods, @@ -718,7 +529,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TNothing).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] static void MethodMultipleWithDifferentRequirements_TestFields< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods, @@ -730,7 +541,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TFields).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] static void MethodMultipleWithDifferentRequirements_TestMethods< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods, @@ -753,8 +564,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TBoth).RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicFields), new Type[] { typeof (Type) }, messageCode: "IL2087")] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) }, messageCode: "IL2087")] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + [ExpectedWarning ("IL2087", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] static void MethodMultipleWithDifferentRequirements_TestNothing< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods, @@ -766,537 +577,172 @@ namespace Mono.Linker.Tests.Cases.DataFlow typeof (TNothing).RequiresNone (); } - - class MakeGenericType + static void TestMethodGenericParametersViaInheritance () { - 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. - [RecognizedReflectionAccessPattern] - static void TestNullType () - { - Type nullType = null; - nullType.MakeGenericType (typeof (TestType)); - } - - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) }, - messageCode: "IL2055")] - static void TestUnknownInput (Type inputType) - { - inputType.MakeGenericType (typeof (TestType)); - } - - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) }, - messageCode: "IL2055")] - static void TestWithUnknownTypeArray (Type[] types) - { - typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types); - } - - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) }, - messageCode: "IL2055")] - static void TestWithArrayUnknownIndexSet (int indexToSet) - { - Type[] types = new Type[1]; - types[indexToSet] = typeof (TestType); - typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types); - } - - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.MakeGenericType), new Type[] { typeof (Type[]) }, - messageCode: "IL2055")] - static void TestWithArrayUnknownLengthSet (int arrayLen) - { - Type[] types = new Type[arrayLen]; - types[0] = typeof (TestType); - typeof (GenericWithPublicFieldsArgument<>).MakeGenericType (types); - } - - [RecognizedReflectionAccessPattern] - static void TestNoArguments () - { - typeof (TypeMakeGenericNoArguments).MakeGenericType (); - } - - class TypeMakeGenericNoArguments - { - } - - [RecognizedReflectionAccessPattern] - 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)); - } - - [RecognizedReflectionAccessPattern] - 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); - } - - [RecognizedReflectionAccessPattern] - 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> - { - } - - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirements () - { - typeof (GenericWithNoRequirements<>).MakeGenericType (typeof (TestType)); - } - - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirementsFromParam (Type type) - { - typeof (GenericWithNoRequirements<>).MakeGenericType (type); - } - - class GenericWithNoRequirements<T> - { - } - - [RecognizedReflectionAccessPattern] - static void TestWithMultipleArgumentsWithRequirements () - { - typeof (GenericWithMultipleArgumentsWithRequirements<,>).MakeGenericType (typeof (TestType), typeof (TestType)); - } - - class GenericWithMultipleArgumentsWithRequirements< - TOne, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TTwo> - { - } - - [RecognizedReflectionAccessPattern] - static void TestWithNewConstraint () - { - typeof (GenericWithNewConstraint<>).MakeGenericType (typeof (TestType)); - } + TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticRequiresPublicFields<TestType> (); + TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticRequiresPublicFieldsNonGeneric (); - class GenericWithNewConstraint<T> where T : new() - { - } + TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticPartialInstantiation (); + TypeWithInstantiatedGenericMethodViaGenericParameter<TestType>.StaticPartialInstantiationUnrecognized (); - [RecognizedReflectionAccessPattern] - static void TestWithStructConstraint () - { - typeof (GenericWithStructConstraint<>).MakeGenericType (typeof (TestType)); - } + var instance = new TypeWithInstantiatedGenericMethodViaGenericParameter<TestType> (); - class GenericWithStructConstraint<T> where T : struct - { - } + instance.InstanceRequiresPublicFields<TestType> (); + instance.InstanceRequiresPublicFieldsNonGeneric (); - [RecognizedReflectionAccessPattern] - static void TestWithUnmanagedConstraint () - { - typeof (GenericWithUnmanagedConstraint<>).MakeGenericType (typeof (TestType)); - } + instance.VirtualRequiresPublicFields<TestType> (); + instance.VirtualRequiresPublicMethods<TestType> (); - class GenericWithUnmanagedConstraint<T> where T : unmanaged - { - } + instance.CallInterface (); - [RecognizedReflectionAccessPattern] - static void TestWithNullable () - { - typeof (Nullable<>).MakeGenericType (typeof (TestType)); - } + IInterfaceWithGenericMethod interfaceInstance = (IInterfaceWithGenericMethod) instance; + interfaceInstance.InterfaceRequiresPublicFields<TestType> (); + interfaceInstance.InterfaceRequiresPublicMethods<TestType> (); } - class MakeGenericMethod + class BaseTypeWithGenericMethod { - 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 (); - } - - [RecognizedReflectionAccessPattern] - static void TestNullMethod () - { - MethodInfo mi = null; - mi.MakeGenericMethod (typeof (TestType)); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - static void TestUnknownMethod (MethodInfo mi) - { - mi.MakeGenericMethod (typeof (TestType)); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - 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); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - static void TestWithUnknownTypeArray (Type[] types) - { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static) - .MakeGenericMethod (types); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - static void TestWithArrayUnknownIndexSet (int indexToSet) - { - Type[] types = new Type[1]; - types[indexToSet] = typeof (TestType); - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static) - .MakeGenericMethod (types); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - 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); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - 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) - { - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - static void TestWithArrayPassedToAnotherMethod () - { - Type[] types = new Type[1]; - types[0] = typeof (TestType); - MethodThatTakesArrayParameter (types); - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static) - .MakeGenericMethod (types); - } - - [RecognizedReflectionAccessPattern] - 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. - [RecognizedReflectionAccessPattern] - static void TestWithArgumentsButNonGenericMethod () - { - typeof (MakeGenericMethod).GetMethod (nameof (NonGenericMethod), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod (typeof (TestType)); - } - - static void NonGenericMethod () - { - } - - [RecognizedReflectionAccessPattern] - static void TestWithRequirements () - { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static) - .MakeGenericMethod (typeof (TestType)); - } - - [RecognizedReflectionAccessPattern] - 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)); - } - - - [RecognizedReflectionAccessPattern] - static void TestWithRequirementsViaRuntimeMethod () - { - typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithRequirements), Type.EmptyTypes) - .MakeGenericMethod (typeof (TestType)); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - static void TestWithRequirementsButNoTypeArguments () - { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithRequirements), BindingFlags.Static) - .MakeGenericMethod (Type.EmptyTypes); - } - - public static void GenericWithRequirements<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () - { - } - - [RecognizedReflectionAccessPattern] - static void TestWithMultipleKnownGenericParameters () - { - typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static) - .MakeGenericMethod (typeof (TestType), typeof (TestType), typeof (TestType)); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - static void TestWithOneUnknownGenericParameter (Type[] types) - { - typeof (MakeGenericMethod).GetMethod (nameof (GenericMultipleParameters), BindingFlags.Static) - .MakeGenericMethod (typeof (TestType), typeof (TestStruct), types[0]); - } - - [UnrecognizedReflectionAccessPattern (typeof (MethodInfo), nameof (MethodInfo.MakeGenericMethod), new Type[] { typeof (Type[]) }, - messageCode: "IL2060")] - 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); - } - - [RecognizedReflectionAccessPattern] - 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> () - { - } + public static void StaticRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () + => typeof (T).RequiresPublicFields (); + public void InstanceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () + => typeof (T).RequiresPublicFields (); + public virtual void VirtualRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () + => typeof (T).RequiresPublicFields (); - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirements () - { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements), BindingFlags.Static) - .MakeGenericMethod (typeof (TestType)); - } + public static void StaticRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () + => typeof (T).RequiresPublicMethods (); + public void InstanceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () + => typeof (T).RequiresPublicMethods (); + public virtual void VirtualRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () + => typeof (T).RequiresPublicMethods (); - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirementsFromParam (Type type) + public static void StaticRequiresMultipleGenericParams< + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TFields, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TMethods> () { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements), BindingFlags.Static) - .MakeGenericMethod (type); + typeof (TFields).RequiresPublicFields (); + typeof (TMethods).RequiresPublicMethods (); } + } - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirementsViaRuntimeMethod () - { - typeof (MakeGenericMethod).GetRuntimeMethod (nameof (GenericWithNoRequirements), Type.EmptyTypes) - .MakeGenericMethod (typeof (TestType)); - } + interface IInterfaceWithGenericMethod + { + void InterfaceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> (); + void InterfaceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> (); + } - // There are no requirements, so no warnings - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirementsUnknownType (Type type) - { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements)) - .MakeGenericMethod (type); - } - // There are no requirements, so no warnings - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirementsWrongNumberOfTypeParameters () + class TypeWithInstantiatedGenericMethodViaGenericParameter<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TOuter> + : BaseTypeWithGenericMethod, IInterfaceWithGenericMethod + { + [ExpectedWarning ("IL2091", + "'TInner'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>.StaticRequiresPublicFields<TInner>()", + "'T'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresPublicMethods<T>()")] + public static void StaticRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TInner> () { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements)) - .MakeGenericMethod (typeof (TestType), typeof (TestType)); + StaticRequiresPublicFields<TInner> (); + StaticRequiresPublicMethods<TInner> (); } - // There are no requirements, so no warnings - [RecognizedReflectionAccessPattern] - static void TestWithNoRequirementsUnknownArrayElement () + [ExpectedWarning ("IL2091", + "'TOuter'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>", + "'T'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.StaticRequiresPublicMethods<T>()")] + public static void StaticRequiresPublicFieldsNonGeneric () { - Type[] types = new Type[1]; - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNoRequirements)) - .MakeGenericMethod (types); + StaticRequiresPublicFields<TOuter> (); + StaticRequiresPublicMethods<TOuter> (); } - public static void GenericWithNoRequirements<T> () + public static void StaticPartialInstantiation () { + StaticRequiresMultipleGenericParams<TOuter, TestType> (); } - - [RecognizedReflectionAccessPattern] - static void TestWithMultipleArgumentsWithRequirements () + [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>()", + ProducedBy = ProducedBy.Trimmer)] + public static void StaticPartialInstantiationUnrecognized () { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithMultipleArgumentsWithRequirements), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod (typeof (TestType), typeof (TestType)); + StaticRequiresMultipleGenericParams<TestType, TOuter> (); } - static void GenericWithMultipleArgumentsWithRequirements< - TOne, - [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TTwo> () + [ExpectedWarning ("IL2091", + "'TInner'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>.InstanceRequiresPublicFields<TInner>()", + "'T'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.InstanceRequiresPublicMethods<T>()")] + public void InstanceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] TInner> () { + InstanceRequiresPublicFields<TInner> (); + InstanceRequiresPublicMethods<TInner> (); } - [RecognizedReflectionAccessPattern] - static void TestWithNewConstraint () + [ExpectedWarning ("IL2091", + "'TOuter'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>", + "'T'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.BaseTypeWithGenericMethod.InstanceRequiresPublicMethods<T>()")] + public void InstanceRequiresPublicFieldsNonGeneric () { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithNewConstraint), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod (typeof (TestType)); + InstanceRequiresPublicFields<TOuter> (); + InstanceRequiresPublicMethods<TOuter> (); } - static void GenericWithNewConstraint<T> () where T : new() + public override void VirtualRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () { - var t = new T (); + typeof (T).RequiresPublicFields (); } - [RecognizedReflectionAccessPattern] - static void TestWithStructConstraint () + public override void VirtualRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithStructConstraint), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod (typeof (TestType)); + typeof (T).RequiresPublicMethods (); } - static void GenericWithStructConstraint<T> () where T : struct + public void InterfaceRequiresPublicFields<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] T> () { - var t = new T (); + typeof (T).RequiresPublicFields (); ; } - [RecognizedReflectionAccessPattern] - static void TestWithUnmanagedConstraint () + public void InterfaceRequiresPublicMethods<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] T> () { - typeof (MakeGenericMethod).GetMethod (nameof (GenericWithUnmanagedConstraint), BindingFlags.Static | BindingFlags.NonPublic) - .MakeGenericMethod (typeof (TestType)); + typeof (T).RequiresPublicMethods (); } - static void GenericWithUnmanagedConstraint<T> () where T : unmanaged + [ExpectedWarning ("IL2091", + "'TOuter'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.TypeWithInstantiatedGenericMethodViaGenericParameter<TOuter>", + "'T'", + "Mono.Linker.Tests.Cases.DataFlow.GenericParameterDataFlow.IInterfaceWithGenericMethod.InterfaceRequiresPublicMethods<T>()")] + public void CallInterface () { - var t = new T (); + IInterfaceWithGenericMethod interfaceInstance = (IInterfaceWithGenericMethod) this; + interfaceInstance.InterfaceRequiresPublicFields<TOuter> (); + interfaceInstance.InterfaceRequiresPublicMethods<TOuter> (); } } - [RecognizedReflectionAccessPattern] static void TestNewConstraintSatisfiesParameterlessConstructor<T> () where T : new() { RequiresParameterlessConstructor<T> (); } - [RecognizedReflectionAccessPattern] static void TestStructConstraintSatisfiesParameterlessConstructor<T> () where T : struct { RequiresParameterlessConstructor<T> (); } - - [RecognizedReflectionAccessPattern] static void TestUnmanagedConstraintSatisfiesParameterlessConstructor<T> () where T : unmanaged { RequiresParameterlessConstructor<T> (); @@ -1320,7 +766,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow // Warn about calls to the static methods and the ctor on the RUC type: [ExpectedWarning ("IL2026", "RUCTypeRequiresPublicFields<T>.StaticMethod", "message")] - [ExpectedWarning ("IL2026", "RUCTypeRequiresPublicFields<T>.StaticMethodRequiresPublicMethods<U>", "message")] + [ExpectedWarning ("IL2026", "RUCTypeRequiresPublicFields<T>.StaticMethodRequiresPublicMethods<U>", "message", ProducedBy = ProducedBy.Trimmer)] + // https://github.com/dotnet/linker/issues/2573 + [ExpectedWarning ("IL2026", "RUCTypeRequiresPublicFields<T>.StaticMethodRequiresPublicMethods<T>", "message", ProducedBy = ProducedBy.Analyzer)] [ExpectedWarning ("IL2026", "RUCTypeRequiresPublicFields<T>.RUCTypeRequiresPublicFields", "message")] // And about method generic parameters: [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>.InstanceMethodRequiresPublicMethods<U>()")] @@ -1329,12 +777,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow // And about type generic parameters: (one for each reference to the type): [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // StaticMethod [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // StaticMethodRequiresPublicMethods<T> - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // RUCTypeRequiresPublicFields<T> local [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // RUCTypeRequiresPublicFields<T> ctor - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // InstanceMethod - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // InstanceMethodRequiresPublicMethods<T> - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // VirtualMethod - [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>")] // VirtualMethodRequiresPublicMethods<T> + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>", ProducedBy = ProducedBy.Trimmer)] // RUCTypeRequiresPublicFields<T> local + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>", ProducedBy = ProducedBy.Trimmer)] // InstanceMethod + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>", ProducedBy = ProducedBy.Trimmer)] // InstanceMethodRequiresPublicMethods<T> + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>", ProducedBy = ProducedBy.Trimmer)] // VirtualMethod + [ExpectedWarning ("IL2091", "RUCTypeRequiresPublicFields<T>", ProducedBy = ProducedBy.Trimmer)] // VirtualMethodRequiresPublicMethods<T> static void TestNoWarningsInRUCType<T> () { RUCTypeRequiresPublicFields<T>.StaticMethod (); @@ -1384,12 +832,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/GetInterfaceDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs index b4ae82480..28ad0c355 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs @@ -76,6 +76,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow type.GetInterface ("ITestInterface").RequiresInterfaces (); } + class GetInterfaceInCtor + { + public GetInterfaceInCtor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.GetInterface ("ITestInterface").RequiresInterfaces (); + } + } + public static void Test () { TestNoAnnotation (typeof (TestType)); @@ -85,6 +93,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestKnownType (); TestMultipleValues (0, typeof (TestType)); TestMergedValues (0, typeof (TestType)); + var _ = new GetInterfaceInCtor (typeof (TestType)); } } diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs index e7da76ae9..fbf1c966a 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs @@ -13,68 +13,62 @@ using Mono.Linker.Tests.Cases.Expectations.Helpers; namespace Mono.Linker.Tests.Cases.DataFlow { - [RecognizedReflectionAccessPattern] + [ExpectedNoWarnings] [SkipKeptItemsValidation] class GetNestedTypeOnAllAnnotatedType { - [RecognizedReflectionAccessPattern] static void Main () { - TestOnAllAnnotatedParameter (typeof (GetNestedTypeOnAllAnnotatedType)); - TestOnNonAllAnnotatedParameter (typeof (GetNestedTypeOnAllAnnotatedType)); - TestWithBindingFlags (typeof (GetNestedTypeOnAllAnnotatedType)); - TestWithUnknownBindingFlags (BindingFlags.Public, typeof (GetNestedTypeOnAllAnnotatedType)); - TestUnsupportedBindingFlags (typeof (GetNestedTypeOnAllAnnotatedType)); + TestOnAllAnnotatedParameter (typeof (TestType)); + TestOnNonAllAnnotatedParameter (typeof (TestType)); + TestWithBindingFlags (typeof (TestType)); + TestWithUnknownBindingFlags (BindingFlags.Public, typeof (TestType)); + TestUnsupportedBindingFlags (typeof (TestType)); TestWithNull (); - TestIfElse (1, typeof (GetNestedTypeOnAllAnnotatedType), typeof (GetNestedTypeOnAllAnnotatedType)); - TestSwitchAllValid (1, typeof (GetNestedTypeOnAllAnnotatedType)); + TestIfElse (1, typeof (TestType), typeof (TestType)); + TestSwitchAllValid (1, typeof (TestType)); TestOnKnownTypeOnly (); } - [RecognizedReflectionAccessPattern] static void TestOnAllAnnotatedParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) { - var nestedType = parentType.GetNestedType (nameof (NestedType)); + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType)); nestedType.RequiresAll (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresAll), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll))] static void TestOnNonAllAnnotatedParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type parentType) { - var nestedType = parentType.GetNestedType (nameof (NestedType)); + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType)); nestedType.RequiresAll (); } - [RecognizedReflectionAccessPattern] static void TestWithBindingFlags ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) { - var nestedType = parentType.GetNestedType (nameof (NestedType), BindingFlags.Public); + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType), BindingFlags.Public); nestedType.RequiresAll (); } - [RecognizedReflectionAccessPattern] static void TestWithUnknownBindingFlags (BindingFlags bindingFlags, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) { - var nestedType = parentType.GetNestedType (nameof (NestedType), bindingFlags); + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType), bindingFlags); nestedType.RequiresAll (); } - [RecognizedReflectionAccessPattern] static void TestUnsupportedBindingFlags ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) { - var nestedType = parentType.GetNestedType (nameof (NestedType), BindingFlags.IgnoreCase); + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType), BindingFlags.IgnoreCase); nestedType.RequiresAll (); } - [RecognizedReflectionAccessPattern] static void TestWithNull () { Type parentType = null; - var nestedType = parentType.GetNestedType (nameof (NestedType)); + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType)); nestedType.RequiresAll (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresAll), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll))] static void TestIfElse (int number, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentWithAll, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type parentWithoutAll) { Type typeOfParent; @@ -83,35 +77,36 @@ namespace Mono.Linker.Tests.Cases.DataFlow } else { typeOfParent = parentWithoutAll; } - var nestedType = typeOfParent.GetNestedType (nameof (NestedType)); + var nestedType = typeOfParent.GetNestedType (nameof (TestType.NestedType)); nestedType.RequiresAll (); } - [RecognizedReflectionAccessPattern] static void TestSwitchAllValid (int number, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentWithAll) { Type typeOfParent = number switch { 1 => parentWithAll, 2 => null, - 3 => typeof (GetNestedTypeOnAllAnnotatedType) + 3 => typeof (TestType) }; - var nestedType = typeOfParent.GetNestedType (nameof (NestedType)); + var nestedType = typeOfParent.GetNestedType (nameof (TestType.NestedType)); nestedType.RequiresAll (); } - [RecognizedReflectionAccessPattern] static void TestOnKnownTypeOnly () { - typeof (GetNestedTypeOnAllAnnotatedType).GetNestedType (nameof (NestedType)).RequiresAll (); + typeof (TestType).GetNestedType (nameof (TestType.NestedType)).RequiresAll (); } - private class NestedType + class TestType { - NestedType () { } - public static int PublicStaticInt; - public void Method () { } - int Prop { get; set; } + public class NestedType + { + NestedType () { } + public static int PublicStaticInt; + public void Method () { } + int Prop { get; set; } + } } } } diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs index 5dc272f0f..289916c27 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs @@ -6,12 +6,14 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] + [ExpectedNoWarnings] public class GetTypeDataFlow { public static void Main () @@ -35,59 +37,59 @@ namespace Mono.Linker.Tests.Cases.DataFlow // Type.GetType over two params } - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] static void TestPublicParameterlessConstructor () { Type type = Type.GetType (GetStringTypeWithPublicParameterlessConstructor ()); - RequirePublicParameterlessConstructor (type); - RequirePublicConstructors (type); - RequireNonPublicConstructors (type); - RequireNothing (type); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] static void TestPublicConstructors () { Type type = Type.GetType (GetStringTypeWithPublicConstructors ()); - RequirePublicParameterlessConstructor (type); - RequirePublicConstructors (type); - RequireNonPublicConstructors (type); - RequireNothing (type); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequirePublicParameterlessConstructor), new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] static void TestConstructors () { Type type = Type.GetType (GetStringTypeWithNonPublicConstructors ()); - RequirePublicParameterlessConstructor (type); - RequirePublicConstructors (type); - RequireNonPublicConstructors (type); - RequireNothing (type); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (GetType), new Type[] { typeof (string) }, messageCode: "IL2057")] + [ExpectedWarning ("IL2057", nameof (GetType))] static void TestUnknownType () { Type type = Type.GetType (GetStringUnkownType ()); } - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] static void TestTypeNameFromParameter ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] string typeName) { - RequirePublicConstructors (Type.GetType (typeName)); + Type.GetType (typeName).RequiresPublicConstructors (); } [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] static string _typeNameWithPublicParameterlessConstructor; - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] static void TestTypeNameFromField () { - RequirePublicConstructors (Type.GetType (_typeNameWithPublicParameterlessConstructor)); + Type.GetType (_typeNameWithPublicParameterlessConstructor).RequiresPublicConstructors (); } static int _switchOnField; @@ -113,16 +115,13 @@ namespace Mono.Linker.Tests.Cases.DataFlow Type.GetType (typeName); } - [RecognizedReflectionAccessPattern] static void TestStringEmpty () { Type.GetType (string.Empty); } - [UnrecognizedReflectionAccessPattern (typeof (GetTypeDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, - messageCode: "IL2072", message: new string[] { "GetType" })] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetType), new Type[] { typeof (string) }, - messageCode: "IL2057", message: new string[] { "System.Type.GetType(String)" })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), nameof (Type.GetType))] + [ExpectedWarning ("IL2057", "System.Type.GetType(String)")] static void TestMultipleMixedValues () { string typeName = null; @@ -141,29 +140,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow break; } - RequireNonPublicConstructors (Type.GetType (typeName)); - } - - private static void RequirePublicParameterlessConstructor ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - Type type) - { - } - - private static void RequirePublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - Type type) - { - } - - private static void RequireNonPublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type) - { - } - - private static void RequireNothing (Type type) - { + Type.GetType (typeName).RequiresNonPublicConstructors (); } [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeInfoDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeInfoDataFlow.cs new file mode 100644 index 000000000..e99d87bc5 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/GetTypeInfoDataFlow.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class GetTypeInfoDataFlow + { + public static void Main () + { + TestNoAnnotations (typeof (TestType)); + TestWithAnnotations (typeof (TestType)); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + static void TestNoAnnotations (Type t) + { + t.GetTypeInfo ().RequiresPublicMethods (); + t.GetTypeInfo ().RequiresNone (); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + static void TestWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + t.GetTypeInfo ().RequiresPublicMethods (); + t.GetTypeInfo ().RequiresPublicFields (); + t.GetTypeInfo ().RequiresNone (); + } + + class TestType { } + } +} diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs index 2a12479a1..9506cf0db 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/IReflectDataflow.cs @@ -9,6 +9,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow // Hits what appears to be a bug in the tool // Could not initialize vtable of class(0x02000007) .MyReflect due to VTable setup of type Mono.Linker.Tests.Cases.DataFlow.IReflectDataflow+MyReflect failed assembly:/tmp/linker_tests/output/test.exe type:MyReflect member:(null) [SkipPeVerify] + [ExpectedNoWarnings] class IReflectDataflow { [ExpectBodyModified] diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs index eca6e9368..379ff5293 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlow.cs @@ -1,12 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + using System; using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] + [ExpectedNoWarnings] public class LocalDataFlow { public static void Main () @@ -18,7 +23,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestBranchMergeSwitch (); TestBranchMergeTry (); TestBranchMergeCatch (); - TestBranchMergeFinally (); // The remaining tests illustrate current limitations of the analysis // that we might be able to lift in the future. @@ -32,6 +36,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestBranchTry (); TestBranchCatch (); TestBranchFinally (); + TestBranchMergeFinally (); // These are missing warnings (potential failure at runtime) TestBackwardsEdgeGoto (); @@ -41,16 +46,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestNoWarningsInRUCType (); } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicFields(String)"})] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)")] + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicFields()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicMethods(String)"})] + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)")] public static void TestBranchMergeGoto () { string str = GetWithPublicMethods (); @@ -59,40 +60,32 @@ namespace Mono.Linker.Tests.Cases.DataFlow str = GetWithPublicFields (); End: - RequirePublicFields (str); // warns for GetWithPublicMethods - RequirePublicMethods (str); // warns for GetWithPublicFields + str.RequiresPublicFields (); // warns for GetWithPublicMethods + str.RequiresPublicMethods (); // warns for GetWithPublicFields } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicFields(String)" })] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)")] + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicFields()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicMethods(String)" })] + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)")] public static void TestBranchMergeIf () { string str = GetWithPublicMethods (); if (String.Empty.Length == 0) str = GetWithPublicFields (); - RequirePublicFields (str); // warns for GetWithPublicMethods - RequirePublicMethods (str); // warns for GetWithPublicFields + str.RequiresPublicFields (); // warns for GetWithPublicMethods + str.RequiresPublicMethods (); // warns for GetWithPublicFields } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicFields(String)" })] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)")] + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicFields()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicMethods(String)" })] + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)")] public static void TestBranchMergeIfElse () { string str = null; @@ -101,27 +94,21 @@ namespace Mono.Linker.Tests.Cases.DataFlow } else { str = GetWithPublicMethods (); } - RequirePublicFields (str); // warns for GetWithPublicMethods - RequirePublicMethods (str); // warns for GetWithPublicFields + str.RequiresPublicFields (); // warns for GetWithPublicMethods + str.RequiresPublicMethods (); // warns for GetWithPublicFields } static int _switchOnField; - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequireNonPublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicFields()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequireNonPublicMethods(String)" })] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequireNonPublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresNonPublicMethods) + "(String)")] + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequireNonPublicMethods(String)" })] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequireNonPublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresNonPublicMethods) + "(String)")] + [ExpectedWarning ("IL2072", "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicConstructors()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequireNonPublicMethods(String)" })] + nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresNonPublicMethods) + "(String)")] public static void TestBranchMergeSwitch () { string str = null; @@ -139,19 +126,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow str = GetWithPublicConstructors (); break; } - RequireNonPublicMethods (str); // warns for GetWithPublicFields, GetWithPublicMethods, and GetWithPublicConstructors + + str.RequiresNonPublicMethods (); // warns for GetWithPublicFields, GetWithPublicMethods, and GetWithPublicConstructors } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicFields(String)" })] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicFields()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicMethods(String)" })] + + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()")] public static void TestBranchMergeTry () { string str = GetWithPublicMethods (); @@ -162,20 +145,16 @@ namespace Mono.Linker.Tests.Cases.DataFlow str = GetWithPublicFields (); } catch { } - RequirePublicFields (str); // warns for GetWithPublicMethods - RequirePublicMethods (str); // warns for GetWithPublicFields + + str.RequiresPublicFields (); // warns for GetWithPublicMethods + str.RequiresPublicMethods (); // warns for GetWithPublicFields } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicFields(String)" })] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicFields()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicMethods(String)" })] + + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()")] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()")] public static void TestBranchMergeCatch () { string str = GetWithPublicMethods (); @@ -185,20 +164,17 @@ namespace Mono.Linker.Tests.Cases.DataFlow } catch { str = GetWithPublicFields (); } - RequirePublicFields (str); // warns for GetWithPublicMethods - RequirePublicMethods (str); // warns for GetWithPublicFields + + str.RequiresPublicFields (); // warns for GetWithPublicMethods + str.RequiresPublicMethods (); // warns for GetWithPublicFields } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicMethods()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicFields(String)" })] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, - messageCode: "IL2072", message: new string[] { - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.GetWithPublicFields()", - "type", - "Mono.Linker.Tests.Cases.DataFlow.LocalDataFlow.RequirePublicMethods(String)" })] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()")] + // Linker produces extraneous warnings + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchMergeFinally () { string str = GetWithPublicMethods (); @@ -209,77 +185,93 @@ namespace Mono.Linker.Tests.Cases.DataFlow } finally { str = GetWithPublicFields (); } - RequirePublicFields (str); // warns for GetWithPublicMethods - RequirePublicMethods (str); // warns for GetWithPublicFields + str.RequiresPublicFields (); // should not warn + str.RequiresPublicMethods (); // should warn } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, messageCode: "IL2072")] + // Analyzer gets this right (no warning), but trimmer merges all branches going forward. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields) + "(String)", + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchGoto () { string str = GetWithPublicMethods (); if (String.Empty.Length == 0) goto End; str = GetWithPublicFields (); - RequirePublicFields (str); // produces a warning + str.RequiresPublicFields (); // produces a warning End: return; } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, messageCode: "IL2072")] + // Analyzer gets this right (no warning), but trimmer merges all branches going forward. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchIf () { string str = GetWithPublicMethods (); if (String.Empty.Length == 0) { str = GetWithPublicFields (); // dataflow will merge this with the value from the previous basic block - RequirePublicFields (str); // produces a warning (technically it should not) + str.RequiresPublicFields (); // produces a warning (technically it should not) } } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, messageCode: "IL2072")] + // Analyzer gets this right (no warning), but trimmer merges all branches going forward. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchIfElse () { string str; if (String.Empty.Length == 0) { // because this branch *happens* to come first in IL, we will only see one value str = GetWithPublicMethods (); - RequirePublicMethods (str); // this works + str.RequiresPublicMethods (); // this works } else { // because this branch *happens* to come second in IL, we will see the merged value for str str = GetWithPublicFields (); - RequirePublicFields (str); // produces a warning + str.RequiresPublicFields (); // produces a warning } } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequireNonPublicMethods), new Type[] { typeof (string) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicMethods), new Type[] { typeof (string) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (string) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (string) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (string) }, messageCode: "IL2072")] + // Analyzer gets this right (no warning), but trimmer merges all branches going forward. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresNonPublicMethods) + "(String)", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicConstructors) + "(String)", + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchSwitch () { string str = null; switch (_switchOnField) { case 0: str = GetWithPublicFields (); - RequirePublicFields (str); // success + str.RequiresPublicFields (); // success break; case 1: str = GetWithNonPublicMethods (); - RequireNonPublicMethods (str); // warns for GetWithPublicFields + str.RequiresNonPublicMethods (); // warns for GetWithPublicFields break; case 2: str = GetWithPublicMethods (); - RequirePublicMethods (str); // warns for GetWithPublicFields and GetWithNonPublicMethods + str.RequiresPublicMethods (); // warns for GetWithPublicFields and GetWithNonPublicMethods break; case 3: str = GetWithPublicConstructors (); - RequirePublicConstructors (str); // warns for GetWithPublicFields, GetWithNonPublicMethods, GetWithPublicMethods + str.RequiresPublicConstructors (); // warns for GetWithPublicFields, GetWithNonPublicMethods, GetWithPublicMethods break; } } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, messageCode: "IL2072")] + // Analyzer gets this right (no warning), but trimmer merges all branches going forward. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchTry () { string str = GetWithPublicMethods (); @@ -288,12 +280,15 @@ namespace Mono.Linker.Tests.Cases.DataFlow throw null; str = GetWithPublicFields (); - RequirePublicFields (str); // warns for GetWithPublicMethods + str.RequiresPublicFields (); // warns for GetWithPublicMethods } catch { } } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, messageCode: "IL2072")] + // Analyzer gets this right (no warning), but trimmer merges all branches going forward. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchCatch () { string str = GetWithPublicMethods (); @@ -302,11 +297,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow throw null; } catch { str = GetWithPublicFields (); - RequirePublicFields (str); // warns for GetWithPublicMethods + str.RequiresPublicFields (); // warns for GetWithPublicMethods } } - [UnrecognizedReflectionAccessPattern (typeof (LocalDataFlow), nameof (RequirePublicFields), new Type[] { typeof (string) }, messageCode: "IL2072")] + // Analyzer gets this right (no warning), but trimmer merges all branches going forward. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicFields), + nameof (LocalDataFlow) + "." + nameof (GetWithPublicMethods) + "()", + ProducedBy = ProducedBy.Trimmer)] public static void TestBranchFinally () { string str = GetWithPublicMethods (); @@ -316,11 +314,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow } catch { } finally { str = GetWithPublicFields (); - RequirePublicFields (str); // warns for GetWithPublicMethods + str.RequiresPublicFields (); // warns for GetWithPublicMethods } } - [RecognizedReflectionAccessPattern] + // Analyzer gets this right, but linker doesn't consider backwards branches. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] public static void TestBackwardsEdgeLoop () { string str = GetWithPublicMethods (); @@ -330,17 +331,20 @@ namespace Mono.Linker.Tests.Cases.DataFlow str = GetWithPublicFields (); // dataflow will merge values to track both possible annotation kinds } - // RequirePublicMethods (str); // this would produce a warning for the value that comes from GetWithPublicFields, as expected - RequirePublicMethods (prev); // this produces no warning, even though "prev" will have the value from GetWithPublicFields! + // str.RequiresPublicMethods (); // this would produce a warning for the value that comes from GetWithPublicFields, as expected + prev.RequiresPublicMethods (); // this produces no warning, even though "prev" will have the value from GetWithPublicFields! } - [RecognizedReflectionAccessPattern] + // Analyzer gets this right, but linker doesn't consider backwards branches. + [ExpectedWarning ("IL2072", nameof (DataFlowStringExtensions) + "." + nameof (DataFlowStringExtensions.RequiresPublicMethods) + "(String)", + nameof (LocalDataFlow) + "." + nameof (GetWithPublicFields) + "()", + ProducedBy = ProducedBy.Analyzer)] public static void TestBackwardsEdgeGoto () { string str = null; goto ForwardTarget; BackwardTarget: - RequirePublicMethods (str); // should warn for the value that comes from GetWithPublicFields, but it doesn't. + str.RequiresPublicMethods (); // should warn for the value that comes from GetWithPublicFields, but it doesn't. return; ForwardTarget: @@ -357,7 +361,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow [RequiresUnreferencedCode ("message")] public static void RUCMethod () { - RequireAll (GetWithPublicMethods ()); + GetWithPublicMethods ().RequiresAll (); } [ExpectedWarning ("IL2026", nameof (RUCType) + "." + nameof (RUCType), "message")] @@ -375,49 +379,20 @@ namespace Mono.Linker.Tests.Cases.DataFlow { public static void StaticMethod () { - RequireAll (GetWithPublicMethods ()); + GetWithPublicMethods ().RequiresAll (); } public void InstanceMethod () { - RequireAll (GetWithPublicMethods ()); + GetWithPublicMethods ().RequiresAll (); } public virtual void VirtualMethod () { - RequireAll (GetWithPublicMethods ()); + GetWithPublicMethods ().RequiresAll (); } } - public static void RequireAll ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - string type) - { - } - - public static void RequirePublicFields ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - string type) - { - } - - public static void RequireNonPublicMethods ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)] - string type) - { - } - public static void RequirePublicMethods ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] - string type) - { - } - - public static void RequirePublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - string type) - { - } - [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] public static string GetWithPublicFields () { diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlowKeptMembers.cs b/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlowKeptMembers.cs index 4c3484013..8e95a6ebc 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlowKeptMembers.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/LocalDataFlowKeptMembers.cs @@ -4,6 +4,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.DataFlow { + [ExpectedNoWarnings] public class LocalDataFlowKeptMembers { public static void Main () 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 + { + } + } +} diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs index af1a2c7ee..b385a3ffe 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypes.cs @@ -12,8 +12,66 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { [SetupCompileArgument ("/optimize+")] + [ExpectedNoWarnings] public class MemberTypes { + // Some of the types below declare delegates and will mark all members on them, this includes the Delegate .ctor(object, string) which has RUC and other members + [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2026", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2026", nameof (MulticastDelegate) + ".MulticastDelegate")] + // Some of the types below declare delegates and will mark all members on them, this includes the Delegate .ctor(Type, string) which has DAM annotations and other members + [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".Delegate")] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (Delegate.CreateDelegate))] + [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2111", nameof (MulticastDelegate) + ".MulticastDelegate")] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2111", nameof (Delegate) + ".BindToMethodName", ProducedBy = ProducedBy.Trimmer)] public static void Main () { RequirePublicParameterlessConstructor (typeof (PublicParameterlessConstructorType)); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs index 8331edaea..dd9bd5cfc 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MemberTypesAllOnCopyAssembly.cs @@ -13,6 +13,8 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { + [ExpectedNoWarnings] + [SetupCompileBefore ("base.dll", new[] { "Dependencies/MemberTypesAllBaseTypeAssembly.cs" })] [KeptAssembly ("base.dll")] [SetupLinkerAction ("link", "base")] diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs index df6e2cd1e..83ded2fe9 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MethodParametersDataFlow.cs @@ -6,13 +6,15 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] + [ExpectedNoWarnings] [SetupLinkerArgument ("--keep-metadata", "parametername")] public class MethodParametersDataFlow { @@ -37,50 +39,51 @@ namespace Mono.Linker.Tests.Cases.DataFlow instance.LongWriteToParameterOnInstanceMethod (0, 0, 0, 0, null); instance.UnsupportedParameterType (null); + ParametersPassedToInstanceCtor (typeof (TestType), typeof (TestType)); + TestParameterOverwrite (typeof (TestType)); } // Validate the error message when annotated parameter is passed to another annotated parameter - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, - messageCode: "IL2067", message: new string[] { "sourceType", "PublicParameterlessConstructorParameter(Type)", "type", "RequirePublicConstructors(Type)" })] - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", "'sourceType'", "PublicParameterlessConstructorParameter(Type)", "'type'", "RequiresPublicConstructors(Type)")] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] private static void PublicParameterlessConstructorParameter ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type sourceType) { - RequirePublicParameterlessConstructor (sourceType); - RequirePublicConstructors (sourceType); - RequireNonPublicConstructors (sourceType); + sourceType.RequiresPublicParameterlessConstructor (); + sourceType.RequiresPublicConstructors (); + sourceType.RequiresNonPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] private static void PublicConstructorsParameter ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) { - RequirePublicParameterlessConstructor (type); - RequirePublicConstructors (type); - RequireNonPublicConstructors (type); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicParameterlessConstructor), new Type[] { typeof (Type) }, messageCode: "IL2067")] - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] private static void NonPublicConstructorsParameter ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) { - RequirePublicParameterlessConstructor (type); - RequirePublicConstructors (type); - RequireNonPublicConstructors (type); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] private void InstanceMethod ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type) { - RequirePublicParameterlessConstructor (type); - RequirePublicConstructors (type); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); } [ExpectedWarning ("IL2072", "'type'", "argument", nameof (WriteToParameterOnInstanceMethod) + "(Type)", nameof (ReturnThingsWithPublicParameterlessConstructor))] @@ -99,7 +102,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow type = ReturnThingsWithPublicParameterlessConstructor (); } - [ExpectedWarning ("IL2072", "'type'", "argument", nameof (LongWriteToParameterOnInstanceMethod) + "(Int32,Int32,Int32,Int32,Type)", nameof (ReturnThingsWithPublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", "'type'", "argument", nameof (LongWriteToParameterOnInstanceMethod) + "(Int32, Int32, Int32, Int32, Type)", nameof (ReturnThingsWithPublicParameterlessConstructor))] private void LongWriteToParameterOnInstanceMethod ( int a, int b, int c, int d, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] @@ -108,7 +111,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow type = ReturnThingsWithPublicParameterlessConstructor (); } - [ExpectedWarning ("IL2072", "'type'", "argument", nameof (LongWriteToParameterOnStaticMethod) + "(Int32,Int32,Int32,Int32,Type)", nameof (ReturnThingsWithPublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", "'type'", "argument", nameof (LongWriteToParameterOnStaticMethod) + "(Int32, Int32, Int32, Int32, Type)", nameof (ReturnThingsWithPublicParameterlessConstructor))] private static void LongWriteToParameterOnStaticMethod ( int a, int b, int c, int d, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] @@ -123,20 +126,24 @@ namespace Mono.Linker.Tests.Cases.DataFlow return null; } - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] private void TwoAnnotatedParameters ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type2) { - RequirePublicParameterlessConstructor (type); - RequirePublicParameterlessConstructor (type2); - RequirePublicConstructors (type); - RequirePublicConstructors (type2); + type.RequiresPublicParameterlessConstructor (); + type2.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type2.RequiresPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2067")] + // TODO: https://github.com/dotnet/linker/issues/2273 + // (Dataflow analysis is not supported by the analyzer yet) + [ExpectedWarning ("IL2067", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)", + "'type'")] private void TwoAnnotatedParametersIntoOneValue ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type, @@ -144,78 +151,73 @@ namespace Mono.Linker.Tests.Cases.DataFlow Type type2) { Type t = type == null ? type : type2; - RequirePublicParameterlessConstructor (t); - RequirePublicConstructors (t); + t.RequiresPublicParameterlessConstructor (); + t.RequiresPublicConstructors (); } // Validate the error message for the case of unannotated method return value passed to an annotated parameter. - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicParameterlessConstructor), new Type[] { typeof (Type) }, - messageCode: "IL2067", message: new string[] { "type", "NoAnnotation(Type)", "type", "RequirePublicParameterlessConstructor(Type)" })] + [ExpectedWarning ("IL2067", "'type'", "NoAnnotation(Type)", "'type'", "RequiresPublicParameterlessConstructor(Type)")] private void NoAnnotation (Type type) { - RequirePublicParameterlessConstructor (type); + type.RequiresPublicParameterlessConstructor (); } // Validate error message when untracable value is passed to an annotated parameter. - [UnrecognizedReflectionAccessPattern (typeof (MethodParametersDataFlow), nameof (RequirePublicParameterlessConstructor), new Type[] { typeof (Type) }, - messageCode: "IL2062", message: new string[] { "type", "RequirePublicParameterlessConstructor" })] + [ExpectedWarning ("IL2062", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor) + "(Type)", + "'type'", + ProducedBy = ProducedBy.Trimmer)] private void UnknownValue () { var array = new object[1]; array[0] = this.GetType (); MakeArrayValuesUnknown (array); - RequirePublicParameterlessConstructor ((Type) array[0]); + ((Type) array[0]).RequiresPublicParameterlessConstructor (); static void MakeArrayValuesUnknown (object[] array) { } } - [RecognizedReflectionAccessPattern] private void AnnotatedValueToUnAnnotatedParameter ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type) { - RequireNothing (type); + type.RequiresNone (); } - [RecognizedReflectionAccessPattern] private void UnknownValueToUnAnnotatedParameter () { - RequireNothing (this.GetType ()); + this.GetType ().RequiresNone (); } - [RecognizedReflectionAccessPattern] private void UnknownValueToUnAnnotatedParameterOnInterestingMethod () { RequirePublicParameterlessConstructorAndNothing (typeof (TestType), this.GetType ()); } - [ExpectedWarning ("IL2098", "p1", nameof (UnsupportedParameterType))] + // TODO: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2098", "p1", nameof (UnsupportedParameterType), ProducedBy = ProducedBy.Trimmer)] private void UnsupportedParameterType ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] object p1) { } - private static void RequirePublicParameterlessConstructor ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - Type type) - { - } - - private static void RequirePublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - Type type) - { - } - - private static void RequireNonPublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type) + private class InstanceCtor { + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + public InstanceCtor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) + { + type.RequiresNonPublicConstructors (); + type.RequiresPublicConstructors (); + } } - private static void RequireNothing (Type type) + [ExpectedWarning ("IL2067", "'type'")] + static void ParametersPassedToInstanceCtor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type typeWithCtors, Type typeWithNothing) { + var a1 = new InstanceCtor (typeWithCtors); // no warn + var a2 = new InstanceCtor (typeof (TestType)); // no warn + var a3 = new InstanceCtor (typeWithNothing); // warn } private static void RequirePublicParameterlessConstructorAndNothing ( diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs index 28735fd9d..1a2ee9aa3 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MethodReturnParameterDataFlow.cs @@ -12,7 +12,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] [ExpectedNoWarnings] public class MethodReturnParameterDataFlow @@ -46,8 +46,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow return typeof (TestType); } - [UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (ReturnPublicParameterlessConstructor), - new Type[] { typeof (Type), typeof (Type), typeof (Type) }, returnType: typeof (Type), messageCode: "IL2068")] + [ExpectedWarning ("IL2068", nameof (ReturnPublicParameterlessConstructor))] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ReturnPublicParameterlessConstructor ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] @@ -71,41 +70,35 @@ namespace Mono.Linker.Tests.Cases.DataFlow } } - [UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (ReturnPublicParameterlessConstructorFromUnknownType), - new Type[] { typeof (Type) }, returnType: typeof (Type), messageCode: "IL2068")] + [ExpectedWarning ("IL2068", nameof (ReturnPublicParameterlessConstructorFromUnknownType))] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ReturnPublicParameterlessConstructorFromUnknownType (Type unknownType) { return unknownType; } - [RecognizedReflectionAccessPattern] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ReturnPublicParameterlessConstructorFromConstant () { return typeof (TestType); } - [RecognizedReflectionAccessPattern] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ReturnPublicParameterlessConstructorFromNull () { return null; } - [RecognizedReflectionAccessPattern] Type ReturnTypeWithNoRequirements () { return null; } // Validate error message when insufficiently annotated value is returned from a method - [UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (ReturnPublicConstructorsFailure), - new Type[] { typeof (Type) }, returnType: typeof (Type), - messageCode: "IL2068", message: new string[] { + [ExpectedWarning ("IL2068", "publicParameterlessConstructorType", "MethodReturnParameterDataFlow.ReturnPublicConstructorsFailure", - "MethodReturnParameterDataFlow.ReturnPublicConstructorsFailure" })] + "MethodReturnParameterDataFlow.ReturnPublicConstructorsFailure")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type ReturnPublicConstructorsFailure ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] @@ -114,8 +107,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow return publicParameterlessConstructorType; } - [UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (ReturnNonPublicConstructorsFailure), - new Type[] { typeof (Type) }, returnType: typeof (Type), messageCode: "IL2068")] + [ExpectedWarning ("IL2068", nameof (ReturnNonPublicConstructorsFailure))] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type ReturnNonPublicConstructorsFailure ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] @@ -124,9 +116,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow return publicConstructorsType; } - [UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (ReturnUnknownValue), - new Type[] { }, returnType: typeof (Type), - messageCode: "IL2063", message: new string[] { nameof (ReturnUnknownValue) })] + // TODO: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2063", + nameof (MethodReturnParameterDataFlow) + "." + nameof (ReturnUnknownValue) + "()", + ProducedBy = ProducedBy.Trimmer)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type ReturnUnknownValue () { @@ -140,8 +133,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow } } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)", + nameof (MethodReturnParameterDataFlow) + "." + nameof (ReturnPublicParameterlessConstructor) + "(Type, Type, Type)")] + [ExpectedWarning ("IL2072", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)", + nameof (MethodReturnParameterDataFlow) + "." + nameof (ReturnPublicParameterlessConstructor) + "(Type, Type, Type)")] void PropagateReturnPublicParameterlessConstructor () { Type t = ReturnPublicParameterlessConstructor (typeof (TestType), typeof (TestType), typeof (TestType)); @@ -151,8 +148,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow t.RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)", + nameof (MethodReturnParameterDataFlow) + "." + nameof (ReturnPublicParameterlessConstructorFromConstant) + "()")] + [ExpectedWarning ("IL2072", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)", + nameof (MethodReturnParameterDataFlow) + "." + nameof (ReturnPublicParameterlessConstructorFromConstant) + "()")] void PropagateReturnPublicParameterlessConstructorFromConstant () { Type t = ReturnPublicParameterlessConstructorFromConstant (); @@ -162,11 +163,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow t.RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (PropagateReturnToReturn), new Type[] { typeof (int) }, returnType: typeof (Type), - messageCode: "IL2073", message: new string[] { + [ExpectedWarning ("IL2073", nameof (ReturnTypeWithNoRequirements), - nameof (PropagateReturnToReturn) - })] + nameof (PropagateReturnToReturn))] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type PropagateReturnToReturn (int n) { @@ -180,17 +179,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow return null; } - // https://github.com/dotnet/linker/issues/2025 - // Ideally this should not warn - [UnrecognizedReflectionAccessPattern (typeof (MethodReturnParameterDataFlow), nameof (ReturnWithRequirementsAlwaysThrows), new Type[] { }, returnType: typeof (Type), - messageCode: "IL2063")] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type ReturnWithRequirementsAlwaysThrows () { throw new NotImplementedException (); } - [ExpectedWarning ("IL2106", nameof (UnsupportedReturnType))] + // TODO: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2106", nameof (UnsupportedReturnType), ProducedBy = ProducedBy.Trimmer)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] static object UnsupportedReturnType () => null; diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs index 5ca8b3181..6a7e8321a 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/MethodThisDataFlow.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; @@ -14,6 +14,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow { [SkipKeptItemsValidation] [SandboxDependency ("Dependencies/TestSystemTypeBase.cs")] + [ExpectedNoWarnings] public class MethodThisDataFlow { public static void Main () @@ -32,11 +33,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow TestFromGenericParameterToThis<MethodThisDataFlow> (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods), new Type[] { }, - messageCode: "IL2075", message: new string[] { + [ExpectedWarning ("IL2075", "Mono.Linker.Tests.Cases.DataFlow.MethodThisDataFlow.GetWithNonPublicMethods()", - "System.MethodThisDataFlowTypeTest.RequireThisPublicMethods()" })] - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods), new Type[] { }, messageCode: "IL2075")] + "System.MethodThisDataFlowTypeTest.RequireThisPublicMethods()")] + [ExpectedWarning ("IL2075", nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods))] static void PropagateToThis () { GetWithPublicMethods ().RequireThisPublicMethods (); @@ -46,11 +46,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow GetWithNonPublicMethods ().RequireThisNonPublicMethods (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.PropertyRequireThisPublicMethods) + ".get", new Type[] { }, - messageCode: "IL2075", message: new string[] { + [ExpectedWarning ("IL2075", "Mono.Linker.Tests.Cases.DataFlow.MethodThisDataFlow.GetWithNonPublicMethods()", - "System.MethodThisDataFlowTypeTest.PropertyRequireThisPublicMethods.get" })] - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.PropertyRequireThisNonPublicMethods) + ".get", new Type[] { }, messageCode: "IL2075")] + "System.MethodThisDataFlowTypeTest.PropertyRequireThisPublicMethods.get")] + [ExpectedWarning ("IL2075", nameof (MethodThisDataFlowTypeTest.PropertyRequireThisNonPublicMethods) + ".get")] static void PropagateToThisWithGetters () { _ = GetWithPublicMethods ().PropertyRequireThisPublicMethods; @@ -60,11 +59,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow _ = GetWithNonPublicMethods ().PropertyRequireThisNonPublicMethods; } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.PropertyRequireThisPublicMethods) + ".set", new Type[] { typeof (Object) }, - messageCode: "IL2075", message: new string[] { + [ExpectedWarning ("IL2075", "Mono.Linker.Tests.Cases.DataFlow.MethodThisDataFlow.GetWithNonPublicMethods()", - "System.MethodThisDataFlowTypeTest.PropertyRequireThisPublicMethods.set" })] - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.PropertyRequireThisNonPublicMethods) + ".set", new Type[] { typeof (Object) }, messageCode: "IL2075")] + "System.MethodThisDataFlowTypeTest.PropertyRequireThisPublicMethods.set")] + [ExpectedWarning ("IL2075", nameof (MethodThisDataFlowTypeTest.PropertyRequireThisNonPublicMethods) + ".set")] static void PropagateToThisWithSetters () { GetWithPublicMethods ().PropertyRequireThisPublicMethods = null; @@ -85,7 +83,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow return null; } - [RecognizedReflectionAccessPattern] static void TestAnnotationOnNonTypeMethod () { var t = new NonTypeType (); @@ -93,8 +90,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow NonTypeType.StaticMethod (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods), new Type[] { }, - messageCode: "IL2065", message: new string[] { nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods) })] + // Analyer doesn't warn about unknown values flowing into annotated locations + // https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2065", nameof (MethodThisDataFlowTypeTest) + "." + nameof (MethodThisDataFlowTypeTest.RequireThisNonPublicMethods), "'this'", + ProducedBy = ProducedBy.Trimmer)] static void TestUnknownThis () { var array = new object[1]; @@ -107,8 +106,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow } } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods), new Type[] { }, - messageCode: "IL2070", message: new string[] { "sourceType", nameof (TestFromParameterToThis), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods) })] + [ExpectedWarning ("IL2070", "sourceType", nameof (TestFromParameterToThis), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods))] static void TestFromParameterToThis (MethodThisDataFlowTypeTest sourceType) { sourceType.RequireThisPublicMethods (); @@ -116,19 +114,16 @@ namespace Mono.Linker.Tests.Cases.DataFlow static MethodThisDataFlowTypeTest _typeField; - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods), new Type[] { }, - messageCode: "IL2080", message: new string[] { nameof (_typeField), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods) })] + [ExpectedWarning ("IL2080", nameof (_typeField), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods))] static void TestFromFieldToThis () { _typeField.RequireThisPublicMethods (); } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods), new Type[] { }, - messageCode: "IL2090", message: new string[] { + [ExpectedWarning ("IL2090", "TSource", "TestFromGenericParameterToThis<TSource>", - nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods) - })] + nameof (MethodThisDataFlowTypeTest.RequireThisPublicMethods))] static void TestFromGenericParameterToThis<TSource> () { ((MethodThisDataFlowTypeTest) typeof (TSource)).RequireThisPublicMethods (); @@ -143,14 +138,18 @@ namespace Mono.Linker.Tests.Cases.DataFlow class NonTypeType { - [ExpectedWarning ("IL2041")] + // Analyzer doesn't warn about annotations on unsupported types: + // https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2041", ProducedBy = ProducedBy.Trimmer)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public MethodInfo GetMethod (string name) { return null; } - [ExpectedWarning ("IL2041")] + // Analyzer doesn't warn about annotations on unsupported types: + // https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2041", ProducedBy = ProducedBy.Trimmer)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public static void StaticMethod () { @@ -164,10 +163,9 @@ namespace System class MethodThisDataFlowTypeTest : TestSystemTypeBase { [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (RequireNonPublicMethods), new Type[] { typeof (Type) }, - messageCode: "IL2082", message: new string[] { - "'type' argument ", "in call to 'System.MethodThisDataFlowTypeTest.RequireNonPublicMethods(Type)'", - "implicit 'this' argument of method 'System.MethodThisDataFlowTypeTest.RequireThisPublicMethods()'" })] + [ExpectedWarning ("IL2082", nameof (MethodThisDataFlowTypeTest) + "." + nameof (RequireNonPublicMethods) + "(Type)", + "'type' argument ", "in call to 'System.MethodThisDataFlowTypeTest.RequireNonPublicMethods(Type)'", + "implicit 'this' argument of method 'System.MethodThisDataFlowTypeTest.RequireThisPublicMethods()'")] public void RequireThisPublicMethods () { RequirePublicMethods (this); @@ -175,19 +173,16 @@ namespace System } [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (RequirePublicMethods), new Type[] { typeof (Type) }, - messageCode: "IL2082")] + [ExpectedWarning ("IL2082", nameof (MethodThisDataFlowTypeTest) + "." + nameof (RequirePublicMethods) + "(Type)")] public void RequireThisNonPublicMethods () { RequirePublicMethods (this); RequireNonPublicMethods (this); } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (PropagateToReturn), new Type[] { }, returnType: typeof (Type), - messageCode: "IL2083", message: new string[] { - nameof(PropagateToReturn), - nameof(PropagateToReturn) - })] + [ExpectedWarning ("IL2083", + nameof (PropagateToReturn), + nameof (PropagateToReturn))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] public Type PropagateToReturn () @@ -198,22 +193,17 @@ namespace System [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type _requiresPublicConstructors; - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (_requiresPublicConstructors), - messageCode: "IL2084", message: new string[] { - nameof (PropagateToField), - nameof (_requiresPublicConstructors) - })] + [ExpectedWarning ("IL2084", nameof (MethodThisDataFlowTypeTest) + "." + nameof (_requiresPublicConstructors), + nameof (PropagateToField))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public void PropagateToField () { _requiresPublicConstructors = this; } - [UnrecognizedReflectionAccessPattern (typeof (MethodThisDataFlowTypeTest), nameof (RequireThisNonPublicMethods), new Type[] { }, - messageCode: "IL2085", message: new string[] { + [ExpectedWarning ("IL2085", nameof (PropagateToThis), - nameof (RequireThisNonPublicMethods) - })] + nameof (RequireThisNonPublicMethods))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] public void PropagateToThis () { diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs index d1f6d57eb..4f2f329c9 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/PropertyDataFlow.cs @@ -10,8 +10,9 @@ using Mono.Linker.Tests.Cases.Expectations.Helpers; namespace Mono.Linker.Tests.Cases.DataFlow { // Note: this test's goal is to validate that the product correctly reports unrecognized patterns - // - so the main validation is done by the UnrecognizedReflectionAccessPattern attributes. + // - so the main validation is done by the ExpectedWarning attributes. [SkipKeptItemsValidation] + [ExpectedNoWarnings] public class PropertyDataFlow { public static void Main () @@ -42,11 +43,13 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] static Type StaticPropertyWithPublicConstructor { get; set; } - [ExpectedWarning ("IL2099", nameof (PropertyWithUnsupportedType))] + // Analyzer doesn't warn about annotations on unsupported types + // https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2099", nameof (PropertyWithUnsupportedType), ProducedBy = ProducedBy.Trimmer)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] static object PropertyWithUnsupportedType { get; set; } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] private void ReadFromInstanceProperty () { PropertyWithPublicConstructor.RequiresPublicParameterlessConstructor (); @@ -55,7 +58,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow PropertyWithPublicConstructor.RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] private void ReadFromStaticProperty () { StaticPropertyWithPublicConstructor.RequiresPublicParameterlessConstructor (); @@ -64,9 +67,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow StaticPropertyWithPublicConstructor.RequiresNone (); } - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (PropertyWithPublicConstructor) + ".set", new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (PropertyWithPublicConstructor) + ".set", new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (PropertyWithPublicConstructor) + ".set", new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (PropertyDataFlow) + "." + nameof (PropertyWithPublicConstructor) + ".set", nameof (GetTypeWithPublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", nameof (PropertyDataFlow) + "." + nameof (PropertyWithPublicConstructor) + ".set", nameof (GetTypeWithNonPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (PropertyDataFlow) + "." + nameof (PropertyWithPublicConstructor) + ".set", nameof (GetUnkownType))] private void WriteToInstanceProperty () { PropertyWithPublicConstructor = GetTypeWithPublicParameterlessConstructor (); @@ -75,9 +78,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow PropertyWithPublicConstructor = GetUnkownType (); } - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (StaticPropertyWithPublicConstructor) + ".set", new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (StaticPropertyWithPublicConstructor) + ".set", new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (StaticPropertyWithPublicConstructor) + ".set", new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (PropertyDataFlow) + "." + nameof (StaticPropertyWithPublicConstructor) + ".set", nameof (GetTypeWithPublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", nameof (PropertyDataFlow) + "." + nameof (StaticPropertyWithPublicConstructor) + ".set", nameof (GetTypeWithNonPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (PropertyDataFlow) + "." + nameof (StaticPropertyWithPublicConstructor) + ".set", nameof (GetUnkownType))] private void WriteToStaticProperty () { StaticPropertyWithPublicConstructor = GetTypeWithPublicParameterlessConstructor (); @@ -90,13 +93,11 @@ namespace Mono.Linker.Tests.Cases.DataFlow Type _fieldWithPublicConstructors; Type PropertyPublicConstructorsWithExplicitAccessors { - [RecognizedReflectionAccessPattern] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] get { return _fieldWithPublicConstructors; } - [RecognizedReflectionAccessPattern] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] set { _fieldWithPublicConstructors = value; @@ -104,14 +105,14 @@ namespace Mono.Linker.Tests.Cases.DataFlow } Type PropertyPublicParameterlessConstructorWithExplicitAccessors { - [RecognizedReflectionAccessPattern] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] get { return _fieldWithPublicConstructors; } - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (_fieldWithPublicConstructors), - messageCode: "IL2069", message: new string[] { "value", nameof (PropertyPublicParameterlessConstructorWithExplicitAccessors) + ".set", nameof (_fieldWithPublicConstructors) })] + [ExpectedWarning ("IL2069", nameof (PropertyDataFlow) + "." + nameof (_fieldWithPublicConstructors), + "'value'", + nameof (PropertyPublicParameterlessConstructorWithExplicitAccessors) + ".set")] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] set { _fieldWithPublicConstructors = value; @@ -119,17 +120,16 @@ namespace Mono.Linker.Tests.Cases.DataFlow } Type PropertyNonPublicConstructorsWithExplicitAccessors { - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (PropertyNonPublicConstructorsWithExplicitAccessors) + ".get", - new Type[] { }, returnType: typeof (Type), messageCode: "IL2078", message: new string[] { - nameof (_fieldWithPublicConstructors), - nameof (PropertyNonPublicConstructorsWithExplicitAccessors) + ".get" - })] + [ExpectedWarning ("IL2078", nameof (PropertyDataFlow) + "." + nameof (PropertyNonPublicConstructorsWithExplicitAccessors) + ".get", + nameof (_fieldWithPublicConstructors))] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] get { return _fieldWithPublicConstructors; } - [UnrecognizedReflectionAccessPattern (typeof (PropertyDataFlow), nameof (_fieldWithPublicConstructors), messageCode: "IL2069")] + [ExpectedWarning ("IL2069", nameof (PropertyDataFlow) + "." + nameof (_fieldWithPublicConstructors), + "'value'", + nameof (PropertyNonPublicConstructorsWithExplicitAccessors) + ".set")] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] set { _fieldWithPublicConstructors = value; @@ -145,6 +145,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow instance.TestInstancePropertyWithStaticField (); instance.TestPropertyWithDifferentBackingFields (); instance.TestPropertyWithExistingAttributes (); + instance.TestPropertyWithConflictingAttributes (); + instance.TestPropertyWithConflictingNoneAttributes (); instance.TestPropertyWithIndexerWithMatchingAnnotations (null); instance.TestPropertyWithIndexerWithoutMatchingAnnotations (null); } @@ -152,7 +154,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow class TestAutomaticPropagationType { // Fully implicit property should work - [UnrecognizedReflectionAccessPattern (typeof (TestAutomaticPropagationType), nameof (ImplicitProperty) + ".set", new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (ImplicitProperty) + ".set")] public void TestImplicitProperty () { ImplicitProperty.RequiresPublicConstructors (); @@ -165,7 +167,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow } // Simple getter is not enough - we do detect the field, but we require the field to be compiler generated for this to work - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] // Make sure we don't warn about the field in context of property annotation propagation. [LogDoesNotContain ("Could not find a unique backing field for property 'System.Type Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow/TestAutomaticPropagationType::PropertyWithSimpleGetter()'")] public void TestPropertyWithSimpleGetter () @@ -178,13 +180,16 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] static Type PropertyWithSimpleGetter { - [UnrecognizedReflectionAccessPattern (typeof (TestAutomaticPropagationType), nameof (PropertyWithSimpleGetter) + ".get", new Type[] { }, returnType: typeof (Type), messageCode: "IL2078")] + [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithSimpleGetter) + ".get")] get { return PropertyWithSimpleGetter_Field; } } - [RecognizedReflectionAccessPattern] + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)", + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field), + ProducedBy = ProducedBy.Analyzer)] public void TestPropertyWhichLooksLikeCompilerGenerated () { // If the property was correctly recognized both the property getter and the backing field should get the annotation. @@ -197,12 +202,16 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] static Type PropertyWhichLooksLikeCompilerGenerated { + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated) + ".get", + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWhichLooksLikeCompilerGenerated_Field), + ProducedBy = ProducedBy.Analyzer)] get { return PropertyWhichLooksLikeCompilerGenerated_Field; } } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] // Make sure we don't warn about the field in context of property annotation propagation. [LogDoesNotContain ("Could not find a unique backing field for property 'System.Type Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow/TestAutomaticPropagationType::InstancePropertyWithStaticField()'")] public void TestInstancePropertyWithStaticField () @@ -218,7 +227,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow Type InstancePropertyWithStaticField { // Nothing to warn about - the "value" is annotated with PublicConstructors and we're assigning // it to unannotated field - that's a perfectly valid operation. - [RecognizedReflectionAccessPattern] set { InstancePropertyWithStaticField_Field = value; } @@ -235,10 +243,19 @@ namespace Mono.Linker.Tests.Cases.DataFlow [CompilerGenerated] private Type PropertyWithDifferentBackingFields_SetterField; + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 [ExpectedWarning ("IL2042", - "Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithDifferentBackingFields")] + "Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithDifferentBackingFields", + ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2078", + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get", + "Type", + ProducedBy = ProducedBy.Analyzer)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type PropertyWithDifferentBackingFields { + [ExpectedWarning ("IL2078", + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithDifferentBackingFields) + ".get", + ProducedBy = ProducedBy.Trimmer)] get { return PropertyWithDifferentBackingFields_GetterField; } @@ -254,23 +271,95 @@ namespace Mono.Linker.Tests.Cases.DataFlow PropertyWithExistingAttributes = null; } - [ExpectedWarning ("IL2056", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes_Field")] + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2056", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes_Field", + ProducedBy = ProducedBy.Trimmer)] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] [CompilerGenerated] Type PropertyWithExistingAttributes_Field; [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type PropertyWithExistingAttributes { - [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get")] + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.get", + ProducedBy = ProducedBy.Trimmer)] [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] get { return PropertyWithExistingAttributes_Field; } - [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set")] + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2043", "PropertyWithExistingAttributes", "PropertyWithExistingAttributes.set", + ProducedBy = ProducedBy.Trimmer)] [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] set { PropertyWithExistingAttributes_Field = value; } } - [RecognizedReflectionAccessPattern] + // When the property annotation conflicts with the getter/setter annotation, + // we issue a warning (IL2043 below) but respect the getter/setter annotations. + [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingAttributes) + ".get", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors) + "(Type)")] + [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingAttributes) + ".set", + nameof (PropertyDataFlow) + "." + nameof (GetTypeWithPublicConstructors) + "()")] + public void TestPropertyWithConflictingAttributes () + { + PropertyWithConflictingAttributes.RequiresPublicConstructors (); + PropertyWithConflictingAttributes.RequiresNonPublicConstructors (); + PropertyWithConflictingAttributes = GetTypeWithPublicConstructors (); + PropertyWithConflictingAttributes = GetTypeWithNonPublicConstructors (); + } + + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2056", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes_Field", + ProducedBy = ProducedBy.Trimmer)] + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] + [CompilerGenerated] + Type PropertyWithConflictingAttributes_Field; + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + Type PropertyWithConflictingAttributes { + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.get", + ProducedBy = ProducedBy.Trimmer)] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] + get { return PropertyWithConflictingAttributes_Field; } + + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2043", "PropertyWithConflictingAttributes", "PropertyWithConflictingAttributes.set", + ProducedBy = ProducedBy.Trimmer)] + [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] + set { PropertyWithConflictingAttributes_Field = value; } + } + + // When the property annotation is DAMT.None and this conflicts with the getter/setter annotations, + // we don't produce a warning about the conflict, and just respect the property annotations. + [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes) + ".get", + nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)")] + [ExpectedWarning ("IL2072", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes) + ".set", + nameof (PropertyDataFlow) + "." + nameof (GetTypeWithNonPublicConstructors) + "()")] + public void TestPropertyWithConflictingNoneAttributes () + { + PropertyWithConflictingNoneAttributes.RequiresPublicConstructors (); + PropertyWithConflictingNoneAttributes.RequiresNonPublicConstructors (); + PropertyWithConflictingNoneAttributes = GetTypeWithPublicConstructors (); + PropertyWithConflictingNoneAttributes = GetTypeWithNonPublicConstructors (); + } + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.None)] + [CompilerGenerated] + Type PropertyWithConflictingNoneAttributes_Field; + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + Type PropertyWithConflictingNoneAttributes { + // Analyzer doesn't try to detect backing fields of properties: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2078", nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes) + ".get", + nameof (TestAutomaticPropagationType) + "." + nameof (PropertyWithConflictingNoneAttributes_Field), + ProducedBy = ProducedBy.Analyzer)] + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.None)] + get { return PropertyWithConflictingNoneAttributes_Field; } + + [param: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.None)] + set { PropertyWithConflictingNoneAttributes_Field = value; } + } + public void TestPropertyWithIndexerWithMatchingAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type myType) { var propclass = new PropertyWithIndexer (); @@ -278,8 +367,10 @@ namespace Mono.Linker.Tests.Cases.DataFlow propclass[1].RequiresPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (PropertyWithIndexer), "Item.set", new Type[] { typeof (Type) }, messageCode: "IL2067")] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), "RequiresNonPublicConstructors", new Type[] { typeof (Type) }, messageCode: "IL2072")] + // Trimmer and analyzer handle formatting of indexers differently. + [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".Item.set", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2067", nameof (PropertyWithIndexer) + ".this[Int32].set", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors) + "(Type)")] [LogDoesNotContain ("'Value passed to parameter 'index' of method 'Mono.Linker.Tests.Cases.DataFlow.PropertyDataFlow.TestAutomaticPropagationType.PropertyWithIndexer.Item.set'")] public void TestPropertyWithIndexerWithoutMatchingAnnotations (Type myType) { @@ -295,7 +386,9 @@ namespace Mono.Linker.Tests.Cases.DataFlow [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] public Type this[int index] { - [ExpectedWarning ("IL2063", "PropertyWithIndexer.Item.get")] + // TODO: warn about unknown types in analyzer: https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2063", "PropertyWithIndexer.Item.get", + ProducedBy = ProducedBy.Trimmer)] get => Property_Field[index]; set => Property_Field[index] = value; } diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.cs b/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.cs index bb890ae64..5210ab617 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.cs @@ -13,6 +13,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow [SkipKeptItemsValidation] [SetupLinkAttributesFile ("SuppressWarningWithLinkAttributes.xml")] [LogDoesNotContain ("Trim analysis warning IL2067: Mono.Linker.Tests.Cases.DataFlow.SuppressWarningWithLinkAttributes::ReadFromInstanceField()")] + [ExpectedWarning ("IL2031", "System.DoesNotExistAttribute", FileName = "SuppressWarningWithLinkAttributes.xml")] + [ExpectedNoWarnings] class SuppressWarningWithLinkAttributes { public static void Main () @@ -26,9 +28,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow Type PropertyWithPublicParameterlessConstructor { get; set; } - [UnrecognizedReflectionAccessPattern (typeof (SuppressWarningWithLinkAttributes), nameof (RequirePublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] - [UnrecognizedReflectionAccessPattern (typeof (SuppressWarningWithLinkAttributes), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) }, messageCode: "IL2077")] - [RecognizedReflectionAccessPattern] + [ExpectedWarning ("IL2077", nameof (SuppressWarningWithLinkAttributes) + "." + nameof (RequirePublicConstructors))] + [ExpectedWarning ("IL2077", nameof (SuppressWarningWithLinkAttributes) + "." + nameof (RequireNonPublicConstructors))] private void ReadFromInstanceField () { RequirePublicParameterlessConstructor (_typeWithPublicParameterlessConstructor); diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.xml b/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.xml index 699a05d5a..40844528f 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.xml +++ b/test/Mono.Linker.Tests.Cases/DataFlow/SuppressWarningWithLinkAttributes.xml @@ -7,7 +7,7 @@ </attribute> <type fullname="Mono.Linker.Tests.Cases.DataFlow.SuppressWarningWithLinkAttributes"> <field name="_typeWithPublicParameterlessConstructor"> - <attribute fullname="System.DoesNotExistattribute" assembly="Mono.Linker.Tests.Cases.Expectations"> + <attribute fullname="System.DoesNotExistAttribute" assembly="Mono.Linker.Tests.Cases.Expectations"> <argument>0</argument> </attribute> <attribute fullname="System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute"> diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs index 68d232252..0667498f6 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/TypeBaseTypeDataFlow.cs @@ -13,6 +13,7 @@ using Mono.Linker.Tests.Cases.Expectations.Helpers; namespace Mono.Linker.Tests.Cases.DataFlow { [SkipKeptItemsValidation] + [ExpectedNoWarnings] public class TypeBaseTypeDataFlow { public static void Main () @@ -47,22 +48,19 @@ namespace Mono.Linker.Tests.Cases.DataFlow Mixed_Derived.Test (typeof (TestType), 0); } - [RecognizedReflectionAccessPattern] static void TestAllPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type derivedType) { derivedType.BaseType.RequiresAll (); } - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicConstructors), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] static void TestPublicConstructorsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type derivedType) { derivedType.BaseType.RequiresPublicConstructors (); } - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicEvents), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicEvents))] static void TestPublicEventsPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] Type derivedType) { derivedType.BaseType.RequiresPublicEvents (); @@ -74,9 +72,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow derivedType.BaseType.RequiresNonPublicEvents (); } - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicFields), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicFields))] static void TestPublicFieldsPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type derivedType) { derivedType.BaseType.RequiresPublicFields (); @@ -88,9 +85,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow derivedType.BaseType.RequiresNonPublicFields (); } - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicProperties), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicMethods), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicProperties))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicMethods))] static void TestPublicMethodsPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type derivedType) { derivedType.BaseType.RequiresPublicMethods (); @@ -102,23 +98,20 @@ namespace Mono.Linker.Tests.Cases.DataFlow derivedType.BaseType.RequiresNonPublicMethods (); } - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes))] static void TestPublicNestedTypesAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type derivedType) { derivedType.BaseType.RequiresPublicNestedTypes (); } - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor))] static void TestPublicParameterlessConstructorIsNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type derivedType) { derivedType.BaseType.RequiresPublicParameterlessConstructor (); } - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicProperties), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicProperties))] static void TestPublicPropertiesPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type derivedType) { derivedType.BaseType.RequiresPublicProperties (); @@ -130,49 +123,47 @@ namespace Mono.Linker.Tests.Cases.DataFlow derivedType.BaseType.RequiresNonPublicProperties (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] static void TestNonPublicConstructorsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type derivedType) { derivedType.BaseType.RequiresNonPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicEvents), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicEvents))] static void TestNonPublicEventsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] Type derivedType) { derivedType.BaseType.RequiresNonPublicEvents (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicFields), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicFields))] static void TestNonPublicFieldsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] Type derivedType) { derivedType.BaseType.RequiresNonPublicFields (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicMethods), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicMethods))] static void TestNonPublicMethodsAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] Type derivedType) { derivedType.BaseType.RequiresNonPublicMethods (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes))] static void TestNonPublicNestedTypesAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] Type derivedType) { derivedType.BaseType.RequiresNonPublicNestedTypes (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicProperties), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicProperties))] static void TestNonPublicPropertiesAreNotPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] Type derivedType) { derivedType.BaseType.RequiresNonPublicProperties (); } - [RecognizedReflectionAccessPattern] static void TestInterfacesPropagated ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type derivedType) { derivedType.BaseType.RequiresInterfaces (); } - [RecognizedReflectionAccessPattern] static void TestCombinationOfPublicsIsPropagated ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicProperties)] Type derivedType) { @@ -180,8 +171,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow derivedType.BaseType.RequiresPublicProperties (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicMethods), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicProperties), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicMethods))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicProperties))] static void TestCombinationOfNonPublicsIsNotPropagated ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type derivedType) { @@ -189,7 +180,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow derivedType.BaseType.RequiresNonPublicProperties (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresNonPublicMethods), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicMethods))] static void TestCombinationOfPublicAndNonPublicsPropagatesPublicOnly ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicProperties)] Type derivedType) { @@ -197,13 +188,13 @@ namespace Mono.Linker.Tests.Cases.DataFlow derivedType.BaseType.RequiresPublicProperties (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] static void TestNoAnnotation (Type derivedType) { derivedType.BaseType.RequiresPublicMethods (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] static void TestAnnotatedAndUnannotated ( Type derivedTypeOne, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type derivedTypeTwo, @@ -213,7 +204,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow type.BaseType.RequiresPublicMethods (); } - [UnrecognizedReflectionAccessPattern (typeof (DataFlowTypeExtensions), nameof (DataFlowTypeExtensions.RequiresPublicMethods), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicMethods))] static void TestNull () { Type type = null; @@ -228,7 +219,6 @@ namespace Mono.Linker.Tests.Cases.DataFlow class Mixed_Derived : Mixed_Base { - [RecognizedReflectionAccessPattern] public static void Test ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type typeWithPublicMethods, int number) diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoAsTypeDataFlow.cs b/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoAsTypeDataFlow.cs new file mode 100644 index 000000000..d41bcf284 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/DataFlow/TypeInfoAsTypeDataFlow.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class TypeInfoAsTypeDataFlow + { + public static void Main () + { + TestNoAnnotations (typeof (TestType).GetTypeInfo ()); + TestWithAnnotations (typeof (TestType).GetTypeInfo ()); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + static void TestNoAnnotations (TypeInfo t) + { + t.AsType ().RequiresPublicMethods (); + t.AsType ().RequiresNone (); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + static void TestWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TypeInfo t) + { + t.AsType ().RequiresPublicMethods (); + t.AsType ().RequiresPublicFields (); + t.AsType ().RequiresNone (); + } + + class TestType { } + } +} diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs b/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs index e65c0e48c..de6707416 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/UnresolvedMembers.cs @@ -15,6 +15,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow [SkipPeVerify] [SetupLinkerArgument ("--skip-unresolved", "true")] [SetupCompileBefore ("UnresolvedLibrary.dll", new[] { "Dependencies/UnresolvedLibrary.cs" }, removeFromLinkerInput: true)] + [ExpectedNoWarnings] class UnresolvedMembers { public static void Main () @@ -42,7 +43,8 @@ namespace Mono.Linker.Tests.Cases.DataFlow { } [Kept] - [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument")] + [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument")] // Local variable type + [ExpectedWarning ("IL2066", "TypeWithUnresolvedGenericArgument")] // Called method declaring type [ExpectedWarning ("IL2066", nameof (MethodWithUnresolvedGenericArgument))] static void UnresolvedGenericArgument () { diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs b/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs index 6d85a8ed4..10b069543 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/VirtualMethodHierarchyDataflowAnnotationValidation.cs @@ -16,8 +16,12 @@ namespace Mono.Linker.Tests.Cases.DataFlow // Suppress warnings about accessing methods with annotations via reflection - the test below does that a LOT // (The test accessed these methods through DynamicallyAccessedMembers annotations which is effectively the same reflection access) [UnconditionalSuppressMessage ("test", "IL2111")] + + [ExpectedNoWarnings] class VirtualMethodHierarchyDataflowAnnotationValidation { + // The code below marks methods which have RUC on them, it's not the point of this test to validate these here + [UnconditionalSuppressMessage ("test", "IL2026")] public static void Main () { // The test uses data flow annotation to mark all public methods on the specified types diff --git a/test/Mono.Linker.Tests.Cases/DataFlow/XmlAnnotations.cs b/test/Mono.Linker.Tests.Cases/DataFlow/XmlAnnotations.cs index ec0c5a0c8..dc3c69ad5 100644 --- a/test/Mono.Linker.Tests.Cases/DataFlow/XmlAnnotations.cs +++ b/test/Mono.Linker.Tests.Cases/DataFlow/XmlAnnotations.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.DataFlow @@ -14,6 +15,7 @@ namespace Mono.Linker.Tests.Cases.DataFlow [SetupLinkAttributesFile ("XmlAnnotations.xml")] [ExpectedWarning ("IL2031", "Attribute type 'System.DoesNotExistAttribute' could not be found", FileName = "XmlAnnotations.xml")] [LogDoesNotContain ("IL2067: Mono.Linker.Tests.Cases.DataFlow.XmlAnnotations.ReadFromInstanceField():*", true)] + [ExpectedNoWarnings] class XmlAnnotations { public static void Main () @@ -36,77 +38,55 @@ namespace Mono.Linker.Tests.Cases.DataFlow Type PropertyWithPublicParameterlessConstructor { get; set; } - [UnrecognizedReflectionAccessPattern (typeof (XmlAnnotations), nameof (RequirePublicConstructors), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (XmlAnnotations), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) })] - [RecognizedReflectionAccessPattern] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] private void ReadFromInstanceField () { - RequirePublicParameterlessConstructor (_typeWithPublicParameterlessConstructor); - RequirePublicConstructors (_typeWithPublicParameterlessConstructor); - RequireNonPublicConstructors (_typeWithPublicParameterlessConstructor); + _typeWithPublicParameterlessConstructor.RequiresPublicParameterlessConstructor (); + _typeWithPublicParameterlessConstructor.RequiresPublicConstructors (); + _typeWithPublicParameterlessConstructor.RequiresNonPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (XmlAnnotations), nameof (RequirePublicConstructors), new Type[] { typeof (Type) })] - [RecognizedReflectionAccessPattern] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] private void TwoAnnotatedParameters ( Type type, Type type2) { - RequirePublicParameterlessConstructor (type); - RequirePublicParameterlessConstructor (type2); - RequirePublicConstructors (type); - RequirePublicConstructors (type2); + type.RequiresPublicParameterlessConstructor (); + type2.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type2.RequiresPublicConstructors (); } - [UnrecognizedReflectionAccessPattern (typeof (XmlAnnotations), nameof (RequirePublicParameterlessConstructor), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor))] private void SpacesBetweenParametersWrongArgument ( Type type, bool nonused) { - RequirePublicParameterlessConstructor (type); + type.RequiresPublicParameterlessConstructor (); } - [RecognizedReflectionAccessPattern] private void GenericMethod<T> ( T input, Type type) { - RequirePublicParameterlessConstructor (type); + type.RequiresPublicParameterlessConstructor (); } - [UnrecognizedReflectionAccessPattern (typeof (XmlAnnotations), nameof (ReturnConstructorsFailure), new Type[] { typeof (Type) }, - returnType: typeof (Type))] + [ExpectedWarning ("IL2068", nameof (XmlAnnotations) + "." + nameof (ReturnConstructorsFailure))] private Type ReturnConstructorsFailure ( Type publicParameterlessConstructorType) { return publicParameterlessConstructorType; } - [UnrecognizedReflectionAccessPattern (typeof (XmlAnnotations), nameof (RequirePublicConstructors), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (XmlAnnotations), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) })] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] private void ReadFromInstanceProperty () { - RequirePublicParameterlessConstructor (PropertyWithPublicParameterlessConstructor); - RequirePublicConstructors (PropertyWithPublicParameterlessConstructor); - RequireNonPublicConstructors (PropertyWithPublicParameterlessConstructor); - } - - private static void RequirePublicParameterlessConstructor ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - Type type) - { - } - - private static void RequirePublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - Type type) - { - } - - private static void RequireNonPublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type) - { + PropertyWithPublicParameterlessConstructor.RequiresPublicParameterlessConstructor (); + PropertyWithPublicParameterlessConstructor.RequiresPublicConstructors (); + PropertyWithPublicParameterlessConstructor.RequiresNonPublicConstructors (); } class TestType { } @@ -115,32 +95,13 @@ namespace Mono.Linker.Tests.Cases.DataFlow { Type _typeWithPublicParameterlessConstructor; - [UnrecognizedReflectionAccessPattern (typeof (NestedType), nameof (RequirePublicConstructors), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (NestedType), nameof (RequireConstructors), new Type[] { typeof (Type) })] - [RecognizedReflectionAccessPattern] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] public void ReadFromInstanceField () { - RequirePublicParameterlessConstructor (_typeWithPublicParameterlessConstructor); - RequirePublicConstructors (_typeWithPublicParameterlessConstructor); - RequireConstructors (_typeWithPublicParameterlessConstructor); - } - - private static void RequirePublicParameterlessConstructor ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - Type type) - { - } - - private static void RequirePublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - Type type) - { - } - - private static void RequireConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type) - { + _typeWithPublicParameterlessConstructor.RequiresPublicParameterlessConstructor (); + _typeWithPublicParameterlessConstructor.RequiresPublicConstructors (); + _typeWithPublicParameterlessConstructor.RequiresNonPublicConstructors (); } } } diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs index 07a2e654a..a798dfa51 100644 --- a/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs +++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics.CodeAnalysis; using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.LinkAttributes @@ -12,6 +13,7 @@ namespace Mono.Linker.Tests.Cases.LinkAttributes [SetupCompileResource ("EmbeddedLinkAttributes.xml", "ILLink.LinkAttributes.xml")] [IgnoreLinkAttributes (false)] [RemovedResourceInAssembly ("test.exe", "ILLink.LinkAttributes.xml")] + [ExpectedNoWarnings] class EmbeddedLinkAttributes { public static void Main () @@ -24,47 +26,22 @@ namespace Mono.Linker.Tests.Cases.LinkAttributes Type _typeWithPublicParameterlessConstructor; - [UnrecognizedReflectionAccessPattern (typeof (EmbeddedLinkAttributes), nameof (RequirePublicConstructors), new Type[] { typeof (Type) })] - [UnrecognizedReflectionAccessPattern (typeof (EmbeddedLinkAttributes), nameof (RequireNonPublicConstructors), new Type[] { typeof (Type) })] - [RecognizedReflectionAccessPattern] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] private void ReadFromInstanceField () { - RequirePublicParameterlessConstructor (_typeWithPublicParameterlessConstructor); - RequirePublicConstructors (_typeWithPublicParameterlessConstructor); - RequireNonPublicConstructors (_typeWithPublicParameterlessConstructor); - } - private static void RequirePublicParameterlessConstructor ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - Type type) - { - } - - private static void RequirePublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - Type type) - { - } - - private static void RequireNonPublicConstructors ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type) - { + _typeWithPublicParameterlessConstructor.RequiresPublicParameterlessConstructor (); + _typeWithPublicParameterlessConstructor.RequiresPublicConstructors (); + _typeWithPublicParameterlessConstructor.RequiresNonPublicConstructors (); } Type _typeWithPublicFields; - [UnrecognizedReflectionAccessPattern (typeof (EmbeddedLinkAttributes), nameof (RequirePublicConstructors), new Type[] { typeof (Type) })] - [RecognizedReflectionAccessPattern] + [ExpectedWarning ("IL2077", nameof (DataFlowTypeExtensions) + "." + nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] private void ReadFromInstanceField2 () { - RequirePublicConstructors (_typeWithPublicFields); - RequirePublicFields (_typeWithPublicFields); - } - - private static void RequirePublicFields ( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - Type type) - { + _typeWithPublicFields.RequiresPublicConstructors (); + _typeWithPublicFields.RequiresPublicFields (); } } } diff --git a/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs b/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs index c2e3766e3..5d345f1e5 100644 --- a/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs +++ b/test/Mono.Linker.Tests.Cases/Logging/SourceLines.cs @@ -9,10 +9,10 @@ namespace Mono.Linker.Tests.Cases.Logging [SkipKeptItemsValidation] [SetupCompileArgument ("/debug:full")] [ExpectedNoWarnings] - [ExpectedWarning ("IL2074", FileName = "", SourceLine = 34, SourceColumn = 4)] - [ExpectedWarning ("IL2074", FileName = "", SourceLine = 35, SourceColumn = 4)] - [ExpectedWarning ("IL2091", FileName = "", SourceLine = 44, SourceColumn = 4)] - [ExpectedWarning ("IL2089", FileName = "", SourceLine = 48, SourceColumn = 36)] + [ExpectedWarning ("IL2074", FileName = "", SourceLine = 39, SourceColumn = 4)] + [ExpectedWarning ("IL2074", FileName = "", SourceLine = 40, SourceColumn = 4)] + [ExpectedWarning ("IL2091", FileName = "", SourceLine = 51, SourceColumn = 4)] + [ExpectedWarning ("IL2089", FileName = "", SourceLine = 55, SourceColumn = 36)] public class SourceLines { public static void Main () @@ -29,12 +29,19 @@ namespace Mono.Linker.Tests.Cases.Logging return typeof (SourceLines); } + // Analyzer test infrastructure doesn't support ExpectedWarning at the top-level. + // This is OK because the test is meant to validate that the linker infrastructure produces the right line numbers, + // and we have separate tests to check the line number of analyzer warnings. + [ExpectedWarning ("IL2074", nameof (SourceLines) + "." + nameof (type), nameof (SourceLines) + "." + nameof (GetUnknownType) + "()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2074", nameof (SourceLines) + "." + nameof (type), nameof (SourceLines) + "." + nameof (GetUnknownType) + "()", ProducedBy = ProducedBy.Analyzer)] static void UnrecognizedReflectionPattern () { type = GetUnknownType (); // IL2074 type = GetUnknownType (); // IL2074 } + [ExpectedWarning ("IL2091", "LocalFunction()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2089", nameof (SourceLines) + "." + nameof (type), "TOuterMethod", ProducedBy = ProducedBy.Analyzer)] static IEnumerable<int> GenericMethodIteratorWithRequirement<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TOuterMethod> () { // Since this is iterator it will turn into a subclass with generic T diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs b/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs index 7eb814fe1..fb8314f9b 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ActivatorCreateInstance.cs @@ -8,6 +8,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] [KeptMember (".ctor()")] public class ActivatorCreateInstance { @@ -165,8 +166,8 @@ namespace Mono.Linker.Tests.Cases.Reflection public FromParameterOnStaticMethodTypeB (int arg) { } } - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (Type), typeof (object[]) }, messageCode: "IL2067")] - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (Type), typeof (BindingFlags), typeof (Binder), typeof (object[]), typeof (CultureInfo) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, Object[])")] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance), nameof (CultureInfo))] [Kept] private void FromParameterOnInstanceMethod ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] @@ -188,8 +189,8 @@ namespace Mono.Linker.Tests.Cases.Reflection public FromParameterOnInstanceMethodType (int arg, int arg2) { } } - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (Type) }, messageCode: "IL2067")] - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (Type), typeof (object[]) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type)")] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance) + "(Type, Object[])")] [Kept] private static void FromParameterWithNonPublicConstructors ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] @@ -212,7 +213,7 @@ namespace Mono.Linker.Tests.Cases.Reflection private FromParameterWithNonPublicConstructorsType (int arg, int arg2) { } } - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (Type), typeof (BindingFlags), typeof (Binder), typeof (object[]), typeof (CultureInfo) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (Activator) + "." + nameof (Activator.CreateInstance))] [Kept] private static void FromParameterWithPublicConstructors ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] @@ -319,16 +320,14 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (string), typeof (string) }, - messageCode: "IL2032", message: new string[] { "assemblyName" })] + [ExpectedWarning ("IL2032", nameof (Activator) + "." + nameof (Activator.CreateInstance), "assemblyName")] private static void WithNullAssemblyName () { Activator.CreateInstance (null, "Mono.Linker.Tests.Cases.Reflection.ActivatorCreateInstance+WithAssemblyNameParameterless1"); } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (string), typeof (string) }, - messageCode: "IL2061", message: new string[] { "NonExistingAssembly" })] + [ExpectedWarning ("IL2061", nameof (Activator) + "." + nameof (Activator.CreateInstance), "NonExistingAssembly")] private static void WithNonExistingAssemblyName () { Activator.CreateInstance ("NonExistingAssembly", "Mono.Linker.Tests.Cases.Reflection.ActivatorCreateInstance+WithAssemblyNameParameterless1"); @@ -338,15 +337,13 @@ namespace Mono.Linker.Tests.Cases.Reflection private static string _typeNameField; [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Activator), nameof (Activator.CreateInstance), new Type[] { typeof (string), typeof (string), typeof (object[]) }, - messageCode: "IL2032", message: new string[] { "typeName" })] + [ExpectedWarning ("IL2032", nameof (Activator) + "." + nameof (Activator.CreateInstance), "typeName")] private static void WithAssemblyAndUnknownTypeName () { Activator.CreateInstance ("test", _typeNameField, new object[] { }); } [Kept] - [RecognizedReflectionAccessPattern] private static void WithAssemblyAndNonExistingTypeName () { Activator.CreateInstance ("test", "NonExistingType", new object[] { }); @@ -381,7 +378,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void AppDomainCreateInstance () { // Just a basic test that these are all recognized, we're not testing that it marks correctly as it has the exact same implementation @@ -404,9 +400,9 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Assembly), nameof (Assembly.CreateInstance), new Type[] { typeof (string) }, messageCode: "IL2058")] - [UnrecognizedReflectionAccessPattern (typeof (Assembly), nameof (Assembly.CreateInstance), new Type[] { typeof (string), typeof (bool) }, messageCode: "IL2058")] - [UnrecognizedReflectionAccessPattern (typeof (Assembly), nameof (Assembly.CreateInstance), new Type[] { typeof (string), typeof (bool), typeof (BindingFlags), typeof (Binder), typeof (object[]), typeof (CultureInfo), typeof (object[]) }, messageCode: "IL2058")] + [ExpectedWarning ("IL2058", nameof (Assembly) + "." + nameof (Assembly.CreateInstance) + "(String)")] + [ExpectedWarning ("IL2058", nameof (Assembly) + "." + nameof (Assembly.CreateInstance) + "(String, Boolean)")] + [ExpectedWarning ("IL2058", nameof (Assembly) + "." + nameof (Assembly.CreateInstance), nameof (BindingFlags))] private static void UnsupportedCreateInstance () { typeof (ActivatorCreateInstance).Assembly.CreateInstance ("NonExistent"); @@ -428,7 +424,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestCreateInstanceOfTWithConcreteType () { Activator.CreateInstance<TestCreateInstanceOfTWithConcreteTypeType> (); @@ -448,7 +443,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestCreateInstanceOfTWithNewConstraint<T> () where T : new() { Activator.CreateInstance<T> (); @@ -468,6 +462,7 @@ namespace Mono.Linker.Tests.Cases.Reflection [Kept] [ExpectedWarning ("IL2091", nameof (Activator), nameof (Activator.CreateInstance) + "<T>")] + [ExpectedWarning ("IL2091", nameof (Activator), nameof (Activator.CreateInstance) + "<T>")] // Warnings are currently duplicated in NETCORE (annotation and intrinsics) - but they're not identical in this case. // See https://github.com/dotnet/linker/issues/1483 private static void TestCreateInstanceOfTWithNoConstraint<T> () @@ -489,7 +484,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestCreateInstanceOfTWithDataflow< [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor), KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] T> () @@ -507,14 +501,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestNullArgsOnKnownType () { Activator.CreateInstance (typeof (TestNullArgsType), null); } [Kept] - [RecognizedReflectionAccessPattern] private static void TestNullArgsOnAnnotatedType ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor), KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] Type type) diff --git a/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs b/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs index 5cecf5e5d..526376526 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/AssemblyImportedViaReflectionWithSweptReferences.cs @@ -5,6 +5,7 @@ using Mono.Linker.Tests.Cases.Reflection.Dependencies; namespace Mono.Linker.Tests.Cases.Reflection { + [ExpectedNoWarnings] [SetupCSharpCompilerToUse ("csc")] [SetupCompileBefore ("unusedreference.dll", new[] { "Dependencies/UnusedAssemblyDependency.cs" })] [SetupCompileBefore ("reference.dll", new[] { "Dependencies/AssemblyDependency.cs" }, addAsReference: false)] @@ -19,7 +20,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void AccessNonExistingTypeInAssembly () { diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs index dde8f46f9..5c28deafe 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ConstructorUsedViaReflection.cs @@ -7,6 +7,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] public class ConstructorUsedViaReflection { public static void Main () @@ -58,9 +59,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (Type[]) }, - typeof (EmptyTypes), nameof (EmptyTypes), new Type[0])] static void TestConstructorWithTypes_EmptyTypes () { var constructor = typeof (EmptyTypes).GetConstructor (new Type[] { }); @@ -68,7 +66,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestConstructorWithTypes_NonEmptyTypes () { var constructor = typeof (GetConstructor_Types).GetConstructor (new Type[] { typeof (int) }); @@ -76,7 +73,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestConstructorWithTypes_EmptyTypes_DataFlow ( [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] @@ -87,8 +83,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (Type[]) }, messageCode: "IL2070")] + [ExpectedWarning ("IL2070", nameof (Type.GetConstructor))] static void TestConstructorWithTypes_NonEmptyTypes_DataFlow ( [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] @@ -123,9 +118,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (KnownBindingFlags), nameof (KnownBindingFlags), new Type[0])] public static void TestWithBindingFlags () { var constructor = typeof (KnownBindingFlags).GetConstructor (BindingFlags.Public, GetNullValue ("some argument", 2, 3), new Type[] { }, new ParameterModifier[] { }); @@ -157,8 +149,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (UnknownBindingFlags), nameof (UnknownBindingFlags), new Type[0])] public static void TestWithUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all constructors on the type @@ -187,9 +177,6 @@ namespace Mono.Linker.Tests.Cases.Reflection { } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (BindingFlags), typeof (Binder), typeof (CallingConventions), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (GetConstructor_BindingAttr_Binder_CallConvention_Types_Modifiers), nameof (GetConstructor_BindingAttr_Binder_CallConvention_Types_Modifiers), new Type[0])] public static void TestWithCallingConvention () { var constructor = typeof (GetConstructor_BindingAttr_Binder_CallConvention_Types_Modifiers).GetConstructor (BindingFlags.Public, GetNullValue ("some argument", 2, 3), CallingConventions.HasThis, new Type[] { }, new ParameterModifier[] { }); @@ -236,9 +223,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (BindingFlags), typeof (Type[]) }, - typeof (GetConstructor_BindingAttr_Types), nameof (GetConstructor_BindingAttr_Types), new Type[0])] static void TestWithBindingFlagsAndTypes_EmptyTypes () { var constructor = typeof (GetConstructor_BindingAttr_Types).GetConstructor (BindingFlags.Public, new Type[] { }); @@ -246,7 +230,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestWithBindingFlagsAndTypes_NonEmptyTypes () { var constructor = typeof (NonEmptyTypes).GetConstructor (BindingFlags.Public, new Type[] { typeof (TestType) }); @@ -254,7 +237,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestWithBindingFlagsAndTypes_EmptyTypes_DataFlow ( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] @@ -264,8 +246,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (BindingFlags), typeof (Type[]) }, messageCode: "IL2070")] + [ExpectedWarning ("IL2070", nameof (Type.GetConstructor))] static void TestWithBindingFlagsAndTypes_NonEmptyTypes_DataFlow ( [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] @@ -289,8 +270,7 @@ namespace Mono.Linker.Tests.Cases.Reflection return null; } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (Type[]) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetConstructor" })] + [ExpectedWarning ("IL2075", "FindType", "GetConstructor")] [Kept] static void TestDataFlowType () { @@ -342,12 +322,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (IfConstructor), nameof (IfConstructor), new Type[0])] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetConstructor), new Type[] { typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (ElseConstructor), nameof (ElseConstructor), new Type[0])] public static void TestIfElse (bool decision) { Type myType; diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ConstructorsUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/ConstructorsUsedViaReflection.cs index be6d2408b..78ed3dad1 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ConstructorsUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ConstructorsUsedViaReflection.cs @@ -21,21 +21,18 @@ namespace Mono.Linker.Tests.Cases.Reflection TestIfElse (true); } - [RecognizedReflectionAccessPattern] [Kept] static void TestGetConstructors () { var constructors = typeof (SimpleGetConstructors).GetConstructors (); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithBindingFlags () { var constructors = typeof (ConstructorsBindingFlags).GetConstructors (BindingFlags.Public | BindingFlags.Static); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithUnknownBindingFlags (BindingFlags bindingFlags) { @@ -44,7 +41,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -57,8 +53,7 @@ namespace Mono.Linker.Tests.Cases.Reflection return null; } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetConstructors), new Type[] { typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetConstructors" })] + [ExpectedWarning ("IL2075", "FindType", "GetConstructors")] [Kept] static void TestDataFlowType () { @@ -67,14 +62,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))][DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) { var constructors = type.GetConstructors (BindingFlags.Public | BindingFlags.Static); } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElse (bool decision) { Type myType; diff --git a/test/Mono.Linker.Tests.Cases/Reflection/EventUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/EventUsedViaReflection.cs index 5f93cf879..5dbad0c58 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/EventUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/EventUsedViaReflection.cs @@ -6,6 +6,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] public class EventUsedViaReflection { public static void Main () @@ -31,9 +32,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetEvent), new Type[] { typeof (string) }, - typeof (Foo), nameof (Foo.Event), (Type[]) null)] static void TestByName () { var eventInfo = typeof (Foo).GetEvent ("Event"); @@ -111,8 +109,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetEvent), new Type[] { typeof (string) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetEvent" })] + [ExpectedWarning ("IL2075", "FindType", "GetEvent")] static void TestDataFlowType () { Type type = FindType (); @@ -120,15 +117,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetEvent), new Type[] { typeof (string) }, - typeof (IfClass), nameof (IfClass.IfEvent), (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetEvent), new Type[] { typeof (string) }, - typeof (IfClass), nameof (IfClass.ElseEvent), (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetEvent), new Type[] { typeof (string) }, - typeof (ElseClass), nameof (ElseClass.IfEvent), (Type[]) null)] static void TestIfElse (int i) { Type myType; @@ -147,9 +135,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetEvent), new Type[] { typeof (string) }, - typeof (BaseClass), nameof (BaseClass.PublicEventOnBase), (Type[]) null)] static void TestEventInBaseType () { typeof (DerivedClass).GetEvent ("ProtectedEventOnBase"); // Will not mark anything as it only works on public events @@ -157,9 +142,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetEvent), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (IgnoreCaseBindingFlagsClass), nameof (IgnoreCaseBindingFlagsClass.PublicEvent), (Type[]) null)] static void TestIgnoreCaseBindingFlags () { typeof (IgnoreCaseBindingFlagsClass).GetEvent ("publicevent", BindingFlags.IgnoreCase | BindingFlags.Public); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/EventsUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/EventsUsedViaReflection.cs index 0c2d15582..53a7494f6 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/EventsUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/EventsUsedViaReflection.cs @@ -28,14 +28,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestGetEvents () { var events = typeof (Foo).GetEvents (); } [Kept] - [RecognizedReflectionAccessPattern] // The event will not be kept as it's internal and the behavior of Type.GetEvents() is to only return public events // But we don't mark it as unrecognized access pattern - we did recognize it fully, just didn't find the event being asked for // The behavior of the code will not change by linking it: @@ -47,14 +45,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestBindingFlags () { var events = typeof (Bar).GetEvents (BindingFlags.NonPublic); } [Kept] - [RecognizedReflectionAccessPattern] static void TestUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all events on the type @@ -62,7 +58,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -76,8 +71,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetEvents), new Type[] { typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetEvents" })] + [ExpectedWarning ("IL2075", "FindType", "GetEvents")] static void TestDataFlowType () { Type type = FindType (); @@ -85,14 +79,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))][DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] Type type) { var events = type.GetEvents (BindingFlags.Public | BindingFlags.Static); } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElse (int i) { Type myType; @@ -105,14 +97,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestIgnoreCaseBindingFlags () { var events = typeof (IgnoreCaseBindingFlagsClass).GetEvents (BindingFlags.IgnoreCase | BindingFlags.Public); } [Kept] - [RecognizedReflectionAccessPattern] static void TestUnsupportedBindingFlags () { var events = typeof (PutRefDispPropertyBindingFlagsClass).GetEvents (BindingFlags.PutRefDispProperty); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs index 699bb9d9d..bb89b436d 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionCallString.cs @@ -118,13 +118,12 @@ namespace Mono.Linker.Tests.Cases.Reflection class TestUnknownType { [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Expression), nameof (Expression.Call), - new Type[] { typeof (Type), typeof (string), typeof (Type[]), typeof (Expression[]) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (Expression) + "." + nameof (Expression.Call))] public static void Test () { // Keep all methods of the type that made the call Expression.Call (GetUnknownType (), "This string will not be reached", Type.EmptyTypes); - // UnrecognizedReflectionAccessPattern + // IL2072 Expression.Call (TriggerUnrecognizedPattern (), "This string will not be reached", Type.EmptyTypes); } diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionFieldString.cs b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionFieldString.cs index 0a6959ce8..c2399e92c 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionFieldString.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionFieldString.cs @@ -7,10 +7,10 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [Reference ("System.Core.dll")] + [ExpectedNoWarnings] public class ExpressionFieldString { - [UnrecognizedReflectionAccessPattern (typeof (Expression), nameof (Expression.Field), - new Type[] { typeof (Expression), typeof (Type), typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (Expression) + "." + nameof (Expression.Field))] public static void Main () { Expression.Field (Expression.Parameter (typeof (int), ""), typeof (ExpressionFieldString), "Field"); @@ -18,8 +18,9 @@ namespace Mono.Linker.Tests.Cases.Reflection Expression.Field (null, typeof (Derived), "_protectedFieldOnBase"); Expression.Field (null, typeof (Derived), "_publicFieldOnBase"); UnknownType.Test (); + UnknownTypeNoAnnotation.Test (); UnknownString.Test (); - Expression.Field (null, GetType (), "This string will not be reached"); // UnrecognizedReflectionAccessPattern + Expression.Field (null, GetType (), "This string will not be reached"); // IL2072 } [Kept] @@ -61,6 +62,26 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] + class UnknownTypeNoAnnotation + { + public static int Field1; + private int Field2; + + [ExpectedWarning ("IL2072", "'type'")] + [Kept] + public static void Test () + { + Expression.Field (null, GetType (), "This string will not be reached"); + } + + [Kept] + static Type GetType () + { + return typeof (UnknownType); + } + } + + [Kept] class UnknownString { [Kept] diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionNewType.cs b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionNewType.cs index a137d122c..9e06ccb43 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionNewType.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionNewType.cs @@ -8,6 +8,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [Reference ("System.Core.dll")] + [ExpectedNoWarnings] public class ExpressionNewType { public static void Main () @@ -25,11 +26,6 @@ namespace Mono.Linker.Tests.Cases.Reflection Expression.New (5 + 7 == 12 ? null : typeof (RemovedType)); } - #region RecognizedReflectionAccessPatterns - [RecognizedReflectionAccessPattern ( - typeof (Expression), nameof (Expression.New), new Type[] { typeof (Type) }, typeof (A), "A", new Type[0])] - [RecognizedReflectionAccessPattern ( - typeof (Expression), nameof (Expression.New), new Type[] { typeof (Type) }, typeof (B), "B", new Type[0])] [Kept] static void Branch_SystemTypeValueNode (int i) { @@ -47,25 +43,22 @@ namespace Mono.Linker.Tests.Cases.Reflection Expression.New (T); } - #endregion - #region UnrecognizedReflectionAccessPatterns - [UnrecognizedReflectionAccessPattern (typeof (Expression), nameof (Expression.New), new Type[] { typeof (Type) }, messageCode: "IL2067")] + [ExpectedWarning ("IL2067", nameof (Expression) + "." + nameof (Expression.New))] [Kept] static void Branch_MethodParameterValueNode (Type T) { Expression.New (T); } - [UnrecognizedReflectionAccessPattern (typeof (Expression), nameof (Expression.New), new Type[] { typeof (Type) }, messageCode: "IL2072")] - [UnrecognizedReflectionAccessPattern (typeof (Expression), nameof (Expression.New), new Type[] { typeof (Type) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (Expression) + "." + nameof (Expression.New), "'System." + nameof (Type) + "." + nameof (Type.GetType))] + [ExpectedWarning ("IL2072", nameof (Expression) + "." + nameof (Expression.New), nameof (ExpressionNewType) + "." + nameof (ExpressionNewType.GetType))] [Kept] static void Branch_UnrecognizedPatterns () { Expression.New (Type.GetType ("RemovedType")); Expression.New (GetType ()); } - #endregion #region Helpers [Kept] diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs index 8a0b2b3b0..b4d9613ae 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyMethodInfo.cs @@ -76,7 +76,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void Test () { Expression<Func<int>> staticGetter = () => StaticProperty; @@ -124,7 +123,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void Test () { Expression.Property (null, typeof (PropertySetter).GetMethod ("set_StaticProperty")); @@ -136,7 +134,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNull () { MethodInfo mi = null; @@ -144,16 +141,13 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern ( - typeof (Expression), nameof (Expression.Property), new Type[] { typeof (Expression), typeof (MethodInfo) }, - messageCode: "IL2103")] + [ExpectedWarning ("IL2103", nameof (Expression) + "." + nameof (Expression.Property))] static void TestNonPropertyMethod () { Expression.Property (null, typeof (ExpressionPropertyMethodInfo).GetMethod (nameof (TestNonPropertyMethod), BindingFlags.NonPublic | BindingFlags.Static)); } [Kept] - [RecognizedReflectionAccessPattern] static void TestNonExistentMethod () { Expression.Property (null, typeof (ExpressionPropertyMethodInfo).GetMethod ("NonExistent")); @@ -181,7 +175,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void Test (int p) { MethodInfo mi; @@ -202,9 +195,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern ( - typeof (Expression), nameof (Expression.Property), new Type[] { typeof (Expression), typeof (MethodInfo) }, - messageCode: "IL2103")] + [ExpectedWarning ("IL2103", nameof (Expression) + "." + nameof (Expression.Property))] static void TestUnknownMethod (MethodInfo mi) { Expression.Property (null, mi); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyString.cs b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyString.cs index 7379710bd..13de4491d 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyString.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/ExpressionPropertyString.cs @@ -9,10 +9,10 @@ namespace Mono.Linker.Tests.Cases.Reflection // Explicitly use roslyn to try and get a compiler that supports defining a static property without a setter [SetupCSharpCompilerToUse ("csc")] [Reference ("System.Core.dll")] + [ExpectedNoWarnings] public class ExpressionPropertyString { - [UnrecognizedReflectionAccessPattern (typeof (Expression), nameof (Expression.Property), - new Type[] { typeof (Expression), typeof (Type), typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (Expression) + "." + nameof (Expression.Property))] public static void Main () { Expression.Property (Expression.Parameter (typeof (int), ""), typeof (ExpressionPropertyString), "Property"); @@ -21,7 +21,7 @@ namespace Mono.Linker.Tests.Cases.Reflection Expression.Property (null, typeof (Derived), "PublicPropertyOnBase"); UnknownType.Test (); UnknownString.Test (); - Expression.Property (null, GetType (), "This string will not be reached"); // UnrecognizedReflectionAccessPattern + Expression.Property (null, GetType (), "This string will not be reached"); // IL2072 } [Kept] diff --git a/test/Mono.Linker.Tests.Cases/Reflection/FieldUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/FieldUsedViaReflection.cs index 94535adb1..c0fad7206 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/FieldUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/FieldUsedViaReflection.cs @@ -6,6 +6,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] public class FieldUsedViaReflection { public static void Main () @@ -29,9 +30,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetField), new Type[] { typeof (string) }, - typeof (FieldUsedViaReflection), nameof (FieldUsedViaReflection.publicField), (Type[]) null)] static void TestByName () { var field = typeof (FieldUsedViaReflection).GetField ("publicField"); @@ -46,9 +44,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetField), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (Foo), nameof (Foo.field), (Type[]) null)] static void TestNameBindingFlags () { var field = typeof (Foo).GetField ("field", BindingFlags.Static); @@ -106,8 +101,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetField), new Type[] { typeof (string) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetField" })] + [ExpectedWarning ("IL2075", "FindType", "GetField")] static void TestDataFlowType () { Type type = FindType (); @@ -115,12 +109,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetField), new Type[] { typeof (string) }, - typeof (IfClass), nameof (IfClass.ifField), (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetField), new Type[] { typeof (string) }, - typeof (ElseClass), nameof (ElseClass.elseField), (Type[]) null)] static void TestIfElse (int i) { Type myType; @@ -139,9 +127,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetField), new Type[] { typeof (string) }, - typeof (BaseClass), nameof (BaseClass.publicFieldOnBase), (Type[]) null)] static void TestFieldInBaseType () { var protectedField = typeof (DerivedClass).GetField ("protectedFieldOnBase"); // Will not be marked - only public fields work this way @@ -149,9 +134,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetField), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (IgnoreCaseBindingFlagsClass), nameof (IgnoreCaseBindingFlagsClass.publicField), (Type[]) null)] static void TestIgnoreCaseBindingFlags () { var field = typeof (IgnoreCaseBindingFlagsClass).GetField ("publicfield", BindingFlags.IgnoreCase | BindingFlags.Public); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/FieldsUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/FieldsUsedViaReflection.cs index 7f805345e..ab50a5dac 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/FieldsUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/FieldsUsedViaReflection.cs @@ -24,21 +24,18 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestGetFields () { var fields = typeof (FieldsUsedViaReflection).GetFields (); } [Kept] - [RecognizedReflectionAccessPattern] static void TestBindingFlags () { var fields = typeof (Foo).GetFields (BindingFlags.Public); } [Kept] - [RecognizedReflectionAccessPattern] static void TestUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all fields on the type @@ -46,7 +43,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -60,8 +56,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetFields), new Type[] { typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetFields" })] + [ExpectedWarning ("IL2075", "FindType", "GetFields")] static void TestDataFlowType () { Type type = FindType (); @@ -69,14 +64,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))][DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type) { var fields = type.GetFields (BindingFlags.Public | BindingFlags.Static); } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElse (int i) { Type myType; @@ -89,14 +82,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestIgnoreCaseBindingFlags () { var fields = typeof (IgnoreCaseBindingFlagsClass).GetFields (BindingFlags.IgnoreCase | BindingFlags.Public); } [Kept] - [RecognizedReflectionAccessPattern] static void TestUnsupportedBindingFlags () { var fields = typeof (PutDispPropertyBindingFlagsClass).GetFields (BindingFlags.PutDispProperty); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs index a73ed2d7a..828ce4d77 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/MemberUsedViaReflection.cs @@ -7,6 +7,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] public class MemberUsedViaReflection { public static void Main () @@ -24,7 +25,6 @@ namespace Mono.Linker.Tests.Cases.Reflection TestIfElse (true); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithName () { @@ -32,21 +32,18 @@ namespace Mono.Linker.Tests.Cases.Reflection } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithPrefixLookup () { var members = typeof (PrefixLookupType).GetMember ("PrefixLookup*"); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithBindingFlags () { var members = typeof (BindingFlagsType).GetMember ("PrefixLookup*", BindingFlags.Public | BindingFlags.NonPublic); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithUnknownBindingFlags (BindingFlags bindingFlags) { @@ -54,7 +51,6 @@ namespace Mono.Linker.Tests.Cases.Reflection var members = typeof (UnknownBindingFlags).GetMember ("PrefixLookup*", bindingFlags); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithMemberTypes () { @@ -63,7 +59,6 @@ namespace Mono.Linker.Tests.Cases.Reflection var members = typeof (TestMemberTypes).GetMember ("PrefixLookup*", MemberTypes.Method, BindingFlags.Public); } - [RecognizedReflectionAccessPattern] [Kept] static void TestNullType () { @@ -77,8 +72,7 @@ namespace Mono.Linker.Tests.Cases.Reflection return null; } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetMember), new Type[] { typeof (string) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetMember" })] + [ExpectedWarning ("IL2075", "FindType", "GetMember")] [Kept] static void TestDataFlowType () { @@ -87,7 +81,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicEvents | @@ -100,7 +93,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElse (bool decision) { Type myType; diff --git a/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs index 5a7fe375e..8a20f7733 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/MembersUsedViaReflection.cs @@ -21,21 +21,18 @@ namespace Mono.Linker.Tests.Cases.Reflection TestIfElse (true); } - [RecognizedReflectionAccessPattern] [Kept] static void TestGetMembers () { var members = typeof (SimpleGetMembers).GetMembers (); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithBindingFlags () { var members = typeof (MembersBindingFlags).GetMembers (BindingFlags.Public); } - [RecognizedReflectionAccessPattern] [Kept] static void TestWithUnknownBindingFlags (BindingFlags bindingFlags) { @@ -44,7 +41,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -57,8 +53,7 @@ namespace Mono.Linker.Tests.Cases.Reflection return null; } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetMembers), new Type[] { typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetMembers" })] + [ExpectedWarning ("IL2075", "FindType", "GetMembers")] [Kept] static void TestDataFlowType () { @@ -67,7 +62,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicEvents | @@ -80,7 +74,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElse (bool decision) { Type myType; diff --git a/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs index 7a9475542..116cabad0 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/MethodUsedViaReflection.cs @@ -7,6 +7,7 @@ namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] [SetupLinkerArgument ("--disable-opt", "unreachablebodies")] public class MethodUsedViaReflection { @@ -73,9 +74,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string) }, - typeof (GetMethod_Name), nameof (GetMethod_Name.OnlyCalledViaReflection), new Type[0])] public static void TestName () { var method = typeof (GetMethod_Name).GetMethod ("OnlyCalledViaReflection"); @@ -83,7 +81,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestNamePrivate () { // This should fail at runtime, since GetMethod(name) only works on public methods @@ -121,9 +118,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (Type[]) }, - typeof (GetMethod_Name_Types), nameof (GetMethod_Name_Types.OnlyCalledViaReflection), new Type[0])] public static void TestNameAndType () { // Currently linker doesn't analyze the Type[] parameter and thus it marks all methods with the name and matching binding flags (public in this case) @@ -159,9 +153,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (GetMethod_Name_BindingAttr), nameof (GetMethod_Name_BindingAttr.OnlyCalledViaReflection), new Type[0])] public static void TestExplicitBindingFlags () { var method = typeof (GetMethod_Name_BindingAttr).GetMethod ("OnlyCalledViaReflection", BindingFlags.Static | BindingFlags.Public); @@ -197,7 +188,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all methods on the type @@ -216,7 +206,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name) { // Since the binding flags and name are not known linker should mark all methods on the type @@ -253,7 +242,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestUnknownNullBindingFlags (BindingFlags bindingFlags) { // The case here is a pattern which linker doesn't recognize (unlike the test case above, which passes a recognized @@ -364,7 +352,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestNameBindingFlagsAndParameterModifier () { var method = typeof (GetMethod_Name_BindingAttr_Binder_Types_Modifiers).GetMethod ("OnlyCalledViaReflection", BindingFlags.Public, null, new Type[] { }, null); @@ -396,9 +383,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags), typeof (Binder), typeof (CallingConventions), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (GetMethod_Name_BindingAttr_Binder_CallConvention_Types_Modifiers), nameof (GetMethod_Name_BindingAttr_Binder_CallConvention_Types_Modifiers.OnlyCalledViaReflection), new Type[0])] public static void TestNameBindingFlagsCallingConventionParameterModifier () { var method = typeof (GetMethod_Name_BindingAttr_Binder_CallConvention_Types_Modifiers).GetMethod ("OnlyCalledViaReflection", BindingFlags.NonPublic, null, CallingConventions.Standard, new Type[] { }, null); @@ -432,7 +416,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestNameBindingFlagsAndTypes () { var method = typeof (GetMethod_Name_BindingAttr_Types).GetMethod ("OnlyCalledViaReflection", BindingFlags.Public, new Type[] { }); @@ -464,9 +447,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (int), typeof (Type[]) }, - typeof (GetMethod_Name_GenericParameterCount_Types), nameof (GetMethod_Name_GenericParameterCount_Types.OnlyCalledViaReflection), new Type[] { typeof (int), typeof (int) })] public static void TestNameWithIntAndType () { var method = typeof (GetMethod_Name_GenericParameterCount_Types).GetMethod ("OnlyCalledViaReflection", 1, new Type[] { typeof (int) }); @@ -498,9 +478,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (int), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (GetMethod_Name_GenericParameterCount_Types_Modifiers), nameof (GetMethod_Name_GenericParameterCount_Types_Modifiers.OnlyCalledViaReflection), new Type[] { typeof (int), typeof (int) })] public static void TestNameWithIntAndTypeAndModifiers () { var method = typeof (GetMethod_Name_GenericParameterCount_Types_Modifiers).GetMethod ("OnlyCalledViaReflection", 1, new Type[] { typeof (int) }, null); @@ -532,7 +509,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestNameWithIntAndBindingFlags () { var method = typeof (GetMethod_Name_GenericParameterCount_BindingAttr_Binder_Types_Modifiers) @@ -566,7 +542,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestNameWithIntAndPrivateBindingFlags () { var method = typeof (GetMethod_Name_GenericParameterCount_BindingAttr_Binder_Types_Modifiers_PrivateBinding) @@ -598,9 +573,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (int), typeof (BindingFlags), typeof (Binder), typeof (CallingConventions), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (GetMethod_Name_GenericParameterCount_BindingAttr_Binder_CallConvention_Types_Modifiers), nameof (GetMethod_Name_GenericParameterCount_BindingAttr_Binder_CallConvention_Types_Modifiers.OnlyCalledViaReflection), new Type[0])] public static void TestNameWithIntBindingFlagsCallingConventionParameter () { var method = typeof (GetMethod_Name_GenericParameterCount_BindingAttr_Binder_CallConvention_Types_Modifiers).GetMethod ("OnlyCalledViaReflection", 1, BindingFlags.Static | BindingFlags.NonPublic, null, CallingConventions.Any, new Type[] { }, null); @@ -610,28 +582,24 @@ namespace Mono.Linker.Tests.Cases.Reflection #endif [Kept] - [RecognizedReflectionAccessPattern] static void TestNullName () { var method = typeof (MethodUsedViaReflection).GetMethod (null); } [Kept] - [RecognizedReflectionAccessPattern] static void TestEmptyName () { var method = typeof (MethodUsedViaReflection).GetMethod (string.Empty); } [Kept] - [RecognizedReflectionAccessPattern] static void TestNonExistingName () { var method = typeof (MethodUsedViaReflection).GetMethod ("NonExisting"); } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -645,8 +613,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetMethod" })] + [ExpectedWarning ("IL2075", "FindType", "GetMethod")] static void TestDataFlowType () { Type type = FindType (); @@ -716,21 +683,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (IfClass), nameof (IfClass.OnlyCalledViaReflection), new Type[0])] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (IfClass), nameof (IfClass.ElseIfCall), new Type[0])] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (ElseIfClass), nameof (ElseIfClass.OnlyCalledViaReflection), new Type[0])] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (ElseIfClass), nameof (ElseIfClass.ElseIfCall), new Type[0])] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags), typeof (Binder), typeof (Type[]), typeof (ParameterModifier[]) }, - typeof (ElseClass), nameof (ElseClass.OnlyCalledViaReflection), new Type[0])] public static void TestIfElse (int i) { Type myType; @@ -773,9 +725,6 @@ namespace Mono.Linker.Tests.Cases.Reflection { } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string) }, - typeof (BaseClass), nameof (BaseClass.OnlyCalledViaReflection), new Type[0])] public static void TestMethodInBaseType () { var method = typeof (DerivedClass).GetMethod ("OnlyCalledViaReflection"); @@ -798,9 +747,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetMethod), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (IgnoreCaseBindingFlags), nameof (IgnoreCaseBindingFlags.OnlyCalledViaReflection), new Type[0])] public static void TestIgnoreCaseBindingFlags () { var method = typeof (IgnoreCaseBindingFlags).GetMethod ("onlycalledviareflection", BindingFlags.IgnoreCase | BindingFlags.Public); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs index 5658a1a99..fcede014b 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/MethodsUsedViaReflection.cs @@ -27,21 +27,18 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestGetMethods () { var methods = typeof (MethodsUsedViaReflection).GetMethods (); } [Kept] - [RecognizedReflectionAccessPattern] static void TestBindingFlags () { var methods = typeof (TestBindingClass).GetMethods (BindingFlags.Static | BindingFlags.Public); } [Kept] - [RecognizedReflectionAccessPattern] static void TestUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all methods on the type @@ -49,7 +46,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -63,8 +59,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetMethods), new Type[] { typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetMethods" })] + [ExpectedWarning ("IL2075", "FindType", "GetMethods")] static void TestDataFlowType () { Type type = FindType (); @@ -72,14 +67,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))][DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) { var methods = type.GetMethods (BindingFlags.Public | BindingFlags.Static); } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElse (int i) { Type myType; @@ -94,7 +87,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestIgnoreCaseBindingFlags () { var methods = typeof (IgnoreCaseClass).GetMethods (BindingFlags.IgnoreCase | BindingFlags.Public); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/NestedTypeUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/NestedTypeUsedViaReflection.cs index 2700a8793..66256ef78 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/NestedTypeUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/NestedTypeUsedViaReflection.cs @@ -8,6 +8,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { + [ExpectedNoWarnings] public class NestedTypeUsedViaReflection { public static void Main () @@ -28,9 +29,6 @@ namespace Mono.Linker.Tests.Cases.Reflection public static class NestedType { } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string) }, - typeof (NestedTypeUsedViaReflection.NestedType), null, (Type[]) null)] static void TestByName () { _ = typeof (NestedTypeUsedViaReflection).GetNestedType (nameof (NestedType)); @@ -55,15 +53,6 @@ namespace Mono.Linker.Tests.Cases.Reflection protected static class ProtectedNestedType { } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (NestedTypeUsedViaReflection.PrivateNestedType), null, (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (NestedTypeUsedViaReflection.PublicNestedType), null, (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (NestedTypeUsedViaReflection.ProtectedNestedType), null, (Type[]) null)] static void TestByBindingFlags () { _ = typeof (NestedTypeUsedViaReflection).GetNestedType (nameof (PrivateNestedType), BindingFlags.NonPublic); @@ -72,9 +61,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (UnknownBindingFlags.PublicNestedType), null, (Type[]) null)] static void TestByUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all nested types on the type @@ -82,9 +68,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (UnknownBindingFlagsAndName.PublicNestedType), null, (Type[]) null)] static void TestByUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name) { // Since the binding flags and name are not known linker should mark all nested types on the type @@ -105,9 +88,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetNestedType), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (IgnoreCaseClass.IgnoreCasePublicNestedType), null, (Type[]) null)] static void TestIgnoreCaseBindingFlags () { _ = typeof (IgnoreCaseClass).GetNestedType ("ignorecasepublicnestedtype", BindingFlags.IgnoreCase | BindingFlags.Public); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/NestedTypesUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/NestedTypesUsedViaReflection.cs index 46c490a29..4d8683aed 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/NestedTypesUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/NestedTypesUsedViaReflection.cs @@ -9,6 +9,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { + [ExpectedNoWarnings] public class NestedTypesUsedViaReflection { public static void Main () @@ -27,7 +28,6 @@ namespace Mono.Linker.Tests.Cases.Reflection public static class NestedType { } [Kept] - [RecognizedReflectionAccessPattern] static void TestGetNestedTypes () { _ = typeof (NestedTypesUsedViaReflection).GetNestedType (nameof (NestedType)); @@ -43,14 +43,12 @@ namespace Mono.Linker.Tests.Cases.Reflection protected static class ProtectedNestedType { } [Kept] - [RecognizedReflectionAccessPattern] static void TestByBindingFlags () { _ = typeof (NestedTypesUsedViaReflection).GetNestedTypes (BindingFlags.Public); } [Kept] - [RecognizedReflectionAccessPattern] static void TestByUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all nested types on the type @@ -58,7 +56,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -71,8 +68,7 @@ namespace Mono.Linker.Tests.Cases.Reflection return null; } - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetNestedTypes), new Type[] { typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetNestedTypes" })] + [ExpectedWarning ("IL2075", "FindType", "GetNestedTypes")] [Kept] static void TestDataFlowType () { @@ -81,14 +77,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))][DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type type) { _ = type.GetNestedTypes (BindingFlags.Public | BindingFlags.Static); } [Kept] - [RecognizedReflectionAccessPattern] static void TestIgnoreCaseBindingFlags () { _ = typeof (IgnoreCaseClass).GetNestedTypes (BindingFlags.IgnoreCase | BindingFlags.Public); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/PropertiesUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/PropertiesUsedViaReflection.cs index 4f8346b7c..2254d93b6 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/PropertiesUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/PropertiesUsedViaReflection.cs @@ -28,21 +28,18 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestGetProperties () { var properties = typeof (PropertiesUsedViaReflection).GetProperties (); } [Kept] - [RecognizedReflectionAccessPattern] static void TestBindingFlags () { var properties = typeof (BindingFlagsTest).GetProperties (BindingFlags.Public | BindingFlags.Static); } [Kept] - [RecognizedReflectionAccessPattern] static void TestUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all properties on the type @@ -50,14 +47,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestPropertiesOfArray () { var properties = typeof (int[]).GetProperties (BindingFlags.Public); } [Kept] - [RecognizedReflectionAccessPattern] static void TestNullType () { Type type = null; @@ -71,8 +66,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetProperties), new Type[] { typeof (BindingFlags) }, - messageCode: "IL2075", message: new string[] { "GetProperties" })] + [ExpectedWarning ("IL2075", "GetProperties")] static void TestDataFlowType () { Type type = FindType (); @@ -80,14 +74,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] private static void TestDataFlowWithAnnotation ([KeptAttributeAttribute (typeof (DynamicallyAccessedMembersAttribute))][DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) { var properties = type.GetProperties (BindingFlags.Public | BindingFlags.Static); } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElse (int i) { Type myType; @@ -100,21 +92,18 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestIgnoreCaseBindingFlags () { var properties = typeof (IgnoreCaseBindingFlagsClass).GetProperties (BindingFlags.IgnoreCase | BindingFlags.Public); } [Kept] - [RecognizedReflectionAccessPattern] static void TestIgnorableBindingFlags () { var properties = typeof (ExactBindingBindingFlagsClass).GetProperties (BindingFlags.Public | BindingFlags.ExactBinding); } [Kept] - [RecognizedReflectionAccessPattern] static void TestUnsupportedBindingFlags () { var properties = typeof (ChangeTypeBindingFlagsClass).GetProperties (BindingFlags.Public | BindingFlags.SuppressChangeType); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/PropertyUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/PropertyUsedViaReflection.cs index 4004e894b..bdd671987 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/PropertyUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/PropertyUsedViaReflection.cs @@ -6,6 +6,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] [SetupLinkerArgument ("--disable-opt", "unreachablebodies")] public class PropertyUsedViaReflection { @@ -33,9 +34,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (PropertyUsedViaReflection), nameof (PropertyUsedViaReflection.OnlyUsedViaReflection), (Type[]) null)] static void TestGetterAndSetter () { var property = typeof (PropertyUsedViaReflection).GetProperty ("OnlyUsedViaReflection"); @@ -51,9 +49,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (PropertyUsedViaReflection), nameof (PropertyUsedViaReflection.SetterOnly), (Type[]) null)] static void TestSetterOnly () { var property = typeof (PropertyUsedViaReflection).GetProperty ("SetterOnly"); @@ -61,9 +56,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (PropertyUsedViaReflection), nameof (PropertyUsedViaReflection.GetterOnly), (Type[]) null)] static void TestGetterOnly () { var property = typeof (PropertyUsedViaReflection).GetProperty ("GetterOnly"); @@ -71,9 +63,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (BindingFlagsTest), nameof (BindingFlagsTest.PublicProperty), (Type[]) null)] static void TestBindingFlags () { var property = typeof (BindingFlagsTest).GetProperty ("PublicProperty", BindingFlags.Public); @@ -81,9 +70,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (UnknownBindingFlags), nameof (UnknownBindingFlags.SomeProperty), (Type[]) null)] static void TestUnknownBindingFlags (BindingFlags bindingFlags) { // Since the binding flags are not known linker should mark all properties on the type @@ -92,9 +78,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (UnknownBindingFlagsAndName), nameof (UnknownBindingFlagsAndName.SomeProperty), (Type[]) null)] static void TestUnknownBindingFlagsAndName (BindingFlags bindingFlags, string name) { // Since the binding flags and name are not known linker should mark all properties on the type @@ -121,9 +104,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (Array), nameof (Array.LongLength))] static void TestPropertyOfArray () { var property = typeof (int[]).GetProperty ("LongLength"); @@ -144,8 +124,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - messageCode: "IL2075", message: new string[] { "FindType", "GetProperty" })] + [ExpectedWarning ("IL2075", "FindType", "GetProperty")] static void TestDataFlowType () { Type type = FindType (); @@ -153,18 +132,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (IfClass), nameof (IfClass.SetterOnly), (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (IfClass), nameof (IfClass.GetterOnly), (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (ElseClass), nameof (ElseClass.SetterOnly), (Type[]) null)] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (ElseClass), nameof (ElseClass.GetterOnly), (Type[]) null)] static void TestIfElse (int i) { Type myType; @@ -183,18 +150,12 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string) }, - typeof (BaseClass), nameof (BaseClass.GetterSetterOnBaseClass), (Type[]) null)] static void TestPropertyInBaseType () { var property = typeof (DerivedClass).GetProperty ("GetterSetterOnBaseClass"); } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetProperty), new Type[] { typeof (string), typeof (BindingFlags) }, - typeof (IgnoreCaseBindingFlagsClass), nameof (IgnoreCaseBindingFlagsClass.SetterOnly), (Type[]) null)] static void TestIgnoreCaseBindingFlags () { var property = typeof (IgnoreCaseBindingFlagsClass).GetProperty ("setteronly", BindingFlags.IgnoreCase | BindingFlags.Public); diff --git a/test/Mono.Linker.Tests.Cases/Reflection/RunClassConstructorUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/RunClassConstructorUsedViaReflection.cs index e4670746c..0744577ec 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/RunClassConstructorUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/RunClassConstructorUsedViaReflection.cs @@ -7,6 +7,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] + [ExpectedNoWarnings] public class RunClassConstructorUsedViaReflection { public static void Main () @@ -20,7 +21,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestRunClassConstructor () { RuntimeHelpers.RunClassConstructor (typeof (OnlyUsedViaReflection).TypeHandle); @@ -33,7 +33,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestNull () { Type type = null; @@ -47,8 +46,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [UnrecognizedReflectionAccessPattern (typeof (RuntimeHelpers), nameof (RuntimeHelpers.RunClassConstructor), new Type[] { typeof (RuntimeTypeHandle) }, - messageCode: "IL2059", message: new string[] { "RunClassConstructor" })] + [ExpectedWarning ("IL2059", nameof (RuntimeHelpers) + "." + nameof (RuntimeHelpers.RunClassConstructor))] static void TestDataFlowType () { @@ -57,10 +55,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] - [UnrecognizedReflectionAccessPattern (typeof (RuntimeHelpers), nameof (RuntimeHelpers.RunClassConstructor), new Type[] { typeof (RuntimeTypeHandle) }, - messageCode: "IL2059")] - + [ExpectedWarning ("IL2059", nameof (RuntimeHelpers) + "." + nameof (RuntimeHelpers.RunClassConstructor))] static void TestIfElseUsingRuntimeTypeHandle (int i) { RuntimeTypeHandle myType; @@ -75,7 +70,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] static void TestIfElseUsingType (int i) { Type myType; diff --git a/test/Mono.Linker.Tests.Cases/Reflection/RuntimeReflectionExtensionsCalls.cs b/test/Mono.Linker.Tests.Cases/Reflection/RuntimeReflectionExtensionsCalls.cs index 068975d4c..6d71c7ad8 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/RuntimeReflectionExtensionsCalls.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/RuntimeReflectionExtensionsCalls.cs @@ -6,6 +6,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; namespace Mono.Linker.Tests.Cases.Reflection { #pragma warning disable 67 // The event {event} is not used + [ExpectedNoWarnings] public class RuntimeReflectionExtensionsCalls { public static void Main () @@ -19,8 +20,7 @@ namespace Mono.Linker.Tests.Cases.Reflection #region GetRuntimeEvent [Kept] - [UnrecognizedReflectionAccessPattern (typeof (RuntimeReflectionExtensions), nameof (RuntimeReflectionExtensions.GetRuntimeEvent), - new Type[] { typeof (Type), typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (RuntimeReflectionExtensions) + "." + nameof (RuntimeReflectionExtensions.GetRuntimeEvent))] public static void TestGetRuntimeEvent () { typeof (ClassWithKeptMembers).GetRuntimeEvent ("PublicEvent"); @@ -28,14 +28,13 @@ namespace Mono.Linker.Tests.Cases.Reflection typeof (ClassWithUnkeptMembers).GetRuntimeEvent ("ProtectedEvent"); GetClassWithEvent ().GetRuntimeEvent ("This string will not be reached"); typeof (Derived).GetRuntimeEvent ("Event"); - GetUnknownType ().GetRuntimeEvent (GetUnknownString ()); // UnrecognizedReflectionAccessPattern + GetUnknownType ().GetRuntimeEvent (GetUnknownString ()); // IL2072 } #endregion #region GetRuntimeField [Kept] - [UnrecognizedReflectionAccessPattern (typeof (RuntimeReflectionExtensions), nameof (RuntimeReflectionExtensions.GetRuntimeField), - new Type[] { typeof (Type), typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (RuntimeReflectionExtensions) + "." + nameof (RuntimeReflectionExtensions.GetRuntimeField))] public static void TestGetRuntimeField () { typeof (ClassWithKeptMembers).GetRuntimeField ("PublicField"); @@ -43,14 +42,13 @@ namespace Mono.Linker.Tests.Cases.Reflection typeof (ClassWithUnkeptMembers).GetRuntimeField ("ProtectedField"); GetClassWithField ().GetRuntimeField ("This string will not be reached"); typeof (Derived).GetRuntimeField ("Field"); - GetUnknownType ().GetRuntimeField (GetUnknownString ()); // UnrecognizedReflectionAccessPattern + GetUnknownType ().GetRuntimeField (GetUnknownString ()); // IL2072 } #endregion #region GetRuntimeMethod [Kept] - [UnrecognizedReflectionAccessPattern (typeof (RuntimeReflectionExtensions), nameof (RuntimeReflectionExtensions.GetRuntimeMethod), - new Type[] { typeof (Type), typeof (string), typeof (Type[]) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (RuntimeReflectionExtensions) + "." + nameof (RuntimeReflectionExtensions.GetRuntimeMethod))] public static void TestGetRuntimeMethod () { typeof (ClassWithKeptMembers).GetRuntimeMethod ("PublicMethod", Type.EmptyTypes); @@ -58,14 +56,13 @@ namespace Mono.Linker.Tests.Cases.Reflection typeof (ClassWithUnkeptMembers).GetRuntimeMethod ("ProtectedMethod", Type.EmptyTypes); GetClassWithMethod ().GetRuntimeMethod ("This string will not be reached", Type.EmptyTypes); typeof (Derived).GetRuntimeMethod ("Method", Type.EmptyTypes); - GetUnknownType ().GetRuntimeMethod (GetUnknownString (), Type.EmptyTypes); // UnrecognizedReflectionAccessPattern + GetUnknownType ().GetRuntimeMethod (GetUnknownString (), Type.EmptyTypes); // IL2072 } #endregion #region GetRuntimeProperty [Kept] - [UnrecognizedReflectionAccessPattern (typeof (RuntimeReflectionExtensions), nameof (RuntimeReflectionExtensions.GetRuntimeProperty), - new Type[] { typeof (Type), typeof (string) }, messageCode: "IL2072")] + [ExpectedWarning ("IL2072", nameof (RuntimeReflectionExtensions) + "." + nameof (RuntimeReflectionExtensions.GetRuntimeProperty))] public static void TestGetRuntimeProperty () { typeof (ClassWithKeptMembers).GetRuntimeProperty ("PublicProperty"); @@ -73,7 +70,7 @@ namespace Mono.Linker.Tests.Cases.Reflection typeof (ClassWithUnkeptMembers).GetRuntimeProperty ("ProtectedProperty"); GetClassWithProperty ().GetRuntimeProperty ("This string will not be reached"); typeof (Derived).GetRuntimeProperty ("Property"); - GetUnknownType ().GetRuntimeProperty (GetUnknownString ()); // UnrecognizedReflectionAccessPattern + GetUnknownType ().GetRuntimeProperty (GetUnknownString ()); // IL2072 } #endregion diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs index 0f660e6ed..8cab53e83 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflection.cs @@ -47,7 +47,6 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [RecognizedReflectionAccessPattern] public static void TestNull () { const string reflectionTypeKeptString = null; @@ -133,9 +132,6 @@ namespace Mono.Linker.Tests.Cases.Reflection public class AType { } [Kept] - [RecognizedReflectionAccessPattern ( - typeof (Type), nameof (Type.GetType), new Type[] { typeof (string), typeof (bool) }, - typeof (AType), null, (Type[]) null)] public static void TestType () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+AType"; @@ -267,7 +263,7 @@ namespace Mono.Linker.Tests.Cases.Reflection public class CaseInsensitive { } [Kept] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Boolean,Boolean)'")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Boolean, Boolean)'")] static void TestTypeUsingCaseInsensitiveFlag () { const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseInsensitive, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; @@ -277,7 +273,7 @@ namespace Mono.Linker.Tests.Cases.Reflection public class CaseUnknown { } [Kept] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Boolean,Boolean)'")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Boolean, Boolean)'")] static void TestTypeUsingCaseUnknownByTheLinker () { bool hideCase = GetCase (); @@ -297,7 +293,7 @@ namespace Mono.Linker.Tests.Cases.Reflection public class CaseUnknown2 { } [Kept] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Boolean,Boolean)'")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Boolean, Boolean)'")] static void TestTypeUsingCaseUnknownByTheLinker2 () { const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; @@ -328,7 +324,7 @@ namespace Mono.Linker.Tests.Cases.Reflection public class OverloadWith5ParametersWithIgnoreCase { } [Kept] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func<AssemblyName,Assembly>,Func<Assembly,String,Boolean,Type>,Boolean,Boolean)'")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean)'")] static void TestTypeOverloadWith5ParametersWithIgnoreCase () { const string reflectionTypeKeptString = "Mono.Linker.Tests.Cases.Reflection.TypeUsedViaReflection+OverloadWith5ParametersWithIgnoreCase"; @@ -361,15 +357,15 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [ExpectedWarning ("IL2026", "'System.Reflection.Assembly.GetType(String,Boolean)'")] - [ExpectedWarning ("IL2057", "'System.Type.GetType(String,Boolean)'")] + [ExpectedWarning ("IL2026", "'System.Reflection.Assembly.GetType(String, Boolean)'")] + [ExpectedWarning ("IL2057", "'System.Type.GetType(String, Boolean)'")] static Type GetTypeFromAssembly (Assembly assembly, string name, bool caseSensitive) { return assembly == null ? Type.GetType (name, caseSensitive) : assembly.GetType (name, caseSensitive); } [Kept] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Boolean,Boolean)'")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Boolean, Boolean)'")] static void TestUnkownIgnoreCase3Params (int num) { const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; @@ -378,7 +374,7 @@ namespace Mono.Linker.Tests.Cases.Reflection } [Kept] - [ExpectedWarning ("IL2096", "'System.Type.GetType(String,Func<AssemblyName,Assembly>,Func<Assembly,String,Boolean,Type>,Boolean,Boolean)'")] + [ExpectedWarning ("IL2096", "'System.Type.GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean)'")] static void TestUnkownIgnoreCase5Params (int num) { const string reflectionTypeKeptString = "mono.linker.tests.cases.reflection.TypeUsedViaReflection+CaseUnknown2, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"; diff --git a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflectionTypeDoesntExist.cs b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflectionTypeDoesntExist.cs index ef69a23e7..3f6244c10 100644 --- a/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflectionTypeDoesntExist.cs +++ b/test/Mono.Linker.Tests.Cases/Reflection/TypeUsedViaReflectionTypeDoesntExist.cs @@ -5,7 +5,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.Reflection { [SetupCSharpCompilerToUse ("csc")] - [VerifyAllReflectionAccessPatternsAreValidated] + [ExpectedNoWarnings] public class TypeUsedViaReflectionTypeDoesntExist { public static void Main () diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs index e519cd9c4..58314a190 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresAttributeMismatch.cs @@ -21,18 +21,31 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [ExpectedNoWarnings] class RequiresAttributeMismatch { - [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "IBaseWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "IBaseWithRequires.Method()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "VirtualPropertyAnnotationInPropertyAndAccessor.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "PropertyAnnotationInPropertyAndAccessor.set", ProducedBy = ProducedBy.Trimmer)] + // Base/Derived and Implementation/Interface differs between linker and analyzer https://github.com/dotnet/linker/issues/2533 + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInAccesor.get")] + [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualPropertyAnnotationInAccesor.get", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInAccesor.set", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.get", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "DerivedClassWithAllWarnings.VirtualPropertyAnnotationInProperty.set", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualMethod()")] + [ExpectedWarning ("IL2026", "DerivedClassWithRequires.VirtualMethod()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "IBaseWithRequires.PropertyAnnotationInAccesor.get")] + [ExpectedWarning ("IL2026", "IBaseWithRequires.PropertyAnnotationInPropertyAndAccessor.set", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "IBaseWithRequires.Method()")] + [ExpectedWarning ("IL2026", "ImplementationClassWithRequires.Method()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "ImplementationClassWithRequires.PropertyAnnotationInAccesor.get", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "ImplementationClassWithRequires.PropertyAnnotationInPropertyAndAccessor.get", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "ImplementationClassWithoutRequires.PropertyAnnotationInPropertyAndAccessor.get", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "ImplementationClassWithRequiresInSource.Method()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "ImplementationClassWithRequiresInSource.PropertyAnnotationInAccesor.get", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] + [ExpectedWarning ("IL2026", "BaseClassWithRequires.VirtualPropertyAnnotationInPropertyAndAccessor.get")] + [ExpectedWarning ("IL2026", "PropertyAnnotationInPropertyAndAccessor.set")] public static void Main () { @@ -285,9 +298,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [RequiresUnreferencedCode ("Message")] [RequiresAssemblyFiles ("Message")] [RequiresDynamicCode ("Message")] - [ExpectedWarning ("IL2046", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()")] - [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = ProducedBy.Analyzer)] - [ExpectedWarning ("IL3051", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = ProducedBy.Analyzer)] + // Linker member string format includes namespace of explicit interface method. + [ExpectedWarning ("IL2046", "ExplicitImplementationClassWithRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2046", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3003", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", "IBaseWithoutRequires.Method()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3051", "IBaseWithoutRequires.Method()", "ExplicitImplementationClassWithRequires.IBaseWithoutRequires.Method()", ProducedBy = ProducedBy.Analyzer)] void IBaseWithoutRequires.Method () { } @@ -356,9 +371,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability class ExplicitImplementationClassWithoutRequires : IBaseWithRequires { - [ExpectedWarning ("IL2046", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()")] - [ExpectedWarning ("IL3003", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", ProducedBy = ProducedBy.Analyzer)] - [ExpectedWarning ("IL3051", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", ProducedBy = ProducedBy.Analyzer)] + // Linker member string format includes namespace of explicit interface method. + [ExpectedWarning ("IL2046", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.Mono.Linker.Tests.Cases.RequiresCapability.RequiresAttributeMismatch.IBaseWithRequires.Method()", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2046", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3003", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL3051", "IBaseWithRequires.Method()", "ExplicitImplementationClassWithoutRequires.IBaseWithRequires.Method()", ProducedBy = ProducedBy.Analyzer)] void IBaseWithRequires.Method () { } diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapabilityReflectionAnalysisEnabled.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapabilityReflectionAnalysisEnabled.cs index 87b55c757..856c3d4a8 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapabilityReflectionAnalysisEnabled.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresCapabilityReflectionAnalysisEnabled.cs @@ -8,6 +8,7 @@ using Mono.Linker.Tests.Cases.Expectations.Metadata; namespace Mono.Linker.Tests.Cases.RequiresCapability { + [ExpectedNoWarnings] public class RequiresCapabilityReflectionAnalysisEnabled { [LogContains ("-- DynamicallyAccessedMembersEnabled --")] @@ -24,7 +25,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("-- DynamicallyAccessedMembersEnabled --")] - [RecognizedReflectionAccessPattern] static void TestRequiresAttributeWithDynamicallyAccessedMembersEnabled () { typeof (TypeWithPublicFieldsAccessed).RequiresPublicFields (); @@ -42,7 +42,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("-- ReflectionPattern --")] - [RecognizedReflectionAccessPattern] static void TestRequiresAttributeWithReflectionPattern () { typeof (TypeWithMethodAccessed).GetMethod ("PublicMethod"); @@ -60,7 +59,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("-- DynamicallyAccessedMembersOnGenericsEnabled --")] - [RecognizedReflectionAccessPattern] static void TestRequiresAttributeWithDynamicallyAccessedMembersOnGenericsEnabled () { TypeRequiresPublicFields<TypeWithPublicFieldsForGenericType>.Method (); @@ -104,13 +102,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability } [Kept] - [ExpectedNoWarnings] class TestRequiresAndDynamicallyAccessedMembers { [Kept] [KeptAttributeAttribute (typeof (RequiresUnreferencedCodeAttribute))] [RequiresUnreferencedCode ("--- RequiresAndPublicMethods ---")] - [RecognizedReflectionAccessPattern] static void RequiresAndPublicMethods ( [KeptAttributeAttribute(typeof(DynamicallyAccessedMembersAttribute))] [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs index 46f519aec..a58f7fa8a 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresInCompilerGeneratedCode.cs @@ -94,7 +94,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability _ = _default.Value; } - [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] static IEnumerable<int> TestDynamicallyAccessedMethod () { typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); @@ -264,7 +264,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability _ = _default.Value; } - [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] static async void TestDynamicallyAccessedMethod () { typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); @@ -436,7 +436,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability _ = _default.Value; } - [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] static async IAsyncEnumerable<int> TestDynamicallyAccessedMethod () { typeof (TypeWithMethodWithRequires).RequiresNonPublicMethods (); @@ -999,7 +999,6 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability Action _ = () => MethodWithRequires (); } - // The warning is currently not detected by roslyn analyzer since it doesn't analyze DAM yet [ExpectedWarning ("IL2067", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)] [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] @@ -1075,7 +1074,8 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability }; } - // The warning is currently not detected by roslyn analyzer since it doesn't analyze DAM yet + // TODO: Fix the discrepancy between linker and analyzer + // https://github.com/dotnet/linker/issues/2350 [ExpectedWarning ("IL2077", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)] [RequiresUnreferencedCode ("Suppress in body")] [RequiresAssemblyFiles ("Suppress in body")] @@ -1146,7 +1146,7 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability } } - [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true, ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--TypeWithMethodWithRequires.MethodWithRequires--", CompilerGeneratedCode = true)] static IEnumerable<int> TestDynamicallyAccessedMethodViaGenericMethodParameterInIterator () { yield return 1; @@ -1260,8 +1260,8 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability MethodWithRequires (); } - [ExpectedWarning ("IL2026", "Requires to suppress", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "Requires to suppress", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "Requires to suppress")] + [ExpectedWarning ("IL2026", "Requires to suppress")] public static void Test () { // This is not a 100% reliable test, since in theory it can be marked in any order and so it could happen that the diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs index 376309f8e..639846b80 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresOnClass.cs @@ -429,11 +429,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability class ReflectionAccessOnMethod { // Analyzer still dont understand RUC on type - [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method(Int32)", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method()", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()")] + [ExpectedWarning ("IL2026", "BaseWithoutRequiresOnType.Method()")] + [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method(Int32)")] + [ExpectedWarning ("IL2026", "InterfaceWithoutRequires.Method()")] + [ExpectedWarning ("IL2026", "ImplementationWithRequiresOnType.Method()")] static void TestDAMAccess () { // Warns because BaseWithoutRequiresOnType.Method as RUC on the method @@ -511,11 +511,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability public DerivedWithRequiresOnBaseWithoutRequires () { } } - [ExpectedWarning ("IL2026", "BaseWithRequires.BaseWithRequires()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "BaseWithRequires.BaseWithRequires()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "BaseWithRequires.BaseWithRequires()")] + [ExpectedWarning ("IL2026", "BaseWithRequires.BaseWithRequires()")] + [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithRequires.DerivedWithRequiresOnBaseWithRequires()")] + [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()")] + [ExpectedWarning ("IL2026", "DerivedWithRequiresOnBaseWithoutRequires.DerivedWithRequiresOnBaseWithoutRequires()")] static void TestDAMAccess () { // Warns because the type has Requires @@ -577,11 +577,11 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability public static int DerivedStaticField; } - [ExpectedWarning ("IL2026", "WithRequires.StaticField", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.StaticField", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.StaticField", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticField", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticField", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "WithRequires.StaticField")] + [ExpectedWarning ("IL2026", "WithRequires.StaticField")] + [ExpectedWarning ("IL2026", "WithRequires.StaticField")] + [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticField")] + [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticField")] static void TestDAMAccess () { typeof (WithRequires).RequiresPublicFields (); @@ -709,16 +709,16 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability public static int DerivedStaticProperty { get; set; } } - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.set", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.get", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.set", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.get")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set")] + [ExpectedWarning ("IL2026", "WithRequires.StaticProperty.set")] + [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.get")] + [ExpectedWarning ("IL2026", "WithRequires.PrivateStaticProperty.set")] + [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.get")] + [ExpectedWarning ("IL2026", "DerivedWithRequires.DerivedStaticProperty.set")] static void TestDAMAccess () { typeof (WithRequires).RequiresPublicProperties (); diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs index 0290a7966..7ad701822 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresViaDataflow.cs @@ -15,8 +15,10 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [ExpectedNoWarnings] class RequiresViaDataflow { - [ExpectedWarning ("IL2026", "--DynamicallyAccessedTypeWithRequires.MethodWithRequires--", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "--BaseType.VirtualMethodRequires--", ProducedBy = ProducedBy.Trimmer)] + // Base/Derived and Implementation/Interface differs between linker and analyzer https://github.com/dotnet/linker/issues/2533 + [ExpectedWarning ("IL2026", "--DynamicallyAccessedTypeWithRequires.MethodWithRequires--")] + [ExpectedWarning ("IL2026", "TypeWhichOverridesMethod.VirtualMethodRequires()", "--TypeWhichOverridesMethod.VirtualMethodRequires--", ProducedBy = ProducedBy.Analyzer)] + [ExpectedWarning ("IL2026", "BaseType.VirtualMethodRequires()", "--BaseType.VirtualMethodRequires--")] public static void Main () { TestDynamicallyAccessedMembersWithRequires (typeof (DynamicallyAccessedTypeWithRequires)); diff --git a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs index 9c60e7772..facd4cf73 100644 --- a/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs +++ b/test/Mono.Linker.Tests.Cases/RequiresCapability/RequiresWithCopyAssembly.cs @@ -32,8 +32,8 @@ namespace Mono.Linker.Tests.Cases.RequiresCapability [ExpectedNoWarnings] class RequiresWithCopyAssembly { - [ExpectedWarning ("IL2026", "--IDerivedInterface.MethodInDerivedInterface--", ProducedBy = ProducedBy.Trimmer)] - [ExpectedWarning ("IL2026", "--IBaseInterface.MethodInBaseInterface--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--IDerivedInterface.MethodInDerivedInterface--")] + [ExpectedWarning ("IL2026", "--IBaseInterface.MethodInBaseInterface--")] public static void Main () { TestRequiresInMethodFromCopiedAssembly (); diff --git a/test/Mono.Linker.Tests/TestCases/Dependencies/SortedWarnings.txt b/test/Mono.Linker.Tests/TestCases/Dependencies/SortedWarnings.txt index 2ef14654e..e2c474b3d 100644 --- a/test/Mono.Linker.Tests/TestCases/Dependencies/SortedWarnings.txt +++ b/test/Mono.Linker.Tests/TestCases/Dependencies/SortedWarnings.txt @@ -1,9 +1,9 @@ ILLink: Trim analysis warning IL2026: library: Using member 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.RUCType.RUCType()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. --RUCType--. -ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.NestedType.Warning3(): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type,String,Type[],Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. -ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.NestedType.Warning4<T>(List`1&): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type,String,Type[],Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. -ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.Warning2.get: '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type,String,Type[],Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. -ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.Main(): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type,String,Type[],Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. -ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.Warning1(): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type,String,Type[],Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. +ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.NestedType.Warning3(): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type, String, Type[], Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. +ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.NestedType.Warning4<T>(List`1&): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type, String, Type[], Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. +ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.Warning2.get: 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type, String, Type[], Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. +ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.Main(): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type, String, Type[], Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. +ILLink: Trim analysis warning IL2072: Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.Warning1(): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods', 'DynamicallyAccessedMemberTypes.NonPublicMethods' in call to 'System.Linq.Expressions.Expression.Call(Type, String, Type[], Expression[])'. The return value of method 'Mono.Linker.Tests.Cases.Warnings.Dependencies.TriggerWarnings_Lib.TriggerUnrecognizedPattern()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. ILLink: Trim analysis warning IL2075: Mono.Linker.Tests.Cases.Warnings.Individual.WarningsAreSorted.A.X(): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'System.Type.GetType(String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. ILLink: Trim analysis warning IL2075: Mono.Linker.Tests.Cases.Warnings.Individual.WarningsAreSorted.A.Y(): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'System.Type.GetType(String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. ILLink: Trim analysis warning IL2075: Mono.Linker.Tests.Cases.Warnings.Individual.WarningsAreSorted.B.X(): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The return value of method 'System.Type.GetType(String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. diff --git a/test/Mono.Linker.Tests/TestCasesRunner/LinkerCustomizations.cs b/test/Mono.Linker.Tests/TestCasesRunner/LinkerCustomizations.cs index f1f69b963..86bc82ce3 100644 --- a/test/Mono.Linker.Tests/TestCasesRunner/LinkerCustomizations.cs +++ b/test/Mono.Linker.Tests/TestCasesRunner/LinkerCustomizations.cs @@ -10,8 +10,6 @@ namespace Mono.Linker.Tests.TestCasesRunner { public TestDependencyRecorder DependencyRecorder { get; set; } - public TestReflectionPatternRecorder ReflectionPatternRecorder { get; set; } - public event Action<LinkContext> CustomizeContext; public void CustomizeLinkContext (LinkContext context) diff --git a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs index 9a983fba9..a2b8e095f 100644 --- a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs +++ b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -190,7 +190,7 @@ namespace Mono.Linker.Tests.TestCasesRunner protected virtual void AdditionalChecking (LinkedTestCaseResult linkResult, AssemblyDefinition original) { bool checkRemainingErrors = !HasAttribute (original.MainModule.GetType (linkResult.TestCase.ReconstructedFullTypeName), nameof (SkipRemainingErrorsValidationAttribute)); - VerifyLoggedMessages (original, linkResult.Logger, linkResult.Customizations.ReflectionPatternRecorder, checkRemainingErrors); + VerifyLoggedMessages (original, linkResult.Logger, checkRemainingErrors); VerifyRecordedDependencies (original, linkResult.Customizations.DependencyRecorder); } @@ -670,12 +670,11 @@ namespace Mono.Linker.Tests.TestCasesRunner yield return assembly; } - void VerifyLoggedMessages (AssemblyDefinition original, LinkerTestLogger logger, TestReflectionPatternRecorder reflectionPatternRecorder, bool checkRemainingErrors) + void VerifyLoggedMessages (AssemblyDefinition original, LinkerTestLogger logger, bool checkRemainingErrors) { List<MessageContainer> loggedMessages = logger.GetLoggedMessages (); List<(IMemberDefinition, CustomAttribute)> expectedNoWarningsAttributes = new List<(IMemberDefinition, CustomAttribute)> (); foreach (var attrProvider in GetAttributeProviders (original)) { - bool foundReflectionAccessPatternAttributesToVerify = false; foreach (var attr in attrProvider.CustomAttributes) { if (!IsProducedByLinker (attr)) continue; @@ -832,160 +831,6 @@ namespace Mono.Linker.Tests.TestCasesRunner } break; - case nameof (RecognizedReflectionAccessPatternAttribute): { - foundReflectionAccessPatternAttributesToVerify = true; - - // Special case for default .ctor - just trigger the overall verification on the method - // but don't verify any specific pattern. - if (attr.ConstructorArguments.Count == 0) - continue; - - string expectedSourceMember = GetFullMemberNameFromDefinition (attrProvider); - string expectedReflectionMember = GetFullMemberNameFromReflectionAccessPatternAttribute (attr, constructorArgumentsOffset: 0, out string expectedReflectionMemberGenericMember); - string expectedAccessedItem = GetFullMemberNameFromReflectionAccessPatternAttribute (attr, constructorArgumentsOffset: 3, out string _genericMember); - - var matchedPatterns = reflectionPatternRecorder.RecognizedPatterns.Where (pattern => { - if (GetFullMemberNameFromDefinition (pattern.Source) != expectedSourceMember) - return false; - - string actualAccessOperation = null; - if (pattern.SourceInstruction?.Operand is IMetadataTokenProvider sourceOperand) - actualAccessOperation = GetFullMemberNameFromDefinition (sourceOperand); - - if (actualAccessOperation != expectedReflectionMember) - return false; - - if (GetFullMemberNameFromDefinition (pattern.AccessedItem) != expectedAccessedItem) - return false; - - return true; - }); - - if (!matchedPatterns.Any ()) { - string sourceMemberCandidates = string.Join (Environment.NewLine, reflectionPatternRecorder.RecognizedPatterns - .Where (p => GetFullMemberNameFromDefinition (p.Source)?.ToLowerInvariant ()?.Contains (expectedReflectionMember.ToLowerInvariant ()) == true) - .Select (p => "\t" + RecognizedReflectionAccessPatternToString (p))); - string reflectionMemberCandidates = string.Join (Environment.NewLine, reflectionPatternRecorder.RecognizedPatterns - .Where (p => GetFullMemberNameFromDefinition (p.SourceInstruction?.Operand as IMetadataTokenProvider)?.ToLowerInvariant ()?.Contains (expectedReflectionMember.ToLowerInvariant ()) == true) - .Select (p => "\t" + RecognizedReflectionAccessPatternToString (p))); - - Assert.Fail ( - $"Expected to find recognized reflection access pattern '{expectedSourceMember}: Usage of {expectedReflectionMember} accessed {expectedAccessedItem}'{Environment.NewLine}" + - $"Potential patterns matching the source member: {Environment.NewLine}{sourceMemberCandidates}{Environment.NewLine}" + - $"Potential patterns matching the reflection member: {Environment.NewLine}{reflectionMemberCandidates}{Environment.NewLine}" + - $"If there's no matches, try to specify just a part of the source member or reflection member name and rerun the test to get potential matches."); - } - - reflectionPatternRecorder.RecognizedPatterns.Remove (matchedPatterns.First ()); - } - break; - - case nameof (UnrecognizedReflectionAccessPatternAttribute): { - Debug.Assert (attr.ConstructorArguments[0].Type.MetadataType != MetadataType.String); - - foundReflectionAccessPatternAttributesToVerify = true; - - string expectedSourceMember = GetFullMemberNameFromDefinition (attrProvider); - string expectedReflectionMember = GetFullMemberNameFromReflectionAccessPatternAttribute (attr, constructorArgumentsOffset: 0, out string expectedReflectionMemberGenericMember); - string expectedReflectionMemberWithoutReturnType = GetFullMemberNameFromReflectionAccessPatternAttribute (attr, constructorArgumentsOffset: 0, out string _genericType, includeReturnType: false); - string[] expectedMessageParts = GetMessagePartsFromReflectionAccessPatternAttribute (attr, 3); - int? expectedMessageCode = null; - if (attr.ConstructorArguments.Count >= 5) { - var codeString = (string) attr.ConstructorArguments[4].Value; - if (codeString != null) { - if (!codeString.StartsWith ("IL")) - Assert.Fail ($"The warning code specified in {nameof (UnrecognizedReflectionAccessPatternAttribute)} must start with the 'IL' prefix. Specified value: '{codeString}'"); - expectedMessageCode = int.Parse (codeString.Substring (2)); - } - } - - // Validate expected unrecognized patterns by looking for them in both the logged messages and the recorded unrecognized patterns. - // Checking for both here ensures that the unrecognized pattern attributes use the same signature formats as the logged warnings. - // The Roslyn analyzer will treat these attributes similarly, checking them against logged diagnostics only. - // Eventually this should go away as we replace UnrecognizedReflectionAccessPatternAttribute with ExpectedWarningAttribute. - - var matchedMessages = loggedMessages.Where (mc => { - if (mc.Category != MessageCategory.Warning) - return false; - - if (!LogMessageHasSameOriginMember (mc, attrProvider)) - return false; - - if (!mc.Text.Contains (expectedReflectionMemberWithoutReturnType)) - return false; - - if (expectedReflectionMemberGenericMember != null && !mc.Text.Contains (expectedReflectionMemberGenericMember)) - return false; - - // Note: string.Compare(string, StringComparison) doesn't exist in .NET Framework API set - if (expectedMessageParts != null && expectedMessageParts.Any (p => mc.Text.IndexOf (p, StringComparison.Ordinal) < 0)) - return false; - - if (expectedMessageCode.HasValue && mc.Code != expectedMessageCode.Value) - return false; - - return true; - }).ToList (); - - var matchedPatterns = reflectionPatternRecorder.UnrecognizedPatterns.Where (pattern => { - if (GetFullMemberNameFromDefinition (pattern.Source) != expectedSourceMember) - return false; - - string actualAccessOperation = null; - string actualAccessGenericMember = null; - if (pattern.SourceInstruction?.Operand is IMetadataTokenProvider sourceOperand) - actualAccessOperation = GetFullMemberNameFromDefinition (sourceOperand); - else - actualAccessOperation = GetFullMemberNameFromDefinition (pattern.AccessedItem, out actualAccessGenericMember); - - if (actualAccessOperation != expectedReflectionMember) - return false; - - if (actualAccessGenericMember != expectedReflectionMemberGenericMember) - return false; - - if (expectedMessageParts != null && expectedMessageParts.Any (p => pattern.Message.IndexOf (p, StringComparison.Ordinal) < 0)) - return false; - - if (expectedMessageCode.HasValue && pattern.MessageCode != expectedMessageCode.Value) - return false; - - return true; - }).ToList (); - - if (matchedMessages.Any ()) - loggedMessages.Remove (matchedMessages.First ()); - - if (matchedPatterns.Any ()) - reflectionPatternRecorder.UnrecognizedPatterns.Remove (matchedPatterns.First ()); - - string expectedUnrecognizedPatternMessage = - $"Expected to find unrecognized reflection access pattern '{(expectedMessageCode == null ? "" : ("IL" + expectedMessageCode + " "))}" + - $"{expectedSourceMember}: Usage of {expectedReflectionMember} unrecognized " + - $"{(expectedMessageParts == null ? string.Empty : "and message contains " + string.Join (" ", expectedMessageParts.Select (p => "'" + p + "'")))}"; - - Assert.AreEqual (matchedMessages.Count, matchedPatterns.Count, - $"Inconsistency between logged messages and recorded patterns.{Environment.NewLine}{expectedUnrecognizedPatternMessage}{Environment.NewLine}" + - $"Matched messages: {Environment.NewLine}{string.Join (Environment.NewLine, matchedMessages.Select (mc => "\t" + mc.Text))}{Environment.NewLine}" + - $"Matched unrecognized patterns: {Environment.NewLine}{string.Join (Environment.NewLine, matchedPatterns.Select (p => "\t" + RecognizedReflectionAccessPatternToString (p)))}{Environment.NewLine}"); - - if (!matchedMessages.Any ()) { - string sourceMemberCandidates = string.Join (Environment.NewLine, loggedMessages - .Where (mc => mc.Text.Contains (expectedSourceMember.ToLowerInvariant ())) - .Select (mc => "\t" + mc.Text)); - string reflectionMemberCandidates = string.Join (Environment.NewLine, loggedMessages - .Where (mc => mc.Text.Contains (expectedReflectionMember.ToLowerInvariant ())) - .Select (mc => "\t" + mc.Text)); - - Assert.Fail ( - $"{expectedUnrecognizedPatternMessage}{Environment.NewLine}" + - $"Potential messages matching the source member: {Environment.NewLine}{sourceMemberCandidates}{Environment.NewLine}" + - $"Potential messages matching the reflection member: {Environment.NewLine}{reflectionMemberCandidates}{Environment.NewLine}" + - $"If there's no matches, try to specify just a part of the source member or reflection member name and rerun the test to get potential matches."); - } - } - break; - case nameof (ExpectedNoWarningsAttribute): // Postpone processing of negative checks, to make it possible to mark some warnings as expected (will be removed from the list above) // and then do the negative check on the rest. @@ -995,52 +840,6 @@ namespace Mono.Linker.Tests.TestCasesRunner break; } } - - // Validate that there are no other reported unrecognized patterns on the member - if (foundReflectionAccessPatternAttributesToVerify) { - string expectedSourceMember = GetFullMemberNameFromDefinition (attrProvider); - var unrecognizedPatternsForSourceMember = reflectionPatternRecorder.UnrecognizedPatterns.Where (pattern => { - if (GetFullMemberNameFromDefinition (pattern.Source) != expectedSourceMember) - return false; - - return true; - }); - - if (unrecognizedPatternsForSourceMember.Any ()) { - string unrecognizedPatterns = string.Join (Environment.NewLine, unrecognizedPatternsForSourceMember - .Select (p => "\t" + UnrecognizedReflectionAccessPatternToString (p))); - - Assert.Fail ( - $"Member {expectedSourceMember} has either {nameof (RecognizedReflectionAccessPatternAttribute)} or {nameof (UnrecognizedReflectionAccessPatternAttribute)} attributes.{Environment.NewLine}" + - $"Some reported unrecognized patterns are not expected by the test (there's no matching attribute for them):{Environment.NewLine}" + - $"{unrecognizedPatterns}"); - } - } - } - - foreach (var typeToVerify in original.MainModule.AllDefinedTypes ()) { - foreach (var attr in typeToVerify.CustomAttributes) { - if (attr.AttributeType.Resolve ()?.Name == nameof (VerifyAllReflectionAccessPatternsAreValidatedAttribute)) { - // By now all verified recorded patterns were removed from the test recorder lists, so validate - // that there are no remaining patterns for this type. - var recognizedPatternsForType = reflectionPatternRecorder.RecognizedPatterns - .Where (pattern => (pattern.Source is IMemberDefinition member) && member.DeclaringType?.FullName == typeToVerify.FullName); - var unrecognizedPatternsForType = reflectionPatternRecorder.UnrecognizedPatterns - .Where (pattern => (pattern.Source is IMemberDefinition member) && member.DeclaringType?.FullName == typeToVerify.FullName); - - if (recognizedPatternsForType.Any () || unrecognizedPatternsForType.Any ()) { - string recognizedPatterns = string.Join (Environment.NewLine, recognizedPatternsForType - .Select (p => "\t" + RecognizedReflectionAccessPatternToString (p))); - string unrecognizedPatterns = string.Join (Environment.NewLine, unrecognizedPatternsForType - .Select (p => "\t" + UnrecognizedReflectionAccessPatternToString (p))); - - Assert.Fail ( - $"All reflection patterns should be verified by test attributes for type {typeToVerify.FullName}, but some were not: {Environment.NewLine}" + - $"Recognized patterns which were not verified: {Environment.NewLine}{recognizedPatterns}{Environment.NewLine}" + - $"Unrecognized patterns which were not verified: {Environment.NewLine}{unrecognizedPatterns}{Environment.NewLine}"); - } - } - } } foreach ((var attrProvider, var attr) in expectedNoWarningsAttributes) { @@ -1140,13 +939,6 @@ namespace Mono.Linker.Tests.TestCasesRunner } } - static void RemoveFromList<T> (List<T> list, IEnumerable<T> itemsToRemove) - { - foreach (var item in itemsToRemove.ToList ()) { - list.Remove (item); - } - } - void VerifyExpectedInstructionSequenceOnMemberInAssembly (CustomAttribute inAssemblyAttribute, TypeDefinition linkedType) { var originalType = GetOriginalTypeFromInAssemblyAttribute (inAssemblyAttribute); @@ -1169,77 +961,6 @@ namespace Mono.Linker.Tests.TestCasesRunner Assert.Fail ($"Invalid test assertion. No method named `{memberName}` exists on the original type `{originalType}`"); } - static string GetFullMemberNameFromReflectionAccessPatternAttribute (CustomAttribute attr, int constructorArgumentsOffset, out string genericMember, bool includeReturnType = true) - { - genericMember = null; - var type = (attr.ConstructorArguments[constructorArgumentsOffset].Value as TypeReference).Resolve (); - Debug.Assert (type != null); - var memberName = (string) attr.ConstructorArguments[constructorArgumentsOffset + 1].Value; - var parameterTypes = (CustomAttributeArgument[]) attr.ConstructorArguments[constructorArgumentsOffset + 2].Value; - - string genericParameter = null; - - static string GetFullName (TypeDefinition type, string memberName, CustomAttributeArgument[] parameterTypes) - { - string fullName = type.GetDisplayName (); - - if (memberName == null) - return fullName; - - fullName += "." + memberName; - if (memberName.EndsWith (".get") || memberName.EndsWith (".set")) - return fullName; - - if (parameterTypes != null) { - fullName += "("; - fullName += string.Join (",", parameterTypes.Select (pt => pt.Value switch { - TypeReference typeRef => typeRef.GetDisplayNameWithoutNamespace ().ToString (), - string str => str, - _ => throw new NotImplementedException () - })); - fullName += ")"; - } - - return fullName; - } - - var fullName = GetFullName (type, memberName, parameterTypes); - - if (attr.AttributeType.Name == "UnrecognizedReflectionAccessPatternAttribute") { - if (includeReturnType) { - var returnType = attr.ConstructorArguments[constructorArgumentsOffset + 5].Value; - if (returnType != null) - fullName = fullName.Insert (0, returnType.ToString () + " "); - } - - genericParameter = attr.ConstructorArguments[constructorArgumentsOffset + 6].Value as string; - } - - if (genericParameter != null) { - Debug.Assert (memberName == null || parameterTypes != null, - "Generic parameter should only be specified for types (with null memberName), or methods (with non-null parameterTypes)."); - - genericMember = fullName; - return genericParameter; - } - - return fullName; - } - - static string[] GetMessagePartsFromReflectionAccessPatternAttribute (CustomAttribute attr, int messageParameterIndex) - { - var messageParameter = attr.ConstructorArguments[messageParameterIndex].Value; - if (messageParameter is CustomAttributeArgument messageAttributeArgument) - messageParameter = messageAttributeArgument.Value; - - if (messageParameter is null) - return null; - else if (messageParameter is string messagePartString) - return new string[] { messagePartString }; - else - return ((CustomAttributeArgument[]) messageParameter).Select (p => (string) p.Value).ToArray (); - } - static string GetFullMemberNameFromDefinition (IMetadataTokenProvider member) { return GetFullMemberNameFromDefinition (member, out _); @@ -1253,7 +974,6 @@ namespace Mono.Linker.Tests.TestCasesRunner // parameter, and the full member name of the member which declares the generic parameter will be // returned via the out parameter. - genericMember = null; if (member == null) return null; @@ -1292,26 +1012,6 @@ namespace Mono.Linker.Tests.TestCasesRunner throw new NotImplementedException ($"Getting the full member name has not been implemented for {member}"); } - static string RecognizedReflectionAccessPatternToString (TestReflectionPatternRecorder.ReflectionAccessPattern pattern) - { - string operationDescription; - if (pattern.SourceInstruction?.Operand is IMetadataTokenProvider instructionOperand) { - operationDescription = "Usage of " + GetFullMemberNameFromDefinition (instructionOperand) + " accessed"; - } else - operationDescription = "Accessed"; - return $"{GetFullMemberNameFromDefinition (pattern.Source)}: {operationDescription} {GetFullMemberNameFromDefinition (pattern.AccessedItem)}"; - } - - static string UnrecognizedReflectionAccessPatternToString (TestReflectionPatternRecorder.ReflectionAccessPattern pattern) - { - string operationDescription; - if (pattern.SourceInstruction?.Operand is IMetadataTokenProvider instructionOperand) { - operationDescription = "Usage of " + GetFullMemberNameFromDefinition (instructionOperand) + " unrecognized"; - } else - operationDescription = "Usage of " + GetFullMemberNameFromDefinition (pattern.AccessedItem) + " unrecognized"; - return $"IL{pattern.MessageCode} {GetFullMemberNameFromDefinition (pattern.Source)}: {operationDescription} '{pattern.Message}'"; - } - protected TypeDefinition GetOriginalTypeFromInAssemblyAttribute (CustomAttribute inAssemblyAttribute) { string assemblyName; diff --git a/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs b/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs index fdcde52f7..888df76b3 100644 --- a/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs +++ b/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs @@ -95,15 +95,6 @@ namespace Mono.Linker.Tests.TestCasesRunner }; } - if (ValidatesReflectionAccessPatterns (_testCaseTypeDefinition)) { - customizations.ReflectionPatternRecorder = new TestReflectionPatternRecorder (); - customizations.CustomizeContext += context => { - customizations.ReflectionPatternRecorder.PreviousRecorder = context.ReflectionPatternRecorder; - context.ReflectionPatternRecorder = customizations.ReflectionPatternRecorder; - context.LogMessages = true; - }; - } - if (ValidatesLogMessages (_testCaseTypeDefinition)) { customizations.CustomizeContext += context => { context.LogMessages = true; @@ -111,26 +102,6 @@ namespace Mono.Linker.Tests.TestCasesRunner } } - bool ValidatesReflectionAccessPatterns (TypeDefinition testCaseTypeDefinition) - { - if (testCaseTypeDefinition.HasNestedTypes) { - var nestedTypes = new Queue<TypeDefinition> (testCaseTypeDefinition.NestedTypes.ToList ()); - while (nestedTypes.Count > 0) { - if (ValidatesReflectionAccessPatterns (nestedTypes.Dequeue ())) - return true; - } - } - - if (testCaseTypeDefinition.CustomAttributes.Any (attr => - attr.AttributeType.Name == nameof (VerifyAllReflectionAccessPatternsAreValidatedAttribute)) - || testCaseTypeDefinition.AllMembers ().Concat (testCaseTypeDefinition.AllDefinedTypes ()).Any (m => m.CustomAttributes.Any (attr => - attr.AttributeType.Name == nameof (RecognizedReflectionAccessPatternAttribute) || - attr.AttributeType.Name == nameof (UnrecognizedReflectionAccessPatternAttribute)))) - return true; - - return false; - } - bool ValidatesLogMessages (TypeDefinition testCaseTypeDefinition) { if (testCaseTypeDefinition.HasNestedTypes) { diff --git a/test/Mono.Linker.Tests/TestCasesRunner/TestReflectionPatternRecorder.cs b/test/Mono.Linker.Tests/TestCasesRunner/TestReflectionPatternRecorder.cs deleted file mode 100644 index 7143952ed..000000000 --- a/test/Mono.Linker.Tests/TestCasesRunner/TestReflectionPatternRecorder.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; -using Mono.Cecil; -using Mono.Cecil.Cil; - -namespace Mono.Linker.Tests.TestCasesRunner -{ - public class TestReflectionPatternRecorder : IReflectionPatternRecorder - { - public IReflectionPatternRecorder PreviousRecorder; - - public struct ReflectionAccessPattern - { - public ICustomAttributeProvider Source; - public Instruction SourceInstruction; - public IMetadataTokenProvider AccessedItem; - public string Message; - public int MessageCode; - } - - public List<ReflectionAccessPattern> RecognizedPatterns = new List<ReflectionAccessPattern> (); - public List<ReflectionAccessPattern> UnrecognizedPatterns = new List<ReflectionAccessPattern> (); - - public void RecognizedReflectionAccessPattern (ICustomAttributeProvider source, Instruction sourceInstruction, IMetadataTokenProvider accessedItem) - { - PreviousRecorder?.RecognizedReflectionAccessPattern (source, sourceInstruction, accessedItem); - RecognizedPatterns.Add (new ReflectionAccessPattern { - Source = source, - SourceInstruction = sourceInstruction, - AccessedItem = accessedItem - }); - } - - public void UnrecognizedReflectionAccessPattern (in MessageOrigin origin, ICustomAttributeProvider source, Instruction sourceInstruction, IMetadataTokenProvider accessedItem, string message, int messageCode) - { - PreviousRecorder?.UnrecognizedReflectionAccessPattern (origin, source, sourceInstruction, accessedItem, message, messageCode); - UnrecognizedPatterns.Add (new ReflectionAccessPattern { - Source = source, - SourceInstruction = sourceInstruction, - AccessedItem = accessedItem, - Message = message, - MessageCode = messageCode - }); - } - } -} diff --git a/test/Mono.Linker.Tests/Tests/GetDisplayNameTests.cs b/test/Mono.Linker.Tests/Tests/GetDisplayNameTests.cs index 2b3075850..7efb6c8df 100644 --- a/test/Mono.Linker.Tests/Tests/GetDisplayNameTests.cs +++ b/test/Mono.Linker.Tests/Tests/GetDisplayNameTests.cs @@ -23,22 +23,30 @@ namespace Mono.Linker.Tests switch (member.MetadataToken.TokenType) { case TokenType.TypeRef: case TokenType.TypeDef: - var x = (member as TypeReference).GetDisplayName (); Assert.AreEqual (expectedDisplayName, (member as TypeReference).GetDisplayName ()); break; case TokenType.MemberRef: case TokenType.Method: - var y = (member as MethodReference).GetDisplayName (); Assert.AreEqual (expectedDisplayName, (member as MethodReference).GetDisplayName ()); break; + case TokenType.Field: + Assert.AreEqual (expectedDisplayName, (member as FieldReference).GetDisplayName ()); + break; default: throw new NotImplementedException (); } - } public static IEnumerable<TestCaseData> GetMemberAssertions (Type type) => MemberAssertionsCollector.GetMemberAssertionsData (type); + [DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.Field")] + public int Field; + + [DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.MultipleParameters(Int32, Int32)")] + public static void MultipleParameters (int a, int b) + { + } + [DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.A")] public class A { @@ -127,7 +135,7 @@ namespace Mono.Linker.Tests [DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.GenericClassOneParameter<T>.NestedGenericClassOneParameter<S>.Delegate<U>")] public delegate void Delegate<U> (U p); - [DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.GenericClassOneParameter<T>.NestedGenericClassOneParameter<S>.MethodGenericArray<U,V>(IList<U>,V)")] + [DisplayName ("Mono.Linker.Tests.GetDisplayNameTests.GenericClassOneParameter<T>.NestedGenericClassOneParameter<S>.MethodGenericArray<U,V>(IList<U>, V)")] public void MethodGenericArray<U, V> (IList<U> p, V q) { } |