Browse Source

Fixed abstract implementations and bodies of overrides to properly handle abstract overrides.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/560/head
Dimitar Dobrev 11 years ago
parent
commit
fa0e66687d
  1. 10
      src/AST/ClassExtensions.cs
  2. 4
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 28
      src/Generator/Passes/GenerateAbstractImplementationsPass.cs
  4. 6
      tests/Common/Common.Tests.cs
  5. 9
      tests/Common/Common.cpp
  6. 2
      tests/Common/Common.cs
  7. 13
      tests/Common/Common.h

10
src/AST/ClassExtensions.cs

@ -54,10 +54,10 @@ namespace CppSharp.AST
} }
} }
public static Method GetRootBaseMethod(this Class c, Method @override, bool onlyFirstBase = false) public static Method GetRootBaseMethod(this Class c, Method @override, bool onlyPrimaryBase = false, bool oneLevel = false)
{ {
return (from @base in c.Bases return (from @base in c.Bases
where @base.IsClass && @base.Class.OriginalClass != c && (!onlyFirstBase || !@base.Class.IsInterface) where @base.IsClass && @base.Class.OriginalClass != c && (!onlyPrimaryBase || !@base.Class.IsInterface)
let baseMethod = ( let baseMethod = (
from method in @base.Class.Methods from method in @base.Class.Methods
where where
@ -66,8 +66,10 @@ namespace CppSharp.AST
method.Parameters.SequenceEqual(@override.Parameters, new ParameterTypeComparer())) || method.Parameters.SequenceEqual(@override.Parameters, new ParameterTypeComparer())) ||
(@override.IsDestructor && method.IsDestructor && method.IsVirtual) (@override.IsDestructor && method.IsDestructor && method.IsVirtual)
select method).FirstOrDefault() select method).FirstOrDefault()
let rootBaseMethod = @base.Class.GetRootBaseMethod(@override, onlyFirstBase) ?? baseMethod let rootBaseMethod = oneLevel
where rootBaseMethod != null || onlyFirstBase ? baseMethod
: (@base.Class.GetRootBaseMethod(@override, onlyPrimaryBase) ?? baseMethod)
where rootBaseMethod != null || onlyPrimaryBase
select rootBaseMethod).FirstOrDefault(); select rootBaseMethod).FirstOrDefault();
} }

4
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -2310,8 +2310,8 @@ namespace CppSharp.Generators.CSharp
private void GenerateVirtualFunctionCall(Method method, Class @class) private void GenerateVirtualFunctionCall(Method method, Class @class)
{ {
Method rootBaseMethod; Method rootBaseMethod;
if (method.IsOverride && method.SynthKind != FunctionSynthKind.AbstractImplCall && if (method.IsOverride && !method.IsPure && method.SynthKind != FunctionSynthKind.AbstractImplCall &&
(rootBaseMethod = ((Class) method.Namespace).GetRootBaseMethod(method, true)) != null && (rootBaseMethod = ((Class) method.Namespace).GetRootBaseMethod(method, true, true)) != null &&
!rootBaseMethod.IsPure) !rootBaseMethod.IsPure)
{ {
GenerateManagedCall(method, true); GenerateManagedCall(method, true);

28
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -89,7 +89,7 @@ namespace CppSharp.Passes
return internalImpl; return internalImpl;
} }
private static List<Method> GetRelevantAbstractMethods(Class @class) private static IEnumerable<Method> GetRelevantAbstractMethods(Class @class)
{ {
var abstractMethods = GetAbstractMethods(@class); var abstractMethods = GetAbstractMethods(@class);
var overriddenMethods = GetOverriddenMethods(@class); var overriddenMethods = GetOverriddenMethods(@class);
@ -98,11 +98,29 @@ namespace CppSharp.Passes
for (var i = abstractMethods.Count - 1; i >= 0; i--) for (var i = abstractMethods.Count - 1; i >= 0; i--)
{ {
var @abstract = abstractMethods[i]; var @abstract = abstractMethods[i];
if (overriddenMethods.Find(m => m.Name == @abstract.Name && var @override = overriddenMethods.Find(m => m.Name == @abstract.Name &&
m.ReturnType == @abstract.ReturnType && m.ReturnType == @abstract.ReturnType &&
m.Parameters.SequenceEqual(@abstract.Parameters, paramTypeCmp)) != null) m.Parameters.SequenceEqual(@abstract.Parameters, paramTypeCmp));
if (@override != null)
{ {
abstractMethods.RemoveAt(i); if (@abstract.IsOverride)
{
var abstractMethod = abstractMethods[i];
bool found;
var rootBaseMethod = abstractMethod;
do
{
rootBaseMethod = @class.GetRootBaseMethod(rootBaseMethod, false, true);
if (found = (rootBaseMethod == @override))
break;
} while (rootBaseMethod != null);
if (!found)
abstractMethods.RemoveAt(i);
}
else
{
abstractMethods.RemoveAt(i);
}
} }
} }

6
tests/Common/Common.Tests.cs

@ -1,8 +1,8 @@
using System; using System;
using BasicTest; using CommonTest;
using CppSharp.Utils; using CppSharp.Utils;
using NUnit.Framework; using NUnit.Framework;
using Enum = BasicTest.Enum; using Enum = CommonTest.Enum;
[TestFixture] [TestFixture]
public class CommonTests : GeneratorTestFixture public class CommonTests : GeneratorTestFixture
@ -358,7 +358,7 @@ public class CommonTests : GeneratorTestFixture
[Test] [Test]
public void TestFunctions() public void TestFunctions()
{ {
var ret = BasicTest.common.Function(); var ret = common.Function();
Assert.That(ret, Is.EqualTo(5)); Assert.That(ret, Is.EqualTo(5));
} }

9
tests/Common/Common.cpp

@ -528,3 +528,12 @@ int DerivedClassVirtual::retInt()
{ {
return 2; return 2;
} }
DerivedClassOverrideAbstractVirtual::DerivedClassOverrideAbstractVirtual()
{
}
int DerivedClassOverrideAbstractVirtual::retInt()
{
return 1;
}

2
tests/Common/Common.cs

@ -18,7 +18,7 @@ namespace CppSharp.Tests
{ {
base.Setup(driver); base.Setup(driver);
driver.Options.OutputNamespace = "BasicTest"; driver.Options.OutputNamespace = "CommonTest";
} }
public override void SetupPasses(Driver driver) public override void SetupPasses(Driver driver)

13
tests/Common/Common.h

@ -838,6 +838,19 @@ public:
virtual int retInt(); virtual int retInt();
}; };
class DLL_API DerivedClassAbstractVirtual : public DerivedClassVirtual
{
public:
virtual int retInt() = 0;
};
class DLL_API DerivedClassOverrideAbstractVirtual : public DerivedClassAbstractVirtual
{
public:
DerivedClassOverrideAbstractVirtual();
virtual int retInt();
};
namespace boost namespace boost
{ {
template <class T> struct is_member_pointer_cv { static const bool value = false; }; template <class T> struct is_member_pointer_cv { static const bool value = false; };

Loading…
Cancel
Save