Browse Source

Fixed a bug when wrapping virtual properties overridden in indirect derived types.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/563/head
Dimitar Dobrev 10 years ago
parent
commit
4e981a80e6
  1. 41
      src/AST/ClassExtensions.cs
  2. 4
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 6
      src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs
  4. 2
      src/Generator/Passes/MultipleInheritancePass.cs
  5. 2
      src/Generator/Passes/RenamePass.cs
  6. 9
      tests/CSharp/CSharp.Tests.cs
  7. 21
      tests/CSharp/CSharp.cpp
  8. 24
      tests/CSharp/CSharp.h

41
src/AST/ClassExtensions.cs

@ -80,7 +80,7 @@ namespace CppSharp.AST @@ -80,7 +80,7 @@ namespace CppSharp.AST
if (getTopmost)
{
baseMethod = (@base.Class.GetBaseMethod(@override, onlyPrimaryBase));
baseMethod = (@base.Class.GetBaseMethod(@override, onlyPrimaryBase, true));
if (baseMethod != null)
return baseMethod;
}
@ -88,20 +88,37 @@ namespace CppSharp.AST @@ -88,20 +88,37 @@ namespace CppSharp.AST
return null;
}
public static Property GetRootBaseProperty(this Class c, Property @override, bool onlyFirstBase = false)
public static Property GetBaseProperty(this Class c, Property @override, bool onlyFirstBase = false, bool getTopmost = false)
{
foreach (var @base in c.Bases)
{
if (!@base.IsClass || @base.Class.OriginalClass == c || (onlyFirstBase && @base.Class.IsInterface))
continue;
Property baseProperty;
if (!getTopmost)
{
return (from @base in c.Bases
where @base.IsClass && @base.Class.OriginalClass != c && (!onlyFirstBase || !@base.Class.IsInterface)
let baseProperty = (
from property in @base.Class.Properties
baseProperty = @base.Class.GetBaseProperty(@override, onlyFirstBase);
if (baseProperty != null)
return baseProperty;
}
baseProperty = (from property in @base.Class.Properties
where
property.OriginalName == @override.OriginalName &&
property.Parameters.SequenceEqual(@override.Parameters,
new ParameterTypeComparer())
select property).FirstOrDefault()
let rootBaseProperty = @base.Class.GetRootBaseProperty(@override, onlyFirstBase) ?? baseProperty
where rootBaseProperty != null || onlyFirstBase
select rootBaseProperty).FirstOrDefault();
property.Parameters.SequenceEqual(@override.Parameters, new ParameterTypeComparer())
select property).FirstOrDefault();
if (baseProperty != null)
return baseProperty;
if (getTopmost)
{
baseProperty = @base.Class.GetBaseProperty(@override, onlyFirstBase, true);
if (baseProperty != null)
return baseProperty;
}
}
return null;
}
public static Property GetPropertyByName(this Class c, string propertyName)

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

@ -1211,7 +1211,7 @@ namespace CppSharp.Generators.CSharp @@ -1211,7 +1211,7 @@ namespace CppSharp.Generators.CSharp
// check if overriding a property from a secondary base
Property rootBaseProperty;
var isOverride = prop.IsOverride &&
(rootBaseProperty = @class.GetRootBaseProperty(prop, true)) != null &&
(rootBaseProperty = @class.GetBaseProperty(prop, true)) != null &&
(rootBaseProperty.IsVirtual || rootBaseProperty.IsPure);
if (isOverride)
@ -2317,7 +2317,7 @@ namespace CppSharp.Generators.CSharp @@ -2317,7 +2317,7 @@ namespace CppSharp.Generators.CSharp
return AccessSpecifier.Public;
default:
return property.IsOverride ?
((Class) property.Namespace).GetRootBaseProperty(property).Access : property.Access;
((Class) property.Namespace).GetBaseProperty(property).Access : property.Access;
}
}

6
src/Generator/Passes/GetterSetterToPropertyAdvancedPass.cs

@ -84,7 +84,7 @@ namespace CppSharp.Passes @@ -84,7 +84,7 @@ namespace CppSharp.Passes
goto next;
}
}
Property baseProperty = type.GetRootBaseProperty(new Property { Name = afterSet });
Property baseProperty = type.GetBaseProperty(new Property { Name = afterSet }, getTopmost: true);
if (!type.IsInterface && baseProperty != null && baseProperty.IsVirtual && setter.IsVirtual)
{
bool isReadOnly = baseProperty.SetMethod == null;
@ -98,7 +98,7 @@ namespace CppSharp.Passes @@ -98,7 +98,7 @@ namespace CppSharp.Passes
{
Class type = (Class) nonSetter.Namespace;
string name = GetPropertyName(nonSetter.Name);
Property baseProperty = type.GetRootBaseProperty(new Property { Name = name });
Property baseProperty = type.GetBaseProperty(new Property { Name = name }, getTopmost: true);
if (!type.IsInterface && baseProperty != null && baseProperty.IsVirtual)
{
bool isReadOnly = baseProperty.SetMethod == null;
@ -151,7 +151,7 @@ namespace CppSharp.Passes @@ -151,7 +151,7 @@ namespace CppSharp.Passes
};
if (getter.IsOverride || (setter != null && setter.IsOverride))
{
var baseVirtualProperty = type.GetRootBaseProperty(property);
var baseVirtualProperty = type.GetBaseProperty(property, getTopmost: true);
if (baseVirtualProperty.SetMethod == null)
setter = null;
}

2
src/Generator/Passes/MultipleInheritancePass.cs

@ -214,7 +214,7 @@ namespace CppSharp.Passes @@ -214,7 +214,7 @@ namespace CppSharp.Passes
foreach (var property in @interface.Properties.Where(p => p.Name != Helpers.InstanceIdentifier))
{
var impl = new Property(property) { Namespace = @class };
var rootBaseProperty = @class.GetRootBaseProperty(property, true);
var rootBaseProperty = @class.GetBaseProperty(property, true);
if (rootBaseProperty != null && rootBaseProperty.IsDeclared)
impl.ExplicitInterfaceImpl = @interface;
@class.Properties.Add(impl);

2
src/Generator/Passes/RenamePass.cs

@ -57,7 +57,7 @@ namespace CppSharp.Passes @@ -57,7 +57,7 @@ namespace CppSharp.Passes
var property = decl as Property;
if (property != null && !property.IsStatic)
{
var rootBaseProperty = ((Class) property.Namespace).GetRootBaseProperty(property);
var rootBaseProperty = ((Class) property.Namespace).GetBaseProperty(property);
if (rootBaseProperty != null && rootBaseProperty != property)
{
newName = rootBaseProperty.Name;

9
tests/CSharp/CSharp.Tests.cs

@ -461,4 +461,13 @@ public class CSharpTests : GeneratorTestFixture @@ -461,4 +461,13 @@ public class CSharpTests : GeneratorTestFixture
testHashes[testComparison2] = 2;
Assert.That(testHashes[testComparison1], Is.EqualTo(2));
}
[Test]
public void TestOverriddenPropertyFromIndirectBase()
{
using (var overridePropertyFromIndirectPrimaryBase = new OverridePropertyFromIndirectPrimaryBase())
{
Assert.That(overridePropertyFromIndirectPrimaryBase.Property, Is.EqualTo(5));
}
}
}

21
tests/CSharp/CSharp.cpp

@ -812,3 +812,24 @@ bool TestComparison::operator ==(const TestComparison& other) const @@ -812,3 +812,24 @@ bool TestComparison::operator ==(const TestComparison& other) const
{
return A == other.A && B == other.B;
}
OverridePropertyFromIndirectPrimaryBaseBase::OverridePropertyFromIndirectPrimaryBaseBase()
{
}
OverridePropertyFromDirectPrimaryBase::OverridePropertyFromDirectPrimaryBase()
{
}
void OverridePropertyFromDirectPrimaryBase::setProperty(int value)
{
}
OverridePropertyFromIndirectPrimaryBase::OverridePropertyFromIndirectPrimaryBase()
{
}
int OverridePropertyFromIndirectPrimaryBase::property()
{
return 5;
}

24
tests/CSharp/CSharp.h

@ -698,7 +698,7 @@ public: @@ -698,7 +698,7 @@ public:
OverrideFromDirectSecondaryBase();
};
class OverrideFromIndirectSecondaryBase : public OverrideFromDirectSecondaryBase
class DLL_API OverrideFromIndirectSecondaryBase : public OverrideFromDirectSecondaryBase
{
public:
OverrideFromIndirectSecondaryBase();
@ -742,3 +742,25 @@ public: @@ -742,3 +742,25 @@ public:
float B;
bool operator ==(const TestComparison& other) const;
};
class DLL_API OverridePropertyFromIndirectPrimaryBaseBase
{
public:
OverridePropertyFromIndirectPrimaryBaseBase();
virtual int property() = 0;
virtual void setProperty(int value) = 0;
};
class DLL_API OverridePropertyFromDirectPrimaryBase : public OverridePropertyFromIndirectPrimaryBaseBase
{
public:
OverridePropertyFromDirectPrimaryBase();
void setProperty(int value);
};
class DLL_API OverridePropertyFromIndirectPrimaryBase : public OverridePropertyFromDirectPrimaryBase
{
public:
OverridePropertyFromIndirectPrimaryBase();
int property();
};

Loading…
Cancel
Save