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

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

@ -1211,7 +1211,7 @@ namespace CppSharp.Generators.CSharp
// check if overriding a property from a secondary base // check if overriding a property from a secondary base
Property rootBaseProperty; Property rootBaseProperty;
var isOverride = prop.IsOverride && var isOverride = prop.IsOverride &&
(rootBaseProperty = @class.GetRootBaseProperty(prop, true)) != null && (rootBaseProperty = @class.GetBaseProperty(prop, true)) != null &&
(rootBaseProperty.IsVirtual || rootBaseProperty.IsPure); (rootBaseProperty.IsVirtual || rootBaseProperty.IsPure);
if (isOverride) if (isOverride)
@ -2317,7 +2317,7 @@ namespace CppSharp.Generators.CSharp
return AccessSpecifier.Public; return AccessSpecifier.Public;
default: default:
return property.IsOverride ? 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
goto next; 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) if (!type.IsInterface && baseProperty != null && baseProperty.IsVirtual && setter.IsVirtual)
{ {
bool isReadOnly = baseProperty.SetMethod == null; bool isReadOnly = baseProperty.SetMethod == null;
@ -98,7 +98,7 @@ namespace CppSharp.Passes
{ {
Class type = (Class) nonSetter.Namespace; Class type = (Class) nonSetter.Namespace;
string name = GetPropertyName(nonSetter.Name); 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) if (!type.IsInterface && baseProperty != null && baseProperty.IsVirtual)
{ {
bool isReadOnly = baseProperty.SetMethod == null; bool isReadOnly = baseProperty.SetMethod == null;
@ -151,7 +151,7 @@ namespace CppSharp.Passes
}; };
if (getter.IsOverride || (setter != null && setter.IsOverride)) if (getter.IsOverride || (setter != null && setter.IsOverride))
{ {
var baseVirtualProperty = type.GetRootBaseProperty(property); var baseVirtualProperty = type.GetBaseProperty(property, getTopmost: true);
if (baseVirtualProperty.SetMethod == null) if (baseVirtualProperty.SetMethod == null)
setter = null; setter = null;
} }

2
src/Generator/Passes/MultipleInheritancePass.cs

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

2
src/Generator/Passes/RenamePass.cs

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

9
tests/CSharp/CSharp.Tests.cs

@ -461,4 +461,13 @@ public class CSharpTests : GeneratorTestFixture
testHashes[testComparison2] = 2; testHashes[testComparison2] = 2;
Assert.That(testHashes[testComparison1], Is.EqualTo(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
{ {
return A == other.A && B == other.B; 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:
OverrideFromDirectSecondaryBase(); OverrideFromDirectSecondaryBase();
}; };
class OverrideFromIndirectSecondaryBase : public OverrideFromDirectSecondaryBase class DLL_API OverrideFromIndirectSecondaryBase : public OverrideFromDirectSecondaryBase
{ {
public: public:
OverrideFromIndirectSecondaryBase(); OverrideFromIndirectSecondaryBase();
@ -742,3 +742,25 @@ public:
float B; float B;
bool operator ==(const TestComparison& other) const; 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