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 10 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 @@ -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
where @base.IsClass && @base.Class.OriginalClass != c && (!onlyFirstBase || !@base.Class.IsInterface)
where @base.IsClass && @base.Class.OriginalClass != c && (!onlyPrimaryBase || !@base.Class.IsInterface)
let baseMethod = (
from method in @base.Class.Methods
where
@ -66,8 +66,10 @@ namespace CppSharp.AST @@ -66,8 +66,10 @@ namespace CppSharp.AST
method.Parameters.SequenceEqual(@override.Parameters, new ParameterTypeComparer())) ||
(@override.IsDestructor && method.IsDestructor && method.IsVirtual)
select method).FirstOrDefault()
let rootBaseMethod = @base.Class.GetRootBaseMethod(@override, onlyFirstBase) ?? baseMethod
where rootBaseMethod != null || onlyFirstBase
let rootBaseMethod = oneLevel
? baseMethod
: (@base.Class.GetRootBaseMethod(@override, onlyPrimaryBase) ?? baseMethod)
where rootBaseMethod != null || onlyPrimaryBase
select rootBaseMethod).FirstOrDefault();
}

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

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

28
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -89,7 +89,7 @@ namespace CppSharp.Passes @@ -89,7 +89,7 @@ namespace CppSharp.Passes
return internalImpl;
}
private static List<Method> GetRelevantAbstractMethods(Class @class)
private static IEnumerable<Method> GetRelevantAbstractMethods(Class @class)
{
var abstractMethods = GetAbstractMethods(@class);
var overriddenMethods = GetOverriddenMethods(@class);
@ -98,11 +98,29 @@ namespace CppSharp.Passes @@ -98,11 +98,29 @@ namespace CppSharp.Passes
for (var i = abstractMethods.Count - 1; i >= 0; i--)
{
var @abstract = abstractMethods[i];
if (overriddenMethods.Find(m => m.Name == @abstract.Name &&
m.ReturnType == @abstract.ReturnType &&
m.Parameters.SequenceEqual(@abstract.Parameters, paramTypeCmp)) != null)
var @override = overriddenMethods.Find(m => m.Name == @abstract.Name &&
m.ReturnType == @abstract.ReturnType &&
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 @@ @@ -1,8 +1,8 @@
using System;
using BasicTest;
using CommonTest;
using CppSharp.Utils;
using NUnit.Framework;
using Enum = BasicTest.Enum;
using Enum = CommonTest.Enum;
[TestFixture]
public class CommonTests : GeneratorTestFixture
@ -358,7 +358,7 @@ public class CommonTests : GeneratorTestFixture @@ -358,7 +358,7 @@ public class CommonTests : GeneratorTestFixture
[Test]
public void TestFunctions()
{
var ret = BasicTest.common.Function();
var ret = common.Function();
Assert.That(ret, Is.EqualTo(5));
}

9
tests/Common/Common.cpp

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

2
tests/Common/Common.cs

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

13
tests/Common/Common.h

@ -838,6 +838,19 @@ public: @@ -838,6 +838,19 @@ public:
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
{
template <class T> struct is_member_pointer_cv { static const bool value = false; };

Loading…
Cancel
Save