Browse Source

Completed the parallel hierarchy of interfaces so that a derived class can access the members of all of its bases.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/68/head
Dimitar Dobrev 12 years ago
parent
commit
c9e5c0d505
  1. 10
      src/AST/Class.cs
  2. 21
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 62
      src/Generator/Passes/MultipleInheritancePass.cs
  4. 5
      tests/CSharpTemp/CSharpTemp.cpp
  5. 8
      tests/CSharpTemp/CSharpTemp.h

10
src/AST/Class.cs

@ -203,9 +203,10 @@ namespace CppSharp.AST @@ -203,9 +203,10 @@ namespace CppSharp.AST
}
}
public Method GetRootBaseMethod(Method @override)
public Method GetRootBaseMethod(Method @override, bool onlyFirstBase = false)
{
return (from @base in Bases
where !@base.Class.IsInterface
let baseMethod = (
from method in @base.Class.Methods
where
@ -216,13 +217,14 @@ namespace CppSharp.AST @@ -216,13 +217,14 @@ namespace CppSharp.AST
new ParameterTypeComparer())
select method).FirstOrDefault()
let rootBaseMethod = @base.Class.GetRootBaseMethod(@override) ?? baseMethod
where rootBaseMethod != null
where rootBaseMethod != null || onlyFirstBase
select rootBaseMethod).FirstOrDefault();
}
public Property GetRootBaseProperty(Property @override)
public Property GetRootBaseProperty(Property @override, bool onlyFirstBase = false)
{
return (from @base in Bases
where !@base.Class.IsInterface
let baseProperty = (
from property in @base.Class.Properties
where
@ -232,7 +234,7 @@ namespace CppSharp.AST @@ -232,7 +234,7 @@ namespace CppSharp.AST
new ParameterTypeComparer())
select property).FirstOrDefault()
let rootBaseProperty = @base.Class.GetRootBaseProperty(@override) ?? baseProperty
where rootBaseProperty != null
where rootBaseProperty != null || onlyFirstBase
select rootBaseProperty).FirstOrDefault();
}

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

@ -375,21 +375,12 @@ namespace CppSharp.Generators.CSharp @@ -375,21 +375,12 @@ namespace CppSharp.Generators.CSharp
Write("interface ");
Write("{0}", SafeIdentifier(@class.Name));
//var needsBase = @class.HasBaseClass && !@class.IsValueType
// && !@class.Bases[0].Class.IsValueType
// && !@class.Bases[0].Class.Ignore;
//if (needsBase || @class.IsRefType)
// Write(" : ");
//if (needsBase)
//{
// var qualifiedBase = QualifiedIdentifier(@class.Bases[0].Class);
// Write("{0}", qualifiedBase);
// if (@class.IsRefType)
// Write(", ");
//}
if (@class.HasBase)
{
Write(" : {0}", string.Join(", ",
from @base in @class.Bases
select QualifiedIdentifier(@base.Class)));
}
NewLine();
WriteStartBraceIndent();

62
src/Generator/Passes/MultipleInheritancePass.cs

@ -27,19 +27,25 @@ namespace CppSharp.Passes @@ -27,19 +27,25 @@ namespace CppSharp.Passes
var @base = @class.Bases[i].Class;
if (@base.IsInterface) continue;
var @interface = GetInterface(@class, @base, true);
@class.Bases[i] = new BaseClassSpecifier { Type = new TagType(@interface) };
}
return base.VisitClassDecl(@class);
}
private Class GetInterface(Class @class, Class @base, bool addMembers = false)
{
if (@base.CompleteDeclaration != null)
@base = (Class) @base.CompleteDeclaration;
var name = "I" + @base.Name;
var @interface = (interfaces.ContainsKey(@base)
? interfaces[@base]
var @interface = (this.interfaces.ContainsKey(@base)
? this.interfaces[@base]
: @base.Namespace.Classes.FirstOrDefault(c => c.Name == name)) ??
GetNewInterface(@class, name, @base);
@class.Bases[i] = new BaseClassSpecifier { Type = new TagType(@interface) };
}
return base.VisitClassDecl(@class);
GetNewInterface(@class, name, @base, addMembers);
return @interface;
}
private Class GetNewInterface(Class @class, string name, Class @base)
private Class GetNewInterface(Class @class, string name, Class @base, bool addMembers = false)
{
var @interface = new Class
{
@ -48,8 +54,27 @@ namespace CppSharp.Passes @@ -48,8 +54,27 @@ namespace CppSharp.Passes
Access = @base.Access,
IsInterface = true
};
@interface.Bases.AddRange(
from b in @base.Bases
let i = GetInterface(@base, b.Class)
select new BaseClassSpecifier { Type = new TagType(i) });
@interface.Methods.AddRange(@base.Methods.Where(
m => !m.IsConstructor && !m.IsDestructor && !m.IsStatic && !m.Ignore));
@interface.Properties.AddRange(@base.Properties.Where(p => !p.Ignore));
@interface.Events.AddRange(@base.Events);
if (addMembers)
{
ImplementInterfaceMethods(@class, @interface);
ImplementInterfaceProperties(@class, @interface);
if (@base.Bases.All(b => b.Class != @interface))
@base.Bases.Add(new BaseClassSpecifier { Type = new TagType(@interface) });
}
interfaces.Add(@base, @interface);
return @interface;
}
private static void ImplementInterfaceMethods(Class @class, Class @interface)
{
foreach (var method in @interface.Methods)
{
var impl = new Method(method)
@ -58,28 +83,27 @@ namespace CppSharp.Passes @@ -58,28 +83,27 @@ namespace CppSharp.Passes
IsVirtual = false,
IsOverride = false
};
var rootBaseMethod = @class.GetRootBaseMethod(method);
var rootBaseMethod = @class.GetRootBaseMethod(method, true);
if (rootBaseMethod != null && !rootBaseMethod.Ignore)
impl.Name = @interface.Name + "." + impl.Name;
@class.Methods.Add(impl);
}
@interface.Properties.AddRange(@base.Properties.Where(p => !p.Ignore));
foreach (var property in @interface.Properties)
foreach (var @base in @interface.Bases)
ImplementInterfaceMethods(@class, @base.Class);
}
private static void ImplementInterfaceProperties(Class @class, Class @interface)
{
var impl = new Property(property)
foreach (var property in @interface.Properties)
{
Namespace = @class
};
var rootBaseProperty = @class.GetRootBaseProperty(property);
var impl = new Property(property) { Namespace = @class };
var rootBaseProperty = @class.GetRootBaseProperty(property, true);
if (rootBaseProperty != null && !rootBaseProperty.Ignore)
impl.Name = @interface.Name + "." + impl.Name;
@class.Properties.Add(impl);
}
@interface.Events.AddRange(@base.Events);
if (@base.Bases.All(b => b.Class != @interface))
@base.Bases.Add(new BaseClassSpecifier { Type = new TagType(@interface) });
interfaces.Add(@base, @interface);
return @interface;
foreach (var @base in @interface.Bases)
ImplementInterfaceProperties(@class, @base.Class);
}
}
}

5
tests/CSharpTemp/CSharpTemp.cpp

@ -31,6 +31,11 @@ const Foo& Bar::operator[](int i) const @@ -31,6 +31,11 @@ const Foo& Bar::operator[](int i) const
return m_foo;
}
int Qux::farAwayFunc()
{
return 20;
}
int Bar::method()
{
return 2;

8
tests/CSharpTemp/CSharpTemp.h

@ -18,7 +18,13 @@ protected: @@ -18,7 +18,13 @@ protected:
int P;
};
class DLL_API Bar
class DLL_API Qux
{
public:
int farAwayFunc();
};
class DLL_API Bar : public Qux
{
public:
int method();

Loading…
Cancel
Save