Skip to content

Commit f2282bd

Browse files
authored
Adds a test for multiple nested forwarders in a row with copy/link (dotnet/linker#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/linker#2359. Also improved the test infra to print out errors from ilasm if they happen. Commit migrated from dotnet/linker@57574f1
1 parent 2bc068d commit f2282bd

File tree

7 files changed

+177
-1
lines changed

7 files changed

+177
-1
lines changed

src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ImplementationLibrary.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ public class ImplementationLibraryNestedType
2525
public static int PropertyOnNestedType { get; set; }
2626
}
2727

28+
public class ForwardedNestedType
29+
{
30+
}
31+
2832
public static int someField = 42;
2933

3034
public string GetSomeValue ()
@@ -33,6 +37,13 @@ public string GetSomeValue ()
3337
}
3438
}
3539

40+
public class AnotherImplementationClass
41+
{
42+
public class ForwardedNestedType
43+
{
44+
}
45+
}
46+
3647
[AttributeUsage (AttributeTargets.All)]
3748
public class ImplementationLibraryAttribute : Attribute
3849
{
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
.assembly extern mscorlib
2+
{
3+
}
4+
5+
.assembly extern Implementation
6+
{
7+
}
8+
9+
.assembly NestedForwarderLibrary
10+
{
11+
}
12+
13+
.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary
14+
{
15+
.assembly extern 'Implementation'
16+
}
17+
.class extern ForwardedNestedType
18+
{
19+
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
20+
}
21+
22+
.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherImplementationClass
23+
{
24+
.assembly extern 'Implementation'
25+
}
26+
.class extern ForwardedNestedType
27+
{
28+
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
29+
}
30+
31+
.module 'NestedForwarderLibrary.dll'
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
.assembly extern mscorlib
2+
{
3+
}
4+
5+
.assembly extern NestedForwarderLibrary
6+
{
7+
}
8+
9+
.assembly NestedForwarderLibrary_2
10+
{
11+
}
12+
13+
.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary
14+
{
15+
.assembly extern 'NestedForwarderLibrary'
16+
}
17+
.class extern ForwardedNestedType
18+
{
19+
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
20+
}
21+
22+
.class extern forwarder Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.AnotherImplementationClass
23+
{
24+
.assembly extern 'NestedForwarderLibrary'
25+
}
26+
.class extern ForwardedNestedType
27+
{
28+
.class extern 'Mono.Linker.Tests.Cases.TypeForwarding.Dependencies.ImplementationLibrary'
29+
}
30+
31+
.module 'NestedForwarderLibrary_2.dll'

src/tools/illink/test/Mono.Linker.Tests.Cases/TypeForwarding/Dependencies/ReferenceImplementationLibrary.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public class ImplementationLibraryNestedType
2727
public static int PropertyOnNestedType { get; set; }
2828
}
2929

30+
public class ForwardedNestedType
31+
{
32+
}
33+
3034
public static int someField = 0;
3135

3236
public string GetSomeValue ()
@@ -35,6 +39,13 @@ public string GetSomeValue ()
3539
}
3640
}
3741

42+
public class AnotherImplementationClass
43+
{
44+
public class ForwardedNestedType
45+
{
46+
}
47+
}
48+
3849
[AttributeUsage (AttributeTargets.All)]
3950
public class ImplementationLibraryAttribute : Attribute
4051
{
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using Mono.Linker.Tests.Cases.Expectations.Assertions;
6+
using Mono.Linker.Tests.Cases.Expectations.Metadata;
7+
using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies;
8+
9+
namespace Mono.Linker.Tests.Cases.TypeForwarding
10+
{
11+
[SkipUnresolved (true)]
12+
13+
[SetupCompileBefore ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/ReferenceImplementationLibrary.cs" }, defines: new[] { "INCLUDE_REFERENCE_IMPL" })]
14+
15+
// After compiling the test case we then replace the reference impl with implementation + type forwarder
16+
[SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })]
17+
[SetupCompileAfter ("NestedForwarderLibrary.dll", new[] { "Dependencies/NestedForwarderLibrary.il" }, references: new[] { "Implementation.dll" })]
18+
[SetupCompileAfter ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/NestedForwarderLibrary_2.il" }, references: new[] { "NestedForwarderLibrary.dll" })]
19+
20+
[SetupLinkerAction ("copy", "test")]
21+
[SetupLinkerAction ("copy", "NestedForwarderLibrary_2")]
22+
[SetupLinkerAction ("copyused", "NestedForwarderLibrary")]
23+
[SetupLinkerAction ("copyused", "Implementation")]
24+
25+
// https://github.com/dotnet/linker/issues/2359
26+
// One of the type forwarders in NestedForwarderLibrary will not be kept.
27+
// Which one depends on order.
28+
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
29+
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
30+
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
31+
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
32+
[KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
33+
[KeptTypeInAssembly ("Implementation.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
34+
35+
[KeptMember (".ctor()")]
36+
class MultiForwardedTypesWithCopyUsed
37+
{
38+
static void Main ()
39+
{
40+
Console.WriteLine (typeof (ImplementationLibrary.ForwardedNestedType).FullName);
41+
Console.WriteLine (typeof (AnotherImplementationClass.ForwardedNestedType).FullName);
42+
}
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using Mono.Linker.Tests.Cases.Expectations.Assertions;
6+
using Mono.Linker.Tests.Cases.Expectations.Metadata;
7+
using Mono.Linker.Tests.Cases.TypeForwarding.Dependencies;
8+
9+
namespace Mono.Linker.Tests.Cases.TypeForwarding
10+
{
11+
[SkipUnresolved (true)]
12+
13+
[SetupCompileBefore ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/ReferenceImplementationLibrary.cs" }, defines: new[] { "INCLUDE_REFERENCE_IMPL" })]
14+
15+
// After compiling the test case we then replace the reference impl with implementation + type forwarder
16+
[SetupCompileAfter ("Implementation.dll", new[] { "Dependencies/ImplementationLibrary.cs" })]
17+
[SetupCompileAfter ("NestedForwarderLibrary.dll", new[] { "Dependencies/NestedForwarderLibrary.il" }, references: new[] { "Implementation.dll" })]
18+
[SetupCompileAfter ("NestedForwarderLibrary_2.dll", new[] { "Dependencies/NestedForwarderLibrary_2.il" }, references: new[] { "NestedForwarderLibrary.dll" })]
19+
20+
[SetupLinkerAction ("copy", "test")]
21+
[SetupLinkerAction ("copy", "NestedForwarderLibrary_2")]
22+
[SetupLinkerAction ("link", "NestedForwarderLibrary")]
23+
[SetupLinkerAction ("link", "Implementation")]
24+
25+
// https://github.com/dotnet/linker/issues/2359
26+
// One of the type forwarders in NestedForwarderLibrary will not be kept.
27+
// Which one depends on order.
28+
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
29+
//[KeptTypeInAssembly ("NestedForwarderLibrary.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
30+
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
31+
//[KeptTypeInAssembly ("NestedForwarderLibrary_2.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
32+
[KeptTypeInAssembly ("Implementation.dll", typeof (ImplementationLibrary.ForwardedNestedType))]
33+
[KeptTypeInAssembly ("Implementation.dll", typeof (AnotherImplementationClass.ForwardedNestedType))]
34+
35+
[KeptMember (".ctor()")]
36+
class MultiForwardedTypesWithLink
37+
{
38+
static void Main ()
39+
{
40+
Console.WriteLine (typeof (ImplementationLibrary.ForwardedNestedType).FullName);
41+
Console.WriteLine (typeof (AnotherImplementationClass.ForwardedNestedType).FullName);
42+
}
43+
}
44+
}

src/tools/illink/test/Mono.Linker.Tests/TestCasesRunner/ILCompiler.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,20 @@ public class ILCompiler
1515
public NPath Compile (CompilerOptions options)
1616
{
1717
var capturedOutput = new List<string> ();
18+
var capturedError = new List<string> ();
1819
var process = new Process ();
1920
SetupProcess (process, options);
2021
process.StartInfo.RedirectStandardOutput = true;
22+
process.StartInfo.RedirectStandardError = true;
2123
process.OutputDataReceived += (sender, args) => capturedOutput.Add (args.Data);
24+
process.ErrorDataReceived += (sender, args) => capturedError.Add (args.Data);
2225
process.Start ();
2326
process.BeginOutputReadLine ();
27+
process.BeginErrorReadLine ();
2428
process.WaitForExit ();
2529

2630
if (process.ExitCode != 0) {
27-
Assert.Fail ($"Failed to compile IL assembly : {options.OutputPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}");
31+
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)}");
2832
}
2933

3034
return options.OutputPath;

0 commit comments

Comments
 (0)