Browse Source

Incomplete classes and structs are now generated for C#. (#797)

This feature is NOT coming for C++/CLI !
pull/799/head
realvictorprm 8 years ago committed by Dimitar Dobrev
parent
commit
938ccf686b
  1. 15
      src/AST/Class.cs
  2. 6
      src/Generator/Generators/CSharp/CSharpSources.cs
  3. 13
      src/Generator/Passes/CheckIgnoredDecls.cs
  4. 3
      src/Generator/Passes/ResolveIncompleteDeclsPass.cs
  5. 2
      src/Parser/ASTConverter.cs
  6. 8
      tests/CSharp/CSharp.Tests.cs
  7. 12
      tests/CSharp/CSharp.cpp
  8. 7
      tests/CSharp/CSharp.h

15
src/AST/Class.cs

@ -96,8 +96,20 @@ namespace CppSharp.AST
// True if the class is final / sealed. // True if the class is final / sealed.
public bool IsFinal { get; set; } public bool IsFinal { get; set; }
private bool? isOpaque = null;
// True if the type is to be treated as opaque. // True if the type is to be treated as opaque.
public bool IsOpaque; public bool IsOpaque
{
get
{
return isOpaque == null ? IsIncomplete && CompleteDeclaration == null : isOpaque.Value;
}
set
{
isOpaque = value;
}
}
// True if the class is dynamic. // True if the class is dynamic.
public bool IsDynamic; public bool IsDynamic;
@ -127,7 +139,6 @@ namespace CppSharp.AST
IsAbstract = false; IsAbstract = false;
IsUnion = false; IsUnion = false;
IsFinal = false; IsFinal = false;
IsOpaque = false;
IsPOD = false; IsPOD = false;
Type = ClassType.RefType; Type = ClassType.RefType;
Layout = new ClassLayout(); Layout = new ClassLayout();

6
src/Generator/Generators/CSharp/CSharpSources.cs

@ -272,7 +272,7 @@ namespace CppSharp.Generators.CSharp
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
if (@class.IsIncomplete) if (@class.IsIncomplete && !@class.IsOpaque)
return false; return false;
if (@class.IsInterface) if (@class.IsInterface)
@ -309,14 +309,11 @@ namespace CppSharp.Generators.CSharp
PushBlock(BlockKind.Class); PushBlock(BlockKind.Class);
GenerateDeclarationCommon(@class); GenerateDeclarationCommon(@class);
GenerateClassSpecifier(@class); GenerateClassSpecifier(@class);
NewLine(); NewLine();
WriteStartBraceIndent(); WriteStartBraceIndent();
if (!@class.IsOpaque)
{
if (!@class.IsAbstractImpl) if (!@class.IsAbstractImpl)
GenerateClassInternals(@class); GenerateClassInternals(@class);
@ -364,7 +361,6 @@ namespace CppSharp.Generators.CSharp
if (@class.IsDynamic) if (@class.IsDynamic)
GenerateVTable(@class); GenerateVTable(@class);
}
exit: exit:
WriteCloseBraceIndent(); WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock); PopBlock(NewLineKind.BeforeNextBlock);

13
src/Generator/Passes/CheckIgnoredDecls.cs

@ -369,6 +369,14 @@ namespace CppSharp.Passes
return true; return true;
} }
var @class = decl as Class;
if (@class != null && @class.IsOpaque && !@class.IsDependent &&
!(@class is ClassTemplateSpecialization))
{
msg = null;
return false;
}
if (decl.IsIncomplete) if (decl.IsIncomplete)
{ {
msg = "incomplete"; msg = "incomplete";
@ -400,6 +408,11 @@ namespace CppSharp.Passes
Declaration decl; Declaration decl;
if (!finalType.TryGetDeclaration(out decl)) return true; if (!finalType.TryGetDeclaration(out decl)) return true;
var @class = (decl as Class);
if (@class != null && @class.IsOpaque && !@class.IsDependent &&
!(@class is ClassTemplateSpecialization))
return true;
return !decl.IsIncomplete || decl.CompleteDeclaration != null; return !decl.IsIncomplete || decl.CompleteDeclaration != null;
} }

3
src/Generator/Passes/ResolveIncompleteDeclsPass.cs

@ -67,6 +67,9 @@ namespace CppSharp.Passes
if (declaration.CompleteDeclaration != null) if (declaration.CompleteDeclaration != null)
return; return;
var @class = declaration as Class;
if (@class != null && @class.IsOpaque) return;
declaration.CompleteDeclaration = declaration.CompleteDeclaration =
ASTContext.FindCompleteClass(declaration.QualifiedName); ASTContext.FindCompleteClass(declaration.QualifiedName);

2
src/Parser/ASTConverter.cs

@ -994,7 +994,7 @@ namespace CppSharp
{ {
var decl = ctx.GetClasses(i); var decl = ctx.GetClasses(i);
var _decl = Visit(decl) as AST.Class; var _decl = Visit(decl) as AST.Class;
if (!_decl.IsIncomplete) if (!_decl.IsIncomplete || _decl.IsOpaque)
_ctx.Classes.Add(_decl); _ctx.Classes.Add(_decl);
} }

8
tests/CSharp/CSharp.Tests.cs

@ -698,4 +698,12 @@ public unsafe class CSharpTests : GeneratorTestFixture
return base.HasPointerToEnumInParam(pointerToEnum); return base.HasPointerToEnumInParam(pointerToEnum);
} }
} }
[Test]
public void TestGenerationOfIncompleteClasses()
{
var incompleteStruct = CSharp.CSharp.CreateIncompleteStruct();
Assert.IsNotNull(incompleteStruct);
Assert.DoesNotThrow(() => CSharp.CSharp.UseIncompleteStruct(incompleteStruct));
}
} }

12
tests/CSharp/CSharp.cpp

@ -1310,3 +1310,15 @@ void HasGetterAndOverriddenSetter::setBaseSetter(int value)
void hasArrayOfConstChar(const char* const arrayOfConstChar[]) void hasArrayOfConstChar(const char* const arrayOfConstChar[])
{ {
} }
struct IncompleteStruct {};
IncompleteStruct* createIncompleteStruct()
{
return new IncompleteStruct();
}
DLL_API void useIncompleteStruct(IncompleteStruct * a)
{
return;
}

7
tests/CSharp/CSharp.h

@ -1151,3 +1151,10 @@ protected:
}; };
void DLL_API hasArrayOfConstChar(const char* const arrayOfConstChar[]); void DLL_API hasArrayOfConstChar(const char* const arrayOfConstChar[]);
struct CompleteIncompleteStruct;
typedef struct IncompleteStruct IncompleteStruct;
DLL_API IncompleteStruct* createIncompleteStruct();
DLL_API void useIncompleteStruct(IncompleteStruct* a);
Loading…
Cancel
Save