Browse Source

Added a new class type "Interface".

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/68/head
Dimitar Dobrev 13 years ago
parent
commit
593aac162e
  1. 8
      src/AST/Class.cs
  2. 17
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  3. 3
      src/Generator/Passes/CheckDuplicatedNamesPass.cs
  4. 3
      src/Generator/Passes/GenerateAbstractImplementationsPass.cs
  5. 23
      src/Generator/Passes/MultipleInheritancePass.cs
  6. 2
      src/Generator/Passes/ParamTypeToInterfacePass.cs

8
src/AST/Class.cs

@ -59,6 +59,7 @@ namespace CppSharp.AST
{ {
ValueType, ValueType,
RefType, RefType,
Interface
} }
// Represents a C++ record Decl. // Represents a C++ record Decl.
@ -82,8 +83,6 @@ namespace CppSharp.AST
// True if class provides pure virtual methods. // True if class provides pure virtual methods.
public bool IsAbstract; public bool IsAbstract;
public bool IsInterface { get; set; }
// True if the type is to be treated as a union. // True if the type is to be treated as a union.
public bool IsUnion; public bool IsUnion;
@ -153,6 +152,11 @@ namespace CppSharp.AST
get { return Type == ClassType.RefType && !IsUnion; } get { return Type == ClassType.RefType && !IsUnion; }
} }
public bool IsInterface
{
get { return Type == ClassType.Interface; }
}
public IEnumerable<Method> Constructors public IEnumerable<Method> Constructors
{ {
get get

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

@ -663,8 +663,7 @@ namespace CppSharp.Generators.CSharp
if (@class.HasBaseClass) if (@class.HasBaseClass)
baseClass = @class.Bases[0].Class; baseClass = @class.Bases[0].Class;
var hasRefBase = baseClass != null && baseClass.IsRefType var hasRefBase = baseClass != null && baseClass.IsRefType && !baseClass.Ignore;
&& !baseClass.Ignore && !baseClass.IsInterface;
var hasIgnoredBase = baseClass != null && baseClass.Ignore; var hasIgnoredBase = baseClass != null && baseClass.Ignore;
@ -692,9 +691,7 @@ namespace CppSharp.Generators.CSharp
&& !@class.Bases[0].Class.IsValueType && !@class.Bases[0].Class.IsValueType
&& !@class.Bases[0].Class.Ignore; && !@class.Bases[0].Class.Ignore;
var isRefClass = @class.IsRefType && !@class.IsInterface; if (needsBase || @class.IsRefType)
if (needsBase || isRefClass)
Write(" : "); Write(" : ");
if (needsBase) if (needsBase)
@ -703,11 +700,11 @@ namespace CppSharp.Generators.CSharp
from @base in @class.Bases from @base in @class.Bases
select QualifiedIdentifier(@base.Class))); select QualifiedIdentifier(@base.Class)));
if (isRefClass) if (@class.IsRefType)
Write(", "); Write(", ");
} }
if (isRefClass) if (@class.IsRefType)
Write("IDisposable"); Write("IDisposable");
} }
@ -1422,8 +1419,7 @@ namespace CppSharp.Generators.CSharp
private void GenerateDisposeMethods(Class @class) private void GenerateDisposeMethods(Class @class)
{ {
var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType && var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType;
!@class.BaseClass.IsInterface;
// Generate the IDispose Dispose() method. // Generate the IDispose Dispose() method.
if (!hasBaseClass) if (!hasBaseClass)
@ -1492,8 +1488,7 @@ namespace CppSharp.Generators.CSharp
WriteLine("internal {0}(global::System.IntPtr native){1}", safeIdentifier, WriteLine("internal {0}(global::System.IntPtr native){1}", safeIdentifier,
@class.IsValueType ? " : this()" : string.Empty); @class.IsValueType ? " : this()" : string.Empty);
var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType && var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType;
!@class.BaseClass.IsInterface;
if (hasBaseClass) if (hasBaseClass)
WriteLineIndent(": base(native)"); WriteLineIndent(": base(native)");

3
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -32,7 +32,8 @@ namespace CppSharp.Passes
} }
var property = decl as Property; var property = decl as Property;
if (property != null && property.Parameters.Count > 0) var isIndexer = property != null && property.Parameters.Count > 0;
if (isIndexer)
{ {
return false; return false;
} }

3
src/Generator/Passes/GenerateAbstractImplementationsPass.cs

@ -51,8 +51,7 @@ namespace CppSharp.Passes
foreach (var abstractMethod in abstractMethods) foreach (var abstractMethod in abstractMethods)
{ {
var method = new Method(abstractMethod); var method = new Method(abstractMethod) { Namespace = internalImpl };
method.Namespace = internalImpl;
internalImpl.Methods.Add(method); internalImpl.Methods.Add(method);
var @delegate = new TypedefDecl var @delegate = new TypedefDecl
{ {

23
src/Generator/Passes/MultipleInheritancePass.cs

@ -8,7 +8,10 @@ namespace CppSharp.Passes
public class MultipleInheritancePass : TranslationUnitPass public class MultipleInheritancePass : TranslationUnitPass
{ {
/// <summary> /// <summary>
/// Collects all interfaces in a unit to be added at the end because the unit cannot be changed while it's being iterated though. /// Collects all interfaces in a unit to be added at the end
/// because the unit cannot be changed while it's being iterated though.
/// We also need it to check if a class already has a complementary interface
/// because different classes may have the same secondary bases.
/// </summary> /// </summary>
private readonly Dictionary<Class, Class> interfaces = new Dictionary<Class, Class>(); private readonly Dictionary<Class, Class> interfaces = new Dictionary<Class, Class>();
@ -23,6 +26,7 @@ namespace CppSharp.Passes
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
// skip the first base because we can inherit from one class
for (int i = 1; i < @class.Bases.Count; i++) for (int i = 1; i < @class.Bases.Count; i++)
{ {
var @base = @class.Bases[i].Class; var @base = @class.Bases[i].Class;
@ -39,10 +43,11 @@ namespace CppSharp.Passes
if (@base.CompleteDeclaration != null) if (@base.CompleteDeclaration != null)
@base = (Class) @base.CompleteDeclaration; @base = (Class) @base.CompleteDeclaration;
var name = "I" + @base.Name; var name = "I" + @base.Name;
var @interface = (interfaces.ContainsKey(@base) ? interfaces[@base] if (interfaces.ContainsKey(@base))
: @base.Namespace.Classes.FirstOrDefault(c => c.Name == name)) ?? return interfaces[@base];
GetNewInterface(@class, name, @base, addMembers);
return @interface; return @base.Namespace.Classes.FirstOrDefault(c => c.Name == name) ??
GetNewInterface(@class, name, @base, addMembers);
} }
private Class GetNewInterface(Class @class, string name, Class @base, bool addMembers = false) private Class GetNewInterface(Class @class, string name, Class @base, bool addMembers = false)
@ -52,16 +57,19 @@ namespace CppSharp.Passes
Name = name, Name = name,
Namespace = @base.Namespace, Namespace = @base.Namespace,
Access = @base.Access, Access = @base.Access,
IsInterface = true, Type = ClassType.Interface,
OriginalClass = @base OriginalClass = @base
}; };
@interface.Bases.AddRange( @interface.Bases.AddRange(
from b in @base.Bases from b in @base.Bases
let i = GetInterface(@base, b.Class) let i = GetInterface(@base, b.Class)
select new BaseClassSpecifier { Type = new TagType(i) }); select new BaseClassSpecifier { Type = new TagType(i) });
@interface.Methods.AddRange(@base.Methods.Where( @interface.Methods.AddRange(@base.Methods.Where(
m => !m.IsConstructor && !m.IsDestructor && !m.IsStatic && !m.Ignore)); m => !m.IsConstructor && !m.IsDestructor && !m.IsStatic && !m.Ignore));
@interface.Properties.AddRange(@base.Properties.Where(p => !p.Ignore)); @interface.Properties.AddRange(@base.Properties.Where(p => !p.Ignore));
if (@interface.Bases.Count == 0) if (@interface.Bases.Count == 0)
{ {
Property instance = new Property(); Property instance = new Property();
@ -70,7 +78,9 @@ namespace CppSharp.Passes
instance.GetMethod = new Method(); instance.GetMethod = new Method();
@interface.Properties.Add(instance); @interface.Properties.Add(instance);
} }
@interface.Events.AddRange(@base.Events); @interface.Events.AddRange(@base.Events);
if (addMembers) if (addMembers)
{ {
ImplementInterfaceMethods(@class, @interface); ImplementInterfaceMethods(@class, @interface);
@ -78,6 +88,7 @@ namespace CppSharp.Passes
if (@base.Bases.All(b => b.Class != @interface)) if (@base.Bases.All(b => b.Class != @interface))
@base.Bases.Add(new BaseClassSpecifier { Type = new TagType(@interface) }); @base.Bases.Add(new BaseClassSpecifier { Type = new TagType(@interface) });
} }
interfaces.Add(@base, @interface); interfaces.Add(@base, @interface);
return @interface; return @interface;
} }

2
src/Generator/Passes/ParamTypeToInterfacePass.cs

@ -18,7 +18,7 @@ namespace CppSharp.Passes
var @class = tagType.Declaration as Class; var @class = tagType.Declaration as Class;
if (@class != null) if (@class != null)
{ {
var @interface = @class.Namespace.FindClass("I" + @class.Name); var @interface = @class.Namespace.Classes.Find(c => c.OriginalClass == @class);
if (@interface != null) if (@interface != null)
parameter.QualifiedType = new QualifiedType(new TagType(@interface)); parameter.QualifiedType = new QualifiedType(new TagType(@interface));
} }

Loading…
Cancel
Save