Browse Source

Do not generate the destructor/finalizer pair if the destructor of the native class is protected.

Had to fix line endings (LF) in the CLI* files.
pull/237/head
Elias Holzer 11 years ago
parent
commit
6145bf600b
  1. 127
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  2. 75
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  3. 6
      tests/CLITemp/CLITemp.cs
  4. 9
      tests/CLITemp/CLITemp.h

127
src/Generator/Generators/CLI/CLIHeadersTemplate.cs

@ -52,8 +52,8 @@ namespace CppSharp.Generators.CLI @@ -52,8 +52,8 @@ namespace CppSharp.Generators.CLI
public void GenerateIncludeForwardRefs()
{
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase,
Driver.Options);
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase,
Driver.Options);
typeReferenceCollector.Process(TranslationUnit, filterNamespaces: false);
var includes = new SortedSet<string>(StringComparer.InvariantCulture);
@ -68,8 +68,8 @@ namespace CppSharp.Generators.CLI @@ -68,8 +68,8 @@ namespace CppSharp.Generators.CLI
var include = typeRef.Include;
var unit = include.TranslationUnit;
if (unit != null && !unit.IsDeclared)
if (unit != null && !unit.IsDeclared)
continue;
if(!string.IsNullOrEmpty(include.File) && include.InHeader)
@ -130,8 +130,8 @@ namespace CppSharp.Generators.CLI @@ -130,8 +130,8 @@ namespace CppSharp.Generators.CLI
public void GenerateForwardRefs()
{
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase,
Driver.Options);
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase,
Driver.Options);
typeReferenceCollector.Process(TranslationUnit);
var typeReferences = typeReferenceCollector.TypeReferences;
@ -151,7 +151,7 @@ namespace CppSharp.Generators.CLI @@ -151,7 +151,7 @@ namespace CppSharp.Generators.CLI
// Generate all the enum declarations for the module.
foreach (var @enum in decl.Enums)
{
if (!@enum.IsGenerated || @enum.IsIncomplete)
if (!@enum.IsGenerated || @enum.IsIncomplete)
continue;
PushBlock(CLIBlockKind.Enum, @enum);
@ -165,7 +165,7 @@ namespace CppSharp.Generators.CLI @@ -165,7 +165,7 @@ namespace CppSharp.Generators.CLI
// Generate all the struct/class declarations for the module.
foreach (var @class in decl.Classes)
{
if (!@class.IsGenerated || @class.IsIncomplete)
if (!@class.IsGenerated || @class.IsIncomplete)
continue;
if (@class.IsOpaque)
@ -210,7 +210,7 @@ namespace CppSharp.Generators.CLI @@ -210,7 +210,7 @@ namespace CppSharp.Generators.CLI
{
foreach (var typedef in decl.Typedefs)
{
if (!typedef.IsGenerated)
if (!typedef.IsGenerated)
continue;
GenerateTypedef(typedef);
@ -221,7 +221,7 @@ namespace CppSharp.Generators.CLI @@ -221,7 +221,7 @@ namespace CppSharp.Generators.CLI
{
PushBlock(CLIBlockKind.FunctionsClass);
WriteLine("public ref class {0}", TranslationUnit.FileNameWithoutExtension);
WriteLine("public ref class {0}", TranslationUnit.FileNameWithoutExtension);
WriteLine("{");
WriteLine("public:");
PushIndent();
@ -240,7 +240,7 @@ namespace CppSharp.Generators.CLI @@ -240,7 +240,7 @@ namespace CppSharp.Generators.CLI
public void GenerateClass(Class @class)
{
if (!@class.IsGenerated || @class.IsIncomplete)
if (!@class.IsGenerated || @class.IsIncomplete)
return;
GenerateDeclarationCommon(@class);
@ -270,15 +270,15 @@ namespace CppSharp.Generators.CLI @@ -270,15 +270,15 @@ namespace CppSharp.Generators.CLI
GenerateClassVariables(@class);
PushBlock(CLIBlockKind.AccessSpecifier);
WriteLine("private:");
var accBlock = PopBlock(NewLineKind.IfNotEmpty);
PushBlock(CLIBlockKind.AccessSpecifier);
WriteLine("private:");
var accBlock = PopBlock(NewLineKind.IfNotEmpty);
PushBlock(CLIBlockKind.Fields);
GenerateClassFields(@class);
var fieldsBlock = PopBlock();
PushBlock(CLIBlockKind.Fields);
GenerateClassFields(@class);
var fieldsBlock = PopBlock();
accBlock.CheckGenerate = () => !fieldsBlock.IsEmpty;
accBlock.CheckGenerate = () => !fieldsBlock.IsEmpty;
WriteLine("};");
}
@ -306,7 +306,7 @@ namespace CppSharp.Generators.CLI @@ -306,7 +306,7 @@ namespace CppSharp.Generators.CLI
PushIndent();
foreach (var template in @class.Templates)
{
if (!template.IsGenerated) continue;
if (!template.IsGenerated) continue;
var functionTemplate = template as FunctionTemplate;
if (functionTemplate == null) continue;
@ -371,7 +371,7 @@ namespace CppSharp.Generators.CLI @@ -371,7 +371,7 @@ namespace CppSharp.Generators.CLI
WriteLine("{0}({1} native);", @class.Name, "System::IntPtr");
foreach (var ctor in @class.Constructors)
{
{
if (ASTUtils.CheckIgnoreMethod(ctor, Options))
continue;
@ -382,10 +382,15 @@ namespace CppSharp.Generators.CLI @@ -382,10 +382,15 @@ namespace CppSharp.Generators.CLI
GenerateMethod(ctor);
}
if (@class.IsRefType)
if (Options.GenerateFinalizers && @class.IsRefType)
{
GenerateClassDestructor(@class);
GenerateClassFinalizer(@class);
var destructor = @class.Destructors
.FirstOrDefault(d => d.Parameters.Count == 0 && d.Access == AccessSpecifier.Public);
if (destructor != null)
{
GenerateClassDestructor(@class);
GenerateClassFinalizer(@class);
}
}
PopIndent();
@ -393,9 +398,6 @@ namespace CppSharp.Generators.CLI @@ -393,9 +398,6 @@ namespace CppSharp.Generators.CLI
private void GenerateClassDestructor(Class @class)
{
if (!Options.GenerateFinalizers)
return;
PushBlock(CLIBlockKind.Destructor);
WriteLine("~{0}();", @class.Name);
PopBlock(NewLineKind.BeforeNextBlock);
@ -403,9 +405,6 @@ namespace CppSharp.Generators.CLI @@ -403,9 +405,6 @@ namespace CppSharp.Generators.CLI
private void GenerateClassFinalizer(Class @class)
{
if (!Options.GenerateFinalizers)
return;
PushBlock(CLIBlockKind.Finalizer);
WriteLine("!{0}();", @class.Name);
PopBlock(NewLineKind.BeforeNextBlock);
@ -415,7 +414,7 @@ namespace CppSharp.Generators.CLI @@ -415,7 +414,7 @@ namespace CppSharp.Generators.CLI
{
// Handle the case of struct (value-type) inheritance by adding the base
// properties to the managed value subtypes.
if (@class.IsValueType)
if (@class.IsValueType)
{
foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
{
@ -447,14 +446,14 @@ namespace CppSharp.Generators.CLI @@ -447,14 +446,14 @@ namespace CppSharp.Generators.CLI
field.Offset);
WriteLine("{0} {1};", field.Type, field.Name);
PopBlock();
PopBlock();
}
public void GenerateClassEvents(Class @class)
{
foreach (var @event in @class.Events)
{
if (!@event.IsGenerated) continue;
if (!@event.IsGenerated) continue;
var cppTypePrinter = new CppTypePrinter(Driver.TypeDatabase);
var cppArgs = cppTypePrinter.VisitParameters(@event.Parameters, hasNames: true);
@ -494,7 +493,7 @@ namespace CppSharp.Generators.CLI @@ -494,7 +493,7 @@ namespace CppSharp.Generators.CLI
var staticMethods = new List<Method>();
foreach (var method in @class.Methods)
{
{
if (ASTUtils.CheckIgnoreMethod(method, Options))
continue;
@ -522,7 +521,7 @@ namespace CppSharp.Generators.CLI @@ -522,7 +521,7 @@ namespace CppSharp.Generators.CLI
foreach(var variable in @class.Variables)
{
if (!variable.IsGenerated) continue;
if (!variable.IsGenerated) continue;
if (variable.Access != AccessSpecifier.Public)
continue;
@ -590,7 +589,7 @@ namespace CppSharp.Generators.CLI @@ -590,7 +589,7 @@ namespace CppSharp.Generators.CLI
{
// Handle the case of struct (value-type) inheritance by adding the base
// properties to the managed value subtypes.
if (@class.IsValueType)
if (@class.IsValueType)
{
foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
{
@ -615,18 +614,18 @@ namespace CppSharp.Generators.CLI @@ -615,18 +614,18 @@ namespace CppSharp.Generators.CLI
public void GenerateIndexer(Property property)
{
var type = property.QualifiedType.Visit(TypePrinter);
var getter = property.GetMethod;
var indexParameter = getter.Parameters[0];
var type = property.QualifiedType.Visit(TypePrinter);
var getter = property.GetMethod;
var indexParameter = getter.Parameters[0];
var indexParameterType = indexParameter.QualifiedType.Visit(TypePrinter);
WriteLine("property {0} default[{1}]", type, indexParameterType);
WriteStartBraceIndent();
if (property.HasGetter)
if (property.HasGetter)
WriteLine("{0} get({1} {2});", type, indexParameterType, indexParameter.Name);
if (property.HasSetter)
if (property.HasSetter)
WriteLine("void set({1} {2}, {0} value);", type, indexParameterType, indexParameter.Name);
WriteCloseBraceIndent();
@ -638,9 +637,9 @@ namespace CppSharp.Generators.CLI @@ -638,9 +637,9 @@ namespace CppSharp.Generators.CLI
return;
PushBlock(CLIBlockKind.Property, property);
var type = property.QualifiedType.Visit(TypePrinter);
if (property.IsStatic)
var type = property.QualifiedType.Visit(TypePrinter);
if (property.IsStatic)
Write("static ");
if (property.IsIndexer)
@ -679,9 +678,9 @@ namespace CppSharp.Generators.CLI @@ -679,9 +678,9 @@ namespace CppSharp.Generators.CLI
Operators.IsBuiltinOperator(method.OperatorKind);
if (method.IsStatic || isBuiltinOperator)
Write("static ");
if (method.OperatorKind == CXXOperatorKind.ExplicitConversion)
Write("static ");
if (method.OperatorKind == CXXOperatorKind.ExplicitConversion)
Write("explicit ");
if (method.IsConstructor || method.IsDestructor ||
@ -705,7 +704,7 @@ namespace CppSharp.Generators.CLI @@ -705,7 +704,7 @@ namespace CppSharp.Generators.CLI
public bool GenerateTypedef(TypedefDecl typedef)
{
if (!typedef.IsGenerated)
if (!typedef.IsGenerated)
return false;
FunctionType function;
@ -714,20 +713,20 @@ namespace CppSharp.Generators.CLI @@ -714,20 +713,20 @@ namespace CppSharp.Generators.CLI
PushBlock(CLIBlockKind.Typedef, typedef);
GenerateDeclarationCommon(typedef);
var insideClass = typedef.Namespace is Class;
var attributedType = typedef.Type.GetPointee() as AttributedType;
if (attributedType != null)
{
var equivalentFunctionType = attributedType.Equivalent.Type as FunctionType;
var callingConvention = equivalentFunctionType.CallingConvention.ToInteropCallConv();
if (callingConvention != System.Runtime.InteropServices.CallingConvention.Winapi)
{
WriteLine("[{0}({1}::{2})] ",
"System::Runtime::InteropServices::UnmanagedFunctionPointer",
"System::Runtime::InteropServices::CallingConvention",
callingConvention);
}
var insideClass = typedef.Namespace is Class;
var attributedType = typedef.Type.GetPointee() as AttributedType;
if (attributedType != null)
{
var equivalentFunctionType = attributedType.Equivalent.Type as FunctionType;
var callingConvention = equivalentFunctionType.CallingConvention.ToInteropCallConv();
if (callingConvention != System.Runtime.InteropServices.CallingConvention.Winapi)
{
WriteLine("[{0}({1}::{2})] ",
"System::Runtime::InteropServices::UnmanagedFunctionPointer",
"System::Runtime::InteropServices::CallingConvention",
callingConvention);
}
}
WriteLine("{0}{1};",
@ -744,7 +743,7 @@ namespace CppSharp.Generators.CLI @@ -744,7 +743,7 @@ namespace CppSharp.Generators.CLI
public void GenerateFunction(Function function)
{
if (!function.IsGenerated)
if (!function.IsGenerated)
return;
PushBlock(CLIBlockKind.Function, function);
@ -763,7 +762,7 @@ namespace CppSharp.Generators.CLI @@ -763,7 +762,7 @@ namespace CppSharp.Generators.CLI
public void GenerateEnum(Enumeration @enum)
{
if (!@enum.IsGenerated || @enum.IsIncomplete)
if (!@enum.IsGenerated || @enum.IsIncomplete)
return;
PushBlock(CLIBlockKind.Enum, @enum);

75
src/Generator/Generators/CLI/CLISourcesTemplate.cs

@ -60,7 +60,7 @@ namespace CppSharp.Generators.CLI @@ -60,7 +60,7 @@ namespace CppSharp.Generators.CLI
{
PushBlock(CLIBlockKind.IncludesForwardReferences);
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase, Driver.Options);
var typeReferenceCollector = new CLITypeReferenceCollector(Driver.TypeDatabase, Driver.Options);
typeReferenceCollector.Process(TranslationUnit, filterNamespaces: false);
var includes = new SortedSet<string>(StringComparer.InvariantCulture);
@ -139,7 +139,7 @@ namespace CppSharp.Generators.CLI @@ -139,7 +139,7 @@ namespace CppSharp.Generators.CLI
GenerateClassConstructors(@class);
foreach (var method in @class.Methods)
{
{
if (ASTUtils.CheckIgnoreMethod(method, Options))
continue;
@ -205,10 +205,15 @@ namespace CppSharp.Generators.CLI @@ -205,10 +205,15 @@ namespace CppSharp.Generators.CLI
GenerateClassConstructor(@class, isIntPtr: false);
GenerateClassConstructor(@class, isIntPtr: true);
if (@class.IsRefType)
if (Options.GenerateFinalizers && @class.IsRefType)
{
GenerateClassDestructor(@class);
GenerateClassFinalizer(@class);
var destructor = @class.Destructors
.FirstOrDefault(d => d.Parameters.Count == 0 && d.Access == AccessSpecifier.Public);
if (destructor != null)
{
GenerateClassDestructor(@class);
GenerateClassFinalizer(@class);
}
}
}
@ -229,9 +234,6 @@ namespace CppSharp.Generators.CLI @@ -229,9 +234,6 @@ namespace CppSharp.Generators.CLI
private void GenerateClassDestructor(Class @class)
{
if (!Options.GenerateFinalizers)
return;
PushBlock(CLIBlockKind.Destructor);
WriteLine("{0}::~{1}()", QualifiedIdentifier(@class), @class.Name);
@ -247,9 +249,6 @@ namespace CppSharp.Generators.CLI @@ -247,9 +249,6 @@ namespace CppSharp.Generators.CLI
private void GenerateClassFinalizer(Class @class)
{
if (!Options.GenerateFinalizers)
return;
PushBlock(CLIBlockKind.Finalizer);
WriteLine("{0}::!{1}()", QualifiedIdentifier(@class), @class.Name);
@ -327,37 +326,37 @@ namespace CppSharp.Generators.CLI @@ -327,37 +326,37 @@ namespace CppSharp.Generators.CLI
GeneratePropertyGetter(property.GetMethod, realOwner, property.Name,
property.Type);
if (property.HasSetter)
if (property.IsIndexer)
GeneratePropertySetter(property.SetMethod, realOwner, property.Name,
if (property.HasSetter)
if (property.IsIndexer)
GeneratePropertySetter(property.SetMethod, realOwner, property.Name,
property.Type, property.GetMethod.Parameters[0]);
else
GeneratePropertySetter(property.SetMethod, realOwner, property.Name,
else
GeneratePropertySetter(property.SetMethod, realOwner, property.Name,
property.Type);
}
PopBlock();
}
}
private void GeneratePropertySetter<T>(T decl, Class @class, string name, Type type, Parameter indexParameter = null)
where T : Declaration, ITypedDecl
{
if (decl == null)
return;
var args = new List<string>();
var isIndexer = indexParameter != null;
if (isIndexer)
args.Add(string.Format("{0} {1}", indexParameter.Type, indexParameter.Name));
var function = decl as Function;
var argName = function != null && !isIndexer ? function.Parameters[0].Name : "value";
return;
var args = new List<string>();
var isIndexer = indexParameter != null;
if (isIndexer)
args.Add(string.Format("{0} {1}", indexParameter.Type, indexParameter.Name));
var function = decl as Function;
var argName = function != null && !isIndexer ? function.Parameters[0].Name : "value";
args.Add(string.Format("{0} {1}", type, argName));
WriteLine("void {0}::{1}::set({2})", QualifiedIdentifier(@class),
name, string.Join(", ", args));
WriteStartBraceIndent();
WriteStartBraceIndent();
if (decl is Function && !isIndexer)
{
var func = decl as Function;
@ -418,11 +417,11 @@ namespace CppSharp.Generators.CLI @@ -418,11 +417,11 @@ namespace CppSharp.Generators.CLI
var isIndexer = method != null &&
method.OperatorKind == CXXOperatorKind.Subscript;
var args = new List<string>();
if (isIndexer)
{
var indexParameter = method.Parameters[0];
args.Add(string.Format("{0} {1}", indexParameter.Type, indexParameter.Name));
var args = new List<string>();
if (isIndexer)
{
var indexParameter = method.Parameters[0];
args.Add(string.Format("{0} {1}", indexParameter.Type, indexParameter.Name));
}
WriteLine("{0} {1}::{2}::get({3})", type, QualifiedIdentifier(@class),
@ -628,7 +627,7 @@ namespace CppSharp.Generators.CLI @@ -628,7 +627,7 @@ namespace CppSharp.Generators.CLI
{
foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
{
GenerateStructMarshaling(@base.Class, nativeVar);
GenerateStructMarshaling(@base.Class, nativeVar);
}
foreach (var property in @class.Properties.Where( p => !ASTUtils.CheckIgnoreProperty(p)))
@ -779,7 +778,7 @@ namespace CppSharp.Generators.CLI @@ -779,7 +778,7 @@ namespace CppSharp.Generators.CLI
{
foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
{
GenerateValueTypeConstructorCallProperties(@base.Class);
GenerateValueTypeConstructorCallProperties(@base.Class);
}
foreach (var property in @class.Properties)
@ -811,8 +810,8 @@ namespace CppSharp.Generators.CLI @@ -811,8 +810,8 @@ namespace CppSharp.Generators.CLI
GenerateDeclarationCommon(function);
var classSig = string.Format("{0}::{1}", QualifiedIdentifier(@namespace),
TranslationUnit.FileNameWithoutExtension);
var classSig = string.Format("{0}::{1}", QualifiedIdentifier(@namespace),
TranslationUnit.FileNameWithoutExtension);
Write("{0} {1}::{2}(", function.ReturnType, classSig,
function.Name);

6
tests/CLITemp/CLITemp.cs

@ -11,6 +11,12 @@ namespace CppSharp.Tests @@ -11,6 +11,12 @@ namespace CppSharp.Tests
{
}
public override void Setup(Driver driver)
{
driver.Options.GenerateFinalizers = true;
base.Setup(driver);
}
public override void Preprocess(Driver driver, ASTContext ctx)
{
}

9
tests/CLITemp/CLITemp.h

@ -15,3 +15,12 @@ struct DLL_API Types @@ -15,3 +15,12 @@ struct DLL_API Types
typedef int AttributedFuncType(int, int) ATTR;
AttributedFuncType AttributedSum;
};
// Tests code generator to not generate a destructor/finalizer pair
// if the destructor of the C++ class is not public.
class DLL_API TestProtectedDestructors
{
~TestProtectedDestructors();
};
TestProtectedDestructors::~TestProtectedDestructors() {}
Loading…
Cancel
Save