From fececde104a79cef6bbbffb600418027832d3615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 26 Mar 2026 12:41:26 +0900 Subject: [PATCH] Copy tests over to illink --- .../BasicTests.g.cs | 126 ++++++++++++++++++ .../MultiAssemblyTests.g.cs | 31 +++++ .../Mono.Linker.Tests.Cases/Basic/Calli.cs | 28 ++++ .../Resources_EmbeddedResource.txt | 1 + .../Basic/ExceptionRegions.cs | 52 ++++++++ .../Mono.Linker.Tests.Cases/Basic/FieldRVA.cs | 13 ++ .../Basic/FieldSignature.cs | 24 ++++ .../Basic/FieldsOfEnum.cs | 33 +++++ .../Basic/Finalizer.cs | 33 +++++ .../Mono.Linker.Tests.Cases/Basic/First.cs | 33 +++++ .../Basic/FunctionPointer.cs | 25 ++++ .../Basic/GenericParameters.cs | 19 +++ .../Basic/GenericType.cs | 34 +++++ .../Basic/InstanceFields.cs | 30 +++++ .../Basic/InterfaceCalls.cs | 35 +++++ .../Basic/InterfaceOrder.cs | 55 ++++++++ .../Basic/LibraryModeTest.cs | 48 +++++++ .../Basic/MethodSpecSignature.cs | 27 ++++ .../Basic/MultiDimArraySignature.cs | 20 +++ .../Basic/Resources.cs | 17 +++ .../Mono.Linker.Tests.Cases/Basic/Switch.cs | 59 ++++++++ .../Mono.Linker.Tests.Cases/Basic/TypeOf.cs | 20 +++ .../Basic/TypeSpecSignature.cs | 29 ++++ .../Basic/VirtualMethods.cs | 48 +++++++ .../MultiAssembly/Dependencies/Dep.cs | 14 ++ .../Dependencies/ForwardedType.cs | 15 +++ .../MultiAssembly/Dependencies/Forwarder.cs | 5 + .../Dependencies/TypeRefToAssembly_Library.cs | 6 + .../MultiAssembly/ForwarderReference.cs | 25 ++++ .../MultiAssembly/MultiAssembly.cs | 20 +++ .../MultiAssembly/TypeRefToAssembly.cs | 17 +++ 31 files changed, 942 insertions(+) create mode 100644 src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MultiAssemblyTests.g.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Calli.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Dependencies/Resources_EmbeddedResource.txt create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/ExceptionRegions.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldRVA.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldSignature.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldsOfEnum.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Finalizer.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/First.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FunctionPointer.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericParameters.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericType.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InstanceFields.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceCalls.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceOrder.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/LibraryModeTest.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MethodSpecSignature.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MultiDimArraySignature.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Resources.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Switch.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeOf.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeSpecSignature.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/VirtualMethods.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Dep.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/ForwardedType.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Forwarder.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/TypeRefToAssembly_Library.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/ForwarderReference.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/MultiAssembly.cs create mode 100644 src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/TypeRefToAssembly.cs diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs index 506ecf61be904f..98177101243d26 100644 --- a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/BasicTests.g.cs @@ -9,6 +9,12 @@ public sealed partial class BasicTests : LinkerTestBase protected override string TestSuiteName => "Basic"; + [Fact] + public Task Calli() + { + return RunTest(allowMissingWarnings: true); + } + [Fact] public Task ComplexNestedClassesHasUnusedRemoved() { @@ -21,30 +27,120 @@ public Task DelegateBeginInvokeEndInvokePair() return RunTest(allowMissingWarnings: true); } + [Fact] + public Task ExceptionRegions() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FieldRVA() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FieldSignature() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FieldsOfEnum() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task Finalizer() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task First() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task FunctionPointer() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericParameters() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task GenericType() + { + return RunTest(allowMissingWarnings: true); + } + [Fact] public Task InitializerForArrayIsKept() { return RunTest(allowMissingWarnings: true); } + [Fact] + public Task InstanceFields() + { + return RunTest(allowMissingWarnings: true); + } + [Fact] public Task InstantiatedTypeWithOverridesFromObject() { return RunTest(allowMissingWarnings: true); } + [Fact] + public Task InterfaceCalls() + { + return RunTest(allowMissingWarnings: true); + } + [Fact] public Task InterfaceMethodImplementedOnBaseClassDoesNotGetStripped() { return RunTest(allowMissingWarnings: true); } + [Fact] + public Task InterfaceOrder() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task LibraryModeTest() + { + return RunTest(allowMissingWarnings: true); + } + [Fact] public Task LinkerHandlesRefFields() { return RunTest(allowMissingWarnings: true); } + [Fact] + public Task MethodSpecSignature() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MultiDimArraySignature() + { + return RunTest(allowMissingWarnings: true); + } + [Fact] public Task MultiLevelNestedClassesAllRemovedWhenNonUsed() { @@ -63,6 +159,30 @@ public Task NeverInstantiatedTypeWithOverridesFromObject() return RunTest(allowMissingWarnings: true); } + [Fact] + public Task Resources() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task Switch() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeOf() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeSpecSignature() + { + return RunTest(allowMissingWarnings: true); + } + [Fact] public Task UninvokedInterfaceMemberGetsRemoved() { @@ -177,5 +297,11 @@ public Task UsedStructIsKept() return RunTest(allowMissingWarnings: true); } + [Fact] + public Task VirtualMethods() + { + return RunTest(allowMissingWarnings: true); + } + } } diff --git a/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MultiAssemblyTests.g.cs b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MultiAssemblyTests.g.cs new file mode 100644 index 00000000000000..2ad7e2f31771ed --- /dev/null +++ b/src/tools/illink/test/ILLink.RoslynAnalyzer.Tests/generated/ILLink.RoslynAnalyzer.Tests.Generator/ILLink.RoslynAnalyzer.Tests.TestCaseGenerator/MultiAssemblyTests.g.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using Xunit; + +namespace ILLink.RoslynAnalyzer.Tests +{ + public sealed partial class MultiAssemblyTests : LinkerTestBase + { + + protected override string TestSuiteName => "MultiAssembly"; + + [Fact] + public Task ForwarderReference() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task MultiAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + [Fact] + public Task TypeRefToAssembly() + { + return RunTest(allowMissingWarnings: true); + } + + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Calli.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Calli.cs new file mode 100644 index 00000000000000..ee39ec982b700d --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Calli.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [SetupCompileArgument("/unsafe")] + [SkipILVerify] // ILVerify doesn't handle calli + [KeptMember(".cctor()")] + public unsafe class Calli + { + [Kept] + private static readonly delegate* _pfn = null; + + public static void Main() + { + CallCalli(null); + } + + [Kept] + static void CallCalli(object o) + { + _pfn(o); + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Dependencies/Resources_EmbeddedResource.txt b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Dependencies/Resources_EmbeddedResource.txt new file mode 100644 index 00000000000000..b2747dea2cca51 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Dependencies/Resources_EmbeddedResource.txt @@ -0,0 +1 @@ +Embedded resource content diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/ExceptionRegions.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/ExceptionRegions.cs new file mode 100644 index 00000000000000..ee0f19ea47f40a --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/ExceptionRegions.cs @@ -0,0 +1,52 @@ +// 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 Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + public class ExceptionRegions + { + [Kept] + static void Main() + { + try + { + A(); + } + catch (CustomException ce) + { + Console.WriteLine(ce.Message); + try + { + B(); + } + catch (Exception e) when (e.InnerException != null) + { + Console.WriteLine(e.Message); + } + } + finally + { + C(); + } + } + + [Kept] + static void A() { } + + [Kept] + static void B() { throw new Exception(); } + + [Kept] + static void C() { } + } + + [Kept] + [KeptBaseType(typeof(Exception))] + class CustomException : Exception + { + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldRVA.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldRVA.cs new file mode 100644 index 00000000000000..6bb5ec20c7e20b --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldRVA.cs @@ -0,0 +1,13 @@ +using System; +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class FieldRVA + { + [Kept] + [KeptInitializerData] + static int Main() => new byte[] { 1, 2, 3, 4, 5 }.Length; + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldSignature.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldSignature.cs new file mode 100644 index 00000000000000..a74d1fe2dcb3a7 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldSignature.cs @@ -0,0 +1,24 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using System; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class FieldSignature + { + [Kept] + static FieldType field; + + [Kept] + static void Main() + { + field = null; + _ = field; + } + + [Kept] + class FieldType + { + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldsOfEnum.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldsOfEnum.cs new file mode 100644 index 00000000000000..edb9cce4e6217c --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FieldsOfEnum.cs @@ -0,0 +1,33 @@ +// 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 Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class FieldsOfEnum + { + [Kept] + static void Main() + { + Console.WriteLine($"{MyEnum.A}"); + } + } + + [Kept] + [KeptMember("value__")] + [KeptBaseType(typeof(Enum))] + public enum MyEnum + { + [Kept] + A = 0, + + [Kept] + B = 1, + + [Kept] + C = 2, + }; +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Finalizer.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Finalizer.cs new file mode 100644 index 00000000000000..6cedb0642cbbd2 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Finalizer.cs @@ -0,0 +1,33 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using System; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class Finalizer + { + static void Main() + { + MentionUnallocatedType(null); + new AllocatedTypeWithFinalizer(); + } + + [Kept] + static void MentionUnallocatedType(UnallocatedTypeWithFinalizer u) { } + + [Kept] + class UnallocatedTypeWithFinalizer + { + // Not kept + ~UnallocatedTypeWithFinalizer() { } + } + + [Kept] + [KeptMember(".ctor()")] + class AllocatedTypeWithFinalizer + { + [Kept] + ~AllocatedTypeWithFinalizer() { } + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/First.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/First.cs new file mode 100644 index 00000000000000..e558f4860846b7 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/First.cs @@ -0,0 +1,33 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + #pragma warning disable 169 + + [Kept] + public class First + { + static int Field; + + [Kept] + static int FirstMethod() => 300; + + [Kept] + static int Main() + { + return FirstMethod(); + } + + static void LastMethod(int someParameter) { } + } + + class FirstType + { + static void Method() { } + } + + class AnotherType + { + static void Method() { } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FunctionPointer.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FunctionPointer.cs new file mode 100644 index 00000000000000..84f0e6c96f89b1 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/FunctionPointer.cs @@ -0,0 +1,25 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + [SetupCompileArgument("/unsafe")] + unsafe class FunctionPointer + { + [Kept] + static void Main() + { + MethodTakingFunctionPointer(null); + } + + [Kept] + static void MethodTakingFunctionPointer(delegate* del) { } + + [Kept] + class OneType { } + + [Kept] + class OtherType { } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericParameters.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericParameters.cs new file mode 100644 index 00000000000000..f6185e81458019 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericParameters.cs @@ -0,0 +1,19 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class GenericParameters + { + [Kept] + public static void Main() + { + var t = typeof(A<>).ToString(); + } + + [Kept] + class A + { + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericType.cs new file mode 100644 index 00000000000000..3e3f8f8c610a5f --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/GenericType.cs @@ -0,0 +1,34 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class GenericType + { + [Kept] + public static void Main() + { + var c = new C(); + } + } + + [Kept] + [KeptMember(".ctor()")] + class A + { + } + + [Kept] + [KeptMember(".ctor()")] + [KeptBaseType(typeof(A))] + class B : A + { + } + + [Kept] + [KeptMember(".ctor()")] + [KeptBaseType(typeof(B))] + class C : B + { + } +} \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InstanceFields.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InstanceFields.cs new file mode 100644 index 00000000000000..eca6c6c5e3a56e --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InstanceFields.cs @@ -0,0 +1,30 @@ +// 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.Runtime.InteropServices; +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class InstanceFields + { + [Kept] + static void Main() + { + _ = new TypeWithSequentialLayout(); + } + } + + [Kept] + [KeptMember(".ctor()")] + [StructLayout(LayoutKind.Sequential)] + class TypeWithSequentialLayout + { + [Kept] + int Field = 42; + + static int StaticField; // Must not assign value, otherwise .cctor would keep the field + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceCalls.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceCalls.cs new file mode 100644 index 00000000000000..ae4e7285440d8b --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceCalls.cs @@ -0,0 +1,35 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class InterfaceCalls + { + [Kept] + static void Main() + { + ISimpleInterface simpleInterface = new SimpleType(); + simpleInterface.InterfaceMethod(); + } + + [Kept] + interface ISimpleInterface + { + [Kept] + void InterfaceMethod(); + void UnusedMethod(); + } + + interface ISimpleUnusedInterface { } + + [Kept] + [KeptMember(".ctor()")] + [KeptInterface(typeof(ISimpleInterface))] + class SimpleType : ISimpleInterface, ISimpleUnusedInterface + { + [Kept] + public virtual void InterfaceMethod() { } + public virtual void UnusedMethod() { } + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceOrder.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceOrder.cs new file mode 100644 index 00000000000000..3f89243bc5d8be --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/InterfaceOrder.cs @@ -0,0 +1,55 @@ +// 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 Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class InterfaceOrder + { + [Kept] + static void Main() + { + I1 c1 = new C1(); + c1.Method(); + I2 c2 = new C2(); + c2.Method(); + } + [Kept] + interface I1 + { + [Kept] + void Method(); + } + + [Kept] + interface I2 + { + [Kept] + void Method(); + } + + [Kept] + [KeptMember(".ctor()")] + [KeptInterface(typeof(I1))] + [KeptInterface(typeof(I2))] + class C1 : I1, I2 + { + [Kept] + public void Method() { } + } + + [Kept] + [KeptMember(".ctor()")] + [KeptInterface(typeof(I1))] + [KeptInterface(typeof(I2))] + class C2 : I2, I1 + { + [Kept] + public void Method() { } + } + + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/LibraryModeTest.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/LibraryModeTest.cs new file mode 100644 index 00000000000000..bbe9e55670613d --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/LibraryModeTest.cs @@ -0,0 +1,48 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Basic +{ +#pragma warning disable 169 + + [SetupLinkerArgument("-a", "test", "library")] + [SetupLinkerArgument("--enable-opt", "ipconstprop")] + public class LibraryModeTest + { + static int Field; + + [Kept] + public LibraryModeTest() { } + + [Kept] + public void M1() { } + + [Kept] + public void M2() { } + + [Kept] + public void M3() { } + + [Kept] + public static int Main() + { + return 42; + } + void P_M1() { } + void P_M2() { } + void P_M3() { } + } + + internal class InternalType + { + public void M1() { } + } + + [Kept] + [KeptMember(".ctor()")] // Public types are assumed to be constructed + public class AnotherPublicType + { + [Kept] + public void M1() { } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MethodSpecSignature.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MethodSpecSignature.cs new file mode 100644 index 00000000000000..d1631ddc7e8c68 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MethodSpecSignature.cs @@ -0,0 +1,27 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class MethodSpecSignature + { + [Kept] + static void Main() + { + SomeType.SomeMethod(); + } + + [Kept] + class SomeType + { + [Kept] + public static void SomeMethod() { } + } + + [Kept] + class SomeOtherType + { + } + + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MultiDimArraySignature.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MultiDimArraySignature.cs new file mode 100644 index 00000000000000..9d2ba2db5ed8b4 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/MultiDimArraySignature.cs @@ -0,0 +1,20 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + class MultiDimArraySignature + { + [Kept] + static void Main() + { + SomeOtherType[,] multiDimArray = new SomeOtherType[4, 5]; + } + + [Kept] + class SomeOtherType + { + } + + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Resources.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Resources.cs new file mode 100644 index 00000000000000..bb414e06e8afc6 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Resources.cs @@ -0,0 +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 Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [SetupCompileResource("Dependencies/Resources_EmbeddedResource.txt", "EmbeddedResource.txt")] + [KeptResource("EmbeddedResource.txt")] + public class Resources + { + public static void Main() + { + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Switch.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Switch.cs new file mode 100644 index 00000000000000..4fef218aade039 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/Switch.cs @@ -0,0 +1,59 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + public class Switch + { + public static void Main() + { + TestSwitchStatement(1); + TestSwitchExpression(1); + } + + [Kept] + public static void TestSwitchStatement(int p) + { + switch (p) + { + case 0: Case1(); break; + case 1: Case1(); break; + case 3: Case1(); break; + case 4: Case1(); break; + case 5: Case1(); break; + case 6: Case1(); break; + case 7: Case1(); break; + case 8: Case1(); break; + case 9: Case1(); break; + case 10: Case1(); break; + default: + Case2(); + break; + } + } + + [Kept] + public static void Case1() { } + [Kept] + public static void Case2() { } + + [Kept] + public static int TestSwitchExpression(int p) => + p switch + { + 0 => 1, + 1 => 2, + 2 => 3, + 3 => 4, + 4 => 5, + 5 => 6, + 6 => 7, + 7 => 8, + 8 => 9, + 9 => 10, + _ => 0 + }; + } +} \ No newline at end of file diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeOf.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeOf.cs new file mode 100644 index 00000000000000..210f557760db44 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeOf.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ + public class TypeOf + { + public static void Main() + { + var t = typeof(TestType); + } + + [Kept] + class TestType + { + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeSpecSignature.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeSpecSignature.cs new file mode 100644 index 00000000000000..5db0d66c07b97e --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/TypeSpecSignature.cs @@ -0,0 +1,29 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Basic +{ + [Kept] + [SetupCompileArgument("/unsafe")] + unsafe class TypeSpecSignature + { + [Kept] + static void Main() + { + var reflectedType = typeof(SomeType); + TestUnsafe(); + } + + [Kept] + unsafe static void TestUnsafe() + { + void* p = null; + } + + [Kept] + class SomeType { } + + [Kept] + class SomeOtherType { } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/VirtualMethods.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/VirtualMethods.cs new file mode 100644 index 00000000000000..5beeac216438e1 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/Basic/VirtualMethods.cs @@ -0,0 +1,48 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.Basic +{ +#pragma warning disable 169 + + [Kept] + public class VirtualMethods + { + [Kept] + static void Main() + { + BaseType b = new DerivedType(); + b.Method1(); + + // TODO: uncomment once we're okay with ToString bringing the whole world into closure + //((object)default(MyValueType)).ToString(); + } + } + + [Kept] + class BaseType + { + [Kept] + public BaseType() { } + [Kept] + public virtual void Method1() { } + public virtual void Method2() { } + } + + [Kept] + [KeptBaseType(typeof(BaseType))] + class DerivedType : BaseType + { + [Kept] + public DerivedType() { } + [Kept] + public override void Method1() { } + public override void Method2() { } + } + + //[Kept] + //struct MyValueType + //{ + // [Kept] + // public override string ToString() => ""; + //} +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Dep.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Dep.cs new file mode 100644 index 00000000000000..dbf19ccecea5f3 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Dep.cs @@ -0,0 +1,14 @@ + +public class DepClass +{ + public static void Kept() + { + } + + public static void Trimmed() + { + } + + public static int KeptField; + public static int TrimmedField; +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/ForwardedType.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/ForwardedType.cs new file mode 100644 index 00000000000000..395820648f20f8 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/ForwardedType.cs @@ -0,0 +1,15 @@ + +public class ForwardedType +{ + public static void Kept() + { + } + + public static void Removed() + { + } + + public static int KeptField; + + public static int RemovedField; +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Forwarder.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Forwarder.cs new file mode 100644 index 00000000000000..77bbd7e85d7809 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/Forwarder.cs @@ -0,0 +1,5 @@ +using System.Runtime.CompilerServices; + +#if TEST_BUILD +[assembly: TypeForwardedTo(typeof(ForwardedType))] +#endif diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/TypeRefToAssembly_Library.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/TypeRefToAssembly_Library.cs new file mode 100644 index 00000000000000..0d2c8d80d83f37 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/Dependencies/TypeRefToAssembly_Library.cs @@ -0,0 +1,6 @@ +namespace TypeRefToAssembly_Library +{ + public class TestType + { + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/ForwarderReference.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/ForwarderReference.cs new file mode 100644 index 00000000000000..17ba6125c8a391 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/ForwarderReference.cs @@ -0,0 +1,25 @@ + +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.MultiAssembly +{ + [SetupLinkerAction ("link", "ForwardedType")] + [SetupCompileBefore("Forwarder.dll", new[] { "Dependencies/ForwardedType.cs" })] + + [SetupCompileAfter ("ForwardedType.dll", new[] { "Dependencies/ForwardedType.cs" })] + [SetupCompileAfter("Forwarder.dll", new[] { "Dependencies/Forwarder.cs" }, references: new[] { "ForwardedType.dll" }, defines: new[] { "TEST_BUILD" })] + + [KeptMemberInAssembly("ForwardedType.dll", typeof(ForwardedType), "Kept()")] + [KeptMemberInAssembly("ForwardedType.dll", typeof(ForwardedType), nameof(ForwardedType.KeptField))] + + [RemovedAssemblyReference("test", "Forwarder")] + public class ForwarderReference + { + public static void Main() + { + ForwardedType.Kept(); + ForwardedType.KeptField = 0; + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/MultiAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/MultiAssembly.cs new file mode 100644 index 00000000000000..089588ef5a6c36 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/MultiAssembly.cs @@ -0,0 +1,20 @@ + +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.MultiAssembly +{ + [SetupLinkerAction ("link", "Dep")] + [SetupCompileBefore("Dep.dll", new[] { "Dependencies/Dep.cs" })] + + [KeptMemberInAssembly("Dep.dll", typeof(DepClass), "Kept()")] + [KeptMemberInAssembly("Dep.dll", typeof(DepClass), nameof(DepClass.KeptField))] + public class MultiAssembly + { + public static void Main() + { + DepClass.Kept(); + DepClass.KeptField = 0; + } + } +} diff --git a/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/TypeRefToAssembly.cs b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/TypeRefToAssembly.cs new file mode 100644 index 00000000000000..00e06738c66df3 --- /dev/null +++ b/src/tools/illink/test/Mono.Linker.Tests.Cases/MultiAssembly/TypeRefToAssembly.cs @@ -0,0 +1,17 @@ +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.MultiAssembly +{ + [SetupLinkerAction("link", "lib")] + [SetupCompileBefore("lib.dll", new[] { "Dependencies/TypeRefToAssembly_Library.cs" })] + + [KeptTypeInAssembly("lib.dll", typeof(TypeRefToAssembly_Library.TestType))] + public class TypeRefToAssembly + { + public static void Main() + { + var t = typeof(TypeRefToAssembly_Library.TestType); + } + } +}