fix: calling base method when the first base class did not have the virtual method (#2014)

* adding test for error

* adding test with multiple overrides

* calling methods in base type

* adding test for more than 1 override
This commit is contained in:
James Frowen 2020-06-18 23:23:46 +01:00 committed by GitHub
parent 5032ceb000
commit 4af72c3a63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 163 additions and 3 deletions

View File

@ -218,6 +218,32 @@ public static List<MethodDefinition> GetMethods(this TypeDefinition td, string m
return methods;
}
public static MethodDefinition GetMethodInBaseType(this TypeDefinition td, string methodName)
{
TypeDefinition typedef = td;
while (typedef != null)
{
foreach (MethodDefinition md in typedef.Methods)
{
if (md.Name == methodName)
return md;
}
try
{
TypeReference parent = typedef.BaseType;
typedef = parent?.Resolve();
}
catch (AssemblyResolutionException)
{
// this can happen for pluins.
break;
}
}
return null;
}
/// <summary>
///
/// </summary>

View File

@ -84,7 +84,19 @@ public static void FixRemoteCallToBaseMethod(TypeDefinition type, MethodDefiniti
calledMethod.Name == baseRemoteCallName)
{
TypeDefinition baseType = type.BaseType.Resolve();
MethodDefinition baseMethod = baseType.GetMethod(callName);
MethodDefinition baseMethod = baseType.GetMethodInBaseType(callName);
if (baseMethod == null)
{
Weaver.Error($"Could not find base method for {callName}", method);
return;
}
if (!baseMethod.IsVirtual)
{
Weaver.Error($"Could not find base method that was virutal {callName}", method);
return;
}
instruction.Operand = baseMethod;

View File

@ -42,6 +42,21 @@ public override void CmdSendInt(int someInt)
}
}
/// <summary>
/// test for 2 overrides
/// </summary>
class VirtualOverrideCommandWithBase2 : VirtualOverrideCommandWithBase
{
public event Action<int> onOverrideSendInt2;
[Command]
public override void CmdSendInt(int someInt)
{
base.CmdSendInt(someInt);
onOverrideSendInt2?.Invoke(someInt);
}
}
public class CommandOverrideTest : RemoteTestBase
{
[Test]
@ -132,5 +147,39 @@ public void OverrideVirtualWithBaseCallsBothVirtualAndBase()
Assert.That(virtualCallCount, Is.EqualTo(1));
Assert.That(overrideCallCount, Is.EqualTo(1));
}
[Test]
public void OverrideVirtualWithBaseCallsAllMethodsThatCallBase()
{
VirtualOverrideCommandWithBase2 hostBehaviour = CreateHostObject<VirtualOverrideCommandWithBase2>(true);
const int someInt = 20;
int virtualCallCount = 0;
int overrideCallCount = 0;
int override2CallCount = 0;
hostBehaviour.onVirtualSendInt += incomingInt =>
{
virtualCallCount++;
Assert.That(incomingInt, Is.EqualTo(someInt));
};
hostBehaviour.onOverrideSendInt += incomingInt =>
{
overrideCallCount++;
Assert.That(incomingInt, Is.EqualTo(someInt));
};
hostBehaviour.onOverrideSendInt2 += incomingInt =>
{
override2CallCount++;
Assert.That(incomingInt, Is.EqualTo(someInt));
};
hostBehaviour.CmdSendInt(someInt);
ProcessMessages();
Assert.That(virtualCallCount, Is.EqualTo(1));
Assert.That(overrideCallCount, Is.EqualTo(1));
Assert.That(override2CallCount, Is.EqualTo(1));
}
}
}

View File

@ -100,6 +100,8 @@
<Compile Include="WeaverCommandTests~\CommandWithArguments.cs" />
<Compile Include="WeaverCommandTests~\OverrideAbstractCommand.cs" />
<Compile Include="WeaverCommandTests~\OverrideVirtualCallBaseCommand.cs" />
<Compile Include="WeaverCommandTests~\OverrideVirtualCallsBaseCommandWithMultipleBaseClasses.cs" />
<Compile Include="WeaverCommandTests~\OverrideVirtualCallsBaseCommandWithOverride.cs" />
<Compile Include="WeaverCommandTests~\OverrideVirtualCommand.cs" />
<Compile Include="WeaverCommandTests~\VirtualCommand.cs" />
<Compile Include="WeaverCommandTests~\CommandWithSenderConnectionAndOtherArgs.cs" />

View File

@ -76,6 +76,18 @@ public void OverrideVirtualCallBaseCommand()
Assert.That(weaverErrors, Is.Empty);
}
[Test]
public void OverrideVirtualCallsBaseCommandWithMultipleBaseClasses()
{
Assert.That(weaverErrors, Is.Empty);
}
[Test]
public void OverrideVirtualCallsBaseCommandWithOverride()
{
Assert.That(weaverErrors, Is.Empty);
}
[Test]
public void AbstractCommand()
{

View File

@ -1,6 +1,5 @@
using Mirror;
namespace WeaverCommandTests.OverrideVirtualCallBaseCommand
{
class OverrideVirtualCallBaseCommand : baseBehaviour

View File

@ -0,0 +1,27 @@
using Mirror;
namespace WeaverCommandTests.OverrideVirtualCallsBaseCommandWithMultipleBaseClasses
{
class OverrideVirtualCallsBaseCommandWithMultipleBaseClasses : middleBehaviour
{
[Command]
protected override void CmdDoSomething()
{
// do somethin
base.CmdDoSomething();
}
}
class middleBehaviour : baseBehaviour
{
}
class baseBehaviour : NetworkBehaviour
{
[Command]
protected virtual void CmdDoSomething()
{
// do more stuff
}
}
}

View File

@ -0,0 +1,34 @@
using Mirror;
namespace WeaverCommandTests.OverrideVirtualCallsBaseCommandWithOverride
{
class OverrideVirtualCallsBaseCommandWithOverride : middleBehaviour
{
[Command]
protected override void CmdDoSomething()
{
// do something
base.CmdDoSomething();
}
}
class middleBehaviour : baseBehaviour
{
[Command]
protected override void CmdDoSomething()
{
// do something else
base.CmdDoSomething();
}
}
class baseBehaviour : NetworkBehaviour
{
[Command]
protected virtual void CmdDoSomething()
{
// do more stuff
}
}
}

View File

@ -1,6 +1,5 @@
using Mirror;
namespace WeaverCommandTests.OverrideVirtualCommand
{
class OverrideVirtualCommand : baseBehaviour