Skip to content

Commit

Permalink
Adds a test for multiple nested forwarders in a row with copy/link (d…
Browse files Browse the repository at this point in the history
…otnet#2372)

The problematic scenario is if there's a "copy" assembly with a forwarder to a "link" assembly with a forwarder. The forwarder is for a nested class.
Test for dotnet#2359.

Also improved the test infra to print out errors from ilasm if they happen.
  • Loading branch information
vitek-karas authored Nov 17, 2021
1 parent d2febca commit 57574f1
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public class ImplementationLibraryNestedType
public static int PropertyOnNestedType { get; set; }
}

public class ForwardedNestedType
{
}

public static int someField = 42;

public string GetSomeValue ()
Expand All @@ -33,6 +37,13 @@ public string GetSomeValue ()
}
}

public class AnotherImplementationClass
{
public class ForwardedNestedType
{
}
}

[AttributeUsage (AttributeTargets.All)]
public class ImplementationLibraryAttribute : Attribute
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.assembly extern mscorlib
{
}

.assembly extern Implementation
{
}

.assembly NestedForwarderLibrary
{
}

.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary
{
.assembly extern 'Implementation'
}
.class extern ForwardedNestedType
{
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
}

.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherImplementationClass
{
.assembly extern 'Implementation'
}
.class extern ForwardedNestedType
{
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
}

.module 'NestedForwarderLibrary.dll'
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.assembly extern mscorlib
{
}

.assembly extern NestedForwarderLibrary
{
}

.assembly NestedForwarderLibrary_2
{
}

.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary
{
.assembly extern 'NestedForwarderLibrary'
}
.class extern ForwardedNestedType
{
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
}

.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherImplementationClass
{
.assembly extern 'NestedForwarderLibrary'
}
.class extern ForwardedNestedType
{
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
}

.module 'NestedForwarderLibrary_2.dll'
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public class ImplementationLibraryNestedType
public static int PropertyOnNestedType { get; set; }
}

public class ForwardedNestedType
{
}

public static int someField = 0;

public string GetSomeValue ()
Expand All @@ -35,6 +39,13 @@ public string GetSomeValue ()
}
}

public class AnotherImplementationClass
{
public class ForwardedNestedType
{
}
}

[AttributeUsage (AttributeTargets.All)]
public class ImplementationLibraryAttribute : Attribute
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies;

namespace Mono.Linker.Tests.Cases.TypeForwarding
{
[SkipUnresolved (true)]

[SetupCompileBefore ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/ReferenceImplementationLibrary.cs" }, defines: new[] { "INCLUDE_REFERENCE_IMPL" })]

// After compiling the test case we then replace the reference impl with implementation + type forwarder
[SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })]
[SetupCompileAfter ("NestedForwarderLibrary.dll", new[] { "Dependencies/NestedForwarderLibrary.il" }, references: new[] { "Implementation.dll" })]
[SetupCompileAfter ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/NestedForwarderLibrary_2.il" }, references: new[] { "NestedForwarderLibrary.dll" })]

[SetupLinkerAction ("copy", "test")]
[SetupLinkerAction ("copy", "NestedForwarderLibrary_2")]
[SetupLinkerAction ("copyused", "NestedForwarderLibrary")]
[SetupLinkerAction ("copyused", "Implementation")]

// https://github.com/dotnet/linker/issues/2359
// One of the type forwarders in NestedForwarderLibrary will not be kept.
// Which one depends on order.
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
[KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
[KeptTypeInAssembly ("Implementation.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]

[KeptMember (".ctor()")]
class MultiForwardedTypesWithCopyUsed
{
static void Main ()
{
Console.WriteLine (typeof (ImplementationLibrary.ForwardedNestedType).FullName);
Console.WriteLine (typeof (AnotherImplementationClass.ForwardedNestedType).FullName);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies;

namespace Mono.Linker.Tests.Cases.TypeForwarding
{
[SkipUnresolved (true)]

[SetupCompileBefore ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/ReferenceImplementationLibrary.cs" }, defines: new[] { "INCLUDE_REFERENCE_IMPL" })]

// After compiling the test case we then replace the reference impl with implementation + type forwarder
[SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })]
[SetupCompileAfter ("NestedForwarderLibrary.dll", new[] { "Dependencies/NestedForwarderLibrary.il" }, references: new[] { "Implementation.dll" })]
[SetupCompileAfter ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/NestedForwarderLibrary_2.il" }, references: new[] { "NestedForwarderLibrary.dll" })]

[SetupLinkerAction ("copy", "test")]
[SetupLinkerAction ("copy", "NestedForwarderLibrary_2")]
[SetupLinkerAction ("link", "NestedForwarderLibrary")]
[SetupLinkerAction ("link", "Implementation")]

// https://github.com/dotnet/linker/issues/2359
// One of the type forwarders in NestedForwarderLibrary will not be kept.
// Which one depends on order.
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
[KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
[KeptTypeInAssembly ("Implementation.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]

[KeptMember (".ctor()")]
class MultiForwardedTypesWithLink
{
static void Main ()
{
Console.WriteLine (typeof (ImplementationLibrary.ForwardedNestedType).FullName);
Console.WriteLine (typeof (AnotherImplementationClass.ForwardedNestedType).FullName);
}
}
}
6 changes: 5 additions & 1 deletion test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@ public class ILCompiler
public NPath Compile (CompilerOptions options)
{
var capturedOutput = new List<string> ();
var capturedError = new List<string> ();
var process = new Process ();
SetupProcess (process, options);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.OutputDataReceived += (sender, args) => capturedOutput.Add (args.Data);
process.ErrorDataReceived += (sender, args) => capturedError.Add (args.Data);
process.Start ();
process.BeginOutputReadLine ();
process.BeginErrorReadLine ();
process.WaitForExit ();

if (process.ExitCode != 0) {
Assert.Fail ($"Failed to compile IL assembly : {options.OutputPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}");
Assert.Fail ($"Failed to compile IL assembly : {options.OutputPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}{capturedError.Aggregate ((buff, s) => buff + Environment.NewLine + s)}");
}

return options.OutputPath;
Expand Down

0 comments on commit 57574f1

Please sign in to comment.