Skip to content

Commit

Permalink
Added tests for virtual/non-virtual override complex combinations.
Browse files Browse the repository at this point in the history
  • Loading branch information
kekyo committed Oct 28, 2018
1 parent a56f330 commit 6ca7f7b
Show file tree
Hide file tree
Showing 16 changed files with 423 additions and 12 deletions.
24 changes: 17 additions & 7 deletions IL2C.Core/AssemblyWriter.cs
Expand Up @@ -105,8 +105,13 @@ public static class AssemblyWriter
Select(entry => entry.method).
Where(method => method.DeclaringType.IsAssignableFrom(declaredType) && method.IsNewSlot).
ToArray();
var overrideBaseMethods = virtualMethods.
Select(entry => entry.method).
var overrideBaseMethods = declaredType.
Traverse(type => type.BaseType).
Reverse().
SelectMany(type => type.DeclaredMethods.
Where(method => method.IsVirtual).
CalculateOverloadMethods().
SelectMany(entry => entry.Value)).
Where(method =>
!method.DeclaringType.Equals(declaredType) &&
method.DeclaringType.IsAssignableFrom(declaredType)).
Expand All @@ -119,7 +124,7 @@ public static class AssemblyWriter
if (!declaredType.IsEnum)
{
// If virtual method collection doesn't contain newslot method at this declared type:
if (!newSlotMethods.Any())
if (!newSlotMethods.Any(method => method.DeclaringType.Equals(declaredType)))
{
tw.WriteLine();
tw.WriteLine(
Expand Down Expand Up @@ -220,7 +225,7 @@ public static class AssemblyWriter
tw.WriteLine("};");
}

// If virtual method collection doesn't contain reuseslot and newslot method at this declared type:
// If virtual method collection doesn't contain reuseslot and newslot method at declared types:
if (!overrideMethods.Any() && !newSlotMethods.Any())
{
tw.WriteLine();
Expand Down Expand Up @@ -778,14 +783,19 @@ private struct VirtualFunctionInformation
Select(entry => entry.method).
Where(method => method.DeclaringType.IsAssignableFrom(declaredType) && method.IsNewSlot).
ToArray();
var overrideBaseMethods = virtualMethods.
Select(entry => entry.method).
var overrideBaseMethods = declaredType.
Traverse(type => type.BaseType).
Reverse().
SelectMany(type => type.DeclaredMethods.
Where(method => method.IsVirtual).
CalculateOverloadMethods().
SelectMany(entry => entry.Value)).
Where(method =>
!method.DeclaringType.Equals(declaredType) &&
method.DeclaringType.IsAssignableFrom(declaredType)).
ToArray();

// If virtual method collection doesn't contain reuseslot and newslot method at this declared type:
// If virtual method collection doesn't contain reuseslot and newslot method at declared types:
if (!overrideMethods.Any() && !newSlotMethods.Any())
{
tw.WriteLine();
Expand Down
4 changes: 2 additions & 2 deletions supported-opcodes.md
Expand Up @@ -35,9 +35,9 @@ OpCode | Binary | Implement | Test | ILConverter
| [brfalse.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.brfalse_s) | 0x2c | Implemented | [Test [10]](tests/IL2C.Core.Test.Target/ILConverters/Brfalse_S) | IL2C.ILConverters.Brfalse_sConverter |
| [brtrue](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.brtrue) | 0x3a | Implemented | [Test [10]](tests/IL2C.Core.Test.Target/ILConverters/Brtrue) | IL2C.ILConverters.BrtrueConverter |
| [brtrue.s](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.brtrue_s) | 0x2d | Implemented | [Test [10]](tests/IL2C.Core.Test.Target/ILConverters/Brtrue_S) | IL2C.ILConverters.Brtrue_sConverter |
| [call](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.call) | 0x28 | Implemented | [Test [11]](tests/IL2C.Core.Test.Target/ILConverters/Call) | IL2C.ILConverters.CallConverter |
| [call](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.call) | 0x28 | Implemented | [Test [17]](tests/IL2C.Core.Test.Target/ILConverters/Call) | IL2C.ILConverters.CallConverter |
| [calli](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.calli) | 0x29 | | | |
| [callvirt](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.callvirt) | 0x6f | Implemented | [Test [12]](tests/IL2C.Core.Test.Target/ILConverters/Callvirt) | IL2C.ILConverters.CallvirtConverter |
| [callvirt](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.callvirt) | 0x6f | Implemented | [Test [23]](tests/IL2C.Core.Test.Target/ILConverters/Callvirt) | IL2C.ILConverters.CallvirtConverter |
| [castclass](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.castclass) | 0x74 | Implemented | | IL2C.ILConverters.CastclassConverter |
| [ceq](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ceq) | 0xfe01 | Implemented | | IL2C.ILConverters.CeqConverter |
| [cgt](https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.cgt) | 0xfe02 | Implemented | | IL2C.ILConverters.CgtConverter |
Expand Down
6 changes: 6 additions & 0 deletions tests/IL2C.Core.Test.Fixture/ILConvertersTest.cs
Expand Up @@ -76,6 +76,9 @@ public sealed class ILConvertersTest
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Call_Newslot>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Call_Virtual>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Call_Newslot_Virtual>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Call_Overload>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Call_Overload_Virtual>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Call_Overload_Newslot_Virtual>()).
ToArray();
[Test]
public static Task Call([ValueSource(nameof(_Call))] TestCaseInformation caseInfo) =>
Expand All @@ -88,6 +91,9 @@ public sealed class ILConvertersTest
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Callvirt_Derived1_Newslot>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Callvirt_Derived1_Newslot_Virtual>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Callvirt_Derived2_Newslot>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Callvirt_Derived3_Newslot>()).
Concat(TestUtilities.GetTestCaseInformations<IL2C.ILConverters.Callvirt_Derived3_Newslot_Virtual>()).
ToArray();
[Test]
public static Task Callvirt([ValueSource(nameof(_Callvirt))] TestCaseInformation caseInfo) =>
Expand Down
22 changes: 22 additions & 0 deletions tests/IL2C.Core.Test.Target/ILConverters/Call/Call_Overload.cs
@@ -0,0 +1,22 @@
using System;
using System.Runtime.CompilerServices;

namespace IL2C.ILConverters
{
[TestId("Call")]
[TestCase("IL2C.ILConverters.Call_Overload", new[] { "Instance_Overload_ToString_System_Object", "ToString" })]
[TestCase("CallTestABC", new[] { "Instance_Overload_ToString_IL2C_ILConverters_Call", "ToString" }, "ABC")]
public class Call_Overload
{
public string ToString(string value)
{
return "CallTest" + value;
}

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_ToString_System_Object();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_ToString_IL2C_ILConverters_Call(string value);
}
}
19 changes: 19 additions & 0 deletions tests/IL2C.Core.Test.Target/ILConverters/Call/Call_Overload.il
@@ -0,0 +1,19 @@
.class public IL2C.ILConverters.Call_Overload
{
.method public static string Instance_Overload_ToString_System_Object() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Call_Overload::.ctor()
call instance string [mscorlib]System.Object::ToString()
ret
}

.method public static string Instance_Overload_ToString_IL2C_ILConverters_Call(string v) cil managed
{
.maxstack 2
newobj instance void class IL2C.ILConverters.Call_Overload::.ctor()
ldarg.0
call instance string IL2C.ILConverters.Call_Overload::ToString(string v)
ret
}
}
@@ -0,0 +1,30 @@
using System;
using System.Runtime.CompilerServices;

namespace IL2C.ILConverters
{
[TestId("Call")]
[TestCase("IL2C.ILConverters.Call_Overload_Newslot_Virtual", new[] { "Instance_Overload_Newslot_Virtual_ToString_System_Object", "ToString" })]
[TestCase("CallTestABC", new[] { "Instance_Overload_Newslot_Virtual_ToString_IL2C_ILConverters_Call", "ToString" }, "ABC")]
public class Call_Overload_Newslot_Virtual
{
public new virtual string ToString()
{
return "CallTest";
}

public string ToString(string value)
{
return "CallTest" + value;
}

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_Newslot_Virtual_ToString_System_Object();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_Newslot_Virtual_ToString_NoArgument_IL2C_ILConverters_Call();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_Newslot_Virtual_ToString_IL2C_ILConverters_Call(string value);
}
}
@@ -0,0 +1,27 @@
.class public IL2C.ILConverters.Call_Overload_Newslot_Virtual
{
.method public static string Instance_Overload_Newslot_Virtual_ToString_System_Object() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Call_Overload_Newslot_Virtual::.ctor()
call instance string [mscorlib]System.Object::ToString()
ret
}

.method public static string Instance_Overload_Newslot_Virtual_ToString_NoArgument_IL2C_ILConverters_Call() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Call_Overload_Newslot_Virtual::.ctor()
call instance string IL2C.ILConverters.Call_Overload_Newslot_Virtual::ToString()
ret
}

.method public static string Instance_Overload_Newslot_Virtual_ToString_IL2C_ILConverters_Call(string v) cil managed
{
.maxstack 2
newobj instance void class IL2C.ILConverters.Call_Overload_Newslot_Virtual::.ctor()
ldarg.0
call instance string IL2C.ILConverters.Call_Overload_Newslot_Virtual::ToString(string v)
ret
}
}
@@ -0,0 +1,30 @@
using System;
using System.Runtime.CompilerServices;

namespace IL2C.ILConverters
{
[TestId("Call")]
[TestCase("IL2C.ILConverters.Call_Overload_Virtual", new[] { "Instance_Overload_Virtual_ToString_System_Object", "ToString" })]
[TestCase("CallTestABC", new[] { "Instance_Overload_Virtual_ToString_IL2C_ILConverters_Call", "ToString" }, "ABC")]
public class Call_Overload_Virtual
{
public override string ToString()
{
return "CallTest";
}

public string ToString(string value)
{
return "CallTest" + value;
}

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_Virtual_ToString_System_Object();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_Virtual_ToString_NoArgument_IL2C_ILConverters_Call();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Instance_Overload_Virtual_ToString_IL2C_ILConverters_Call(string value);
}
}
@@ -0,0 +1,27 @@
.class public IL2C.ILConverters.Call_Overload_Virtual
{
.method public static string Instance_Overload_Virtual_ToString_System_Object() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Call_Overload_Virtual::.ctor()
call instance string [mscorlib]System.Object::ToString()
ret
}

.method public static string Instance_Overload_Virtual_ToString_NoArgument_IL2C_ILConverters_Call() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Call_Overload_Virtual::.ctor()
call instance string IL2C.ILConverters.Call_Overload_Virtual::ToString()
ret
}

.method public static string Instance_Overload_Virtual_ToString_IL2C_ILConverters_Call(string v) cil managed
{
.maxstack 2
newobj instance void class IL2C.ILConverters.Call_Overload_Virtual::.ctor()
ldarg.0
call instance string IL2C.ILConverters.Call_Overload_Virtual::ToString(string v)
ret
}
}
Expand Up @@ -9,19 +9,19 @@ protected Callvirt_Derived2_Newslot_Base()
{
}

public new virtual string ToString()
public new string ToString()
{
return "Callvirt_Derived_Base";
}
}

[TestId("Callvirt")]
[TestCase("IL2C.ILConverters.Callvirt_Derived2_Newslot", new[] { "Derived2_Newslot_ToString_System_Object", "ToString" }, IncludeBaseTypes = true)]
[TestCase("CallvirtTest", new[] { "Derived2_Newslot_ToString_IL2C_ILConverters_Callvirt_Base", "ToString" }, IncludeBaseTypes = true)]
[TestCase("Callvirt_Derived_Base", new[] { "Derived2_Newslot_ToString_IL2C_ILConverters_Callvirt_Base", "ToString" }, IncludeBaseTypes = true)]
[TestCase("CallvirtTest", new[] { "Derived2_Newslot_ToString_IL2C_ILConverters_Callvirt", "ToString" }, IncludeBaseTypes = true)]
public sealed class Callvirt_Derived2_Newslot : Callvirt_Derived2_Newslot_Base
{
public override string ToString()
public new string ToString()
{
return "CallvirtTest";
}
Expand Down
@@ -0,0 +1,38 @@
using System;
using System.Runtime.CompilerServices;

namespace IL2C.ILConverters
{
public abstract class Callvirt_Derived2_Newslot_Virtual_Base
{
protected Callvirt_Derived2_Newslot_Virtual_Base()
{
}

public new virtual string ToString()
{
return "Callvirt_Derived_Base";
}
}

[TestId("Callvirt")]
[TestCase("IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual", new[] { "Derived2_Newslot_Virtual_ToString_System_Object", "ToString" }, IncludeBaseTypes = true)]
[TestCase("CallvirtTest", new[] { "Derived2_Newslot_Virtual_ToString_IL2C_ILConverters_Callvirt_Base", "ToString" }, IncludeBaseTypes = true)]
[TestCase("CallvirtTest", new[] { "Derived2_Newslot_Virtual_ToString_IL2C_ILConverters_Callvirt", "ToString" }, IncludeBaseTypes = true)]
public class Callvirt_Derived2_Newslot_Virtual : Callvirt_Derived2_Newslot_Virtual_Base
{
public override string ToString()
{
return "CallvirtTest";
}

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Derived2_Newslot_Virtual_ToString_System_Object();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Derived2_Newslot_Virtual_ToString_IL2C_ILConverters_Callvirt_Base();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Derived2_Newslot_Virtual_ToString_IL2C_ILConverters_Callvirt();
}
}
@@ -0,0 +1,26 @@
.class public IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual
{
.method public static string Derived2_Newslot_Virtual_ToString_System_Object() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual::.ctor()
callvirt instance string [mscorlib]System.Object::ToString()
ret
}

.method public static string Derived2_Newslot_Virtual_ToString_IL2C_ILConverters_Callvirt_Base() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual::.ctor()
callvirt instance string IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual_Base::ToString()
ret
}

.method public static string Derived2_Newslot_Virtual_ToString_IL2C_ILConverters_Callvirt() cil managed
{
.maxstack 1
newobj instance void class IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual::.ctor()
callvirt instance string IL2C.ILConverters.Callvirt_Derived2_Newslot_Virtual::ToString()
ret
}
}
@@ -0,0 +1,54 @@
using System;
using System.Runtime.CompilerServices;

namespace IL2C.ILConverters
{
public abstract class Callvirt_Derived3_Newslot_Base1
{
protected Callvirt_Derived3_Newslot_Base1()
{
}

public override string ToString()
{
return "Callvirt_Derived_Base1";
}
}

public abstract class Callvirt_Derived3_Newslot_Base2 : Callvirt_Derived3_Newslot_Base1
{
protected Callvirt_Derived3_Newslot_Base2()
{
}

public new string ToString()
{
return "Callvirt_Derived_Base2";
}
}

[TestId("Callvirt")]
[TestCase("Callvirt_Derived_Base1", new[] { "Derived3_Newslot_ToString_System_Object", "ToString" }, IncludeBaseTypes = true)]
[TestCase("Callvirt_Derived_Base1", new[] { "Derived3_Newslot_ToString_IL2C_ILConverters_Callvirt_Base1", "ToString" }, IncludeBaseTypes = true)]
[TestCase("Callvirt_Derived_Base2", new[] { "Derived3_Newslot_ToString_IL2C_ILConverters_Callvirt_Base2", "ToString" }, IncludeBaseTypes = true)]
[TestCase("CallvirtTest", new[] { "Derived3_Newslot_ToString_IL2C_ILConverters_Callvirt", "ToString" }, IncludeBaseTypes = true)]
public sealed class Callvirt_Derived3_Newslot : Callvirt_Derived3_Newslot_Base2
{
public new string ToString()
{
return "CallvirtTest";
}

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Derived3_Newslot_ToString_System_Object();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Derived3_Newslot_ToString_IL2C_ILConverters_Callvirt_Base1();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Derived3_Newslot_ToString_IL2C_ILConverters_Callvirt_Base2();

[MethodImpl(MethodImplOptions.ForwardRef)]
public static extern string Derived3_Newslot_ToString_IL2C_ILConverters_Callvirt();
}
}

0 comments on commit 6ca7f7b

Please sign in to comment.