Browse Source

Fixed a regression when marshalling arrays. Migrated the C++/CLI back-end to property usage.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/151/head
Dimitar Dobrev 12 years ago
parent
commit
b47fa98c94
  1. 40
      src/Generator/Generators/CLI/CLIHeadersTemplate.cs
  2. 53
      src/Generator/Generators/CLI/CLIMarshal.cs
  3. 78
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  4. 11
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  5. 5
      src/Generator/Passes/FieldToPropertyPass.cs

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

@ -259,8 +259,6 @@ namespace CppSharp.Generators.CLI
GenerateClassConstructors(@class, nativeType); GenerateClassConstructors(@class, nativeType);
GenerateClassFields(@class);
GenerateClassProperties(@class); GenerateClassProperties(@class);
GenerateClassEvents(@class); GenerateClassEvents(@class);
@ -271,6 +269,13 @@ namespace CppSharp.Generators.CLI
GenerateClassVariables(@class); GenerateClassVariables(@class);
if (@class.Fields.Any())
{
NewLine();
WriteLine("private:");
GenerateClassFields(@class);
}
WriteLine("};"); WriteLine("};");
} }
@ -390,17 +395,14 @@ namespace CppSharp.Generators.CLI
public void GenerateClassFields(Class @class) public void GenerateClassFields(Class @class)
{ {
if (!@class.IsValueType)
return;
// Handle the case of struct (value-type) inheritance by adding the base // Handle the case of struct (value-type) inheritance by adding the base
// fields to the managed value subtypes. // fields to the managed value subtypes.
foreach (var @base in @class.Bases) foreach (var @base in @class.Bases)
{ {
Class baseClass; if (!@base.IsClass)
if (!@base.Type.IsTagDecl(out baseClass))
continue; continue;
Class baseClass = @base.Class;
if (!baseClass.IsValueType || baseClass.Ignore) if (!baseClass.IsValueType || baseClass.Ignore)
{ {
Log.EmitMessage("Ignored base class of value type '{0}'", Log.EmitMessage("Ignored base class of value type '{0}'",
@ -414,7 +416,7 @@ namespace CppSharp.Generators.CLI
PushIndent(); PushIndent();
foreach (var field in @class.Fields) foreach (var field in @class.Fields)
{ {
if (ASTUtils.CheckIgnoreField(field)) continue; if (ASTUtils.CheckIgnoreField(field) && !@class.IsValueType) continue;
GenerateDeclarationCommon(field); GenerateDeclarationCommon(field);
if (@class.IsUnion) if (@class.IsUnion)
@ -558,12 +560,30 @@ namespace CppSharp.Generators.CLI
return false; return false;
} }
public void GenerateClassProperties(Class @class) public void GenerateClassProperties(Class @class, bool onlyFieldProperties = false)
{ {
// Handle the case of struct (value-type) inheritance by adding the base
// fields to the managed value subtypes.
foreach (var @base in @class.Bases)
{
if (!@base.IsClass)
continue;
Class baseClass = @base.Class;
if (!baseClass.IsValueType || baseClass.Ignore)
{
Log.EmitMessage("Ignored base class of value type '{0}'",
baseClass.Name);
continue;
}
GenerateClassProperties(baseClass, true);
}
PushIndent(); PushIndent();
foreach (var prop in @class.Properties) foreach (var prop in @class.Properties)
{ {
if (prop.Ignore) continue; if (prop.Ignore || (onlyFieldProperties && prop.Field == null)) continue;
GenerateDeclarationCommon(prop); GenerateDeclarationCommon(prop);
GenerateProperty(prop); GenerateProperty(prop);

53
src/Generator/Generators/CLI/CLIMarshal.cs

@ -196,7 +196,15 @@ namespace CppSharp.Generators.CLI
public override bool VisitDeclaration(Declaration decl) public override bool VisitDeclaration(Declaration decl)
{ {
throw new NotImplementedException(); TypeMap typeMap;
if (Context.Driver.TypeDatabase.FindTypeMap(decl, out typeMap))
{
typeMap.Declaration = decl;
typeMap.CLIMarshalToManaged(Context);
return false;
}
return true;
} }
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
@ -530,7 +538,15 @@ namespace CppSharp.Generators.CLI
public override bool VisitDeclaration(Declaration decl) public override bool VisitDeclaration(Declaration decl)
{ {
throw new NotImplementedException(); TypeMap typeMap;
if (Context.Driver.TypeDatabase.FindTypeMap(decl, out typeMap))
{
typeMap.Declaration = decl;
typeMap.CLIMarshalToNative(Context);
return false;
}
return true;
} }
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
@ -589,7 +605,7 @@ namespace CppSharp.Generators.CLI
Context.SupportBefore.WriteLine("auto {0} = ::{1}();", marshalVar, Context.SupportBefore.WriteLine("auto {0} = ::{1}();", marshalVar,
@class.QualifiedOriginalName); @class.QualifiedOriginalName);
MarshalValueClassFields(@class, marshalVar); MarshalValueClassProperties(@class, marshalVar);
Context.Return.Write(marshalVar); Context.Return.Write(marshalVar);
@ -601,7 +617,7 @@ namespace CppSharp.Generators.CLI
ArgumentPrefix.Write("&"); ArgumentPrefix.Write("&");
} }
public void MarshalValueClassFields(Class @class, string marshalVar) public void MarshalValueClassProperties(Class @class, string marshalVar)
{ {
foreach (var @base in @class.Bases) foreach (var @base in @class.Bases)
{ {
@ -609,22 +625,22 @@ namespace CppSharp.Generators.CLI
continue; continue;
var baseClass = @base.Class; var baseClass = @base.Class;
MarshalValueClassFields(baseClass, marshalVar); MarshalValueClassProperties(baseClass, marshalVar);
} }
foreach (var field in @class.Fields) foreach (var property in @class.Properties)
{ {
if(field.Ignore) if (property.Ignore || property.Field == null)
continue; continue;
MarshalValueClassField(field, marshalVar); MarshalValueClassProperty(property, marshalVar);
} }
} }
private void MarshalValueClassField(Field field, string marshalVar) private void MarshalValueClassProperty(Property property, string marshalVar)
{ {
var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name,
field.Name); property.Name);
var marshalCtx = new MarshalContext(Context.Driver) var marshalCtx = new MarshalContext(Context.Driver)
{ {
@ -634,7 +650,7 @@ namespace CppSharp.Generators.CLI
}; };
var marshal = new CLIMarshalManagedToNativePrinter(marshalCtx); var marshal = new CLIMarshalManagedToNativePrinter(marshalCtx);
field.Visit(marshal); property.Visit(marshal);
Context.ParameterIndex = marshalCtx.ParameterIndex; Context.ParameterIndex = marshalCtx.ParameterIndex;
@ -643,7 +659,7 @@ namespace CppSharp.Generators.CLI
Type type; Type type;
Class @class; Class @class;
var isRef = field.Type.IsPointerTo(out type) && var isRef = property.Type.IsPointerTo(out type) &&
!(type.IsTagDecl(out @class) && @class.IsValueType) && !(type.IsTagDecl(out @class) && @class.IsValueType) &&
!type.IsPrimitiveType(); !type.IsPrimitiveType();
@ -654,7 +670,7 @@ namespace CppSharp.Generators.CLI
} }
Context.SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, Context.SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar,
field.OriginalName, marshal.Context.Return); property.Field.OriginalName, marshal.Context.Return);
if (isRef) if (isRef)
Context.SupportBefore.PopIndent(); Context.SupportBefore.PopIndent();
@ -671,6 +687,17 @@ namespace CppSharp.Generators.CLI
return field.Type.Visit(this); return field.Type.Visit(this);
} }
public override bool VisitProperty(Property property)
{
Context.Parameter = new Parameter
{
Name = Context.ArgName,
QualifiedType = property.QualifiedType
};
return base.VisitProperty(property);
}
public override bool VisitFunctionDecl(Function function) public override bool VisitFunctionDecl(Function function)
{ {
throw new NotImplementedException(); throw new NotImplementedException();

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

@ -165,8 +165,7 @@ namespace CppSharp.Generators.CLI
} }
} }
foreach (var property in @class.Properties) GenerateClassProperties(@class, @class);
GenerateProperty(property);
foreach (var @event in @class.Events) foreach (var @event in @class.Events)
{ {
@ -192,6 +191,22 @@ namespace CppSharp.Generators.CLI
PopBlock(); PopBlock();
} }
private void GenerateClassProperties(Class @class, Class realOwner,
bool onlyFieldProperties = false)
{
if (@class.IsValueType)
{
foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore))
{
GenerateClassProperties(@base.Class, realOwner, true);
}
}
foreach (var property in @class.Properties.Where(
p => !p.Ignore && (!onlyFieldProperties || p.Field != null)))
GenerateProperty(property, realOwner);
}
private void GenerateFunctionTemplate(FunctionTemplate template) private void GenerateFunctionTemplate(FunctionTemplate template)
{ {
var printer = TypePrinter; var printer = TypePrinter;
@ -236,7 +251,7 @@ namespace CppSharp.Generators.CLI
printer.Context = oldCtx; printer.Context = oldCtx;
} }
private void GenerateProperty(Property property) private void GenerateProperty(Property property, Class realOwner)
{ {
if (property.Ignore) return; if (property.Ignore) return;
@ -246,21 +261,21 @@ namespace CppSharp.Generators.CLI
if (property.Field != null) if (property.Field != null)
{ {
if (property.HasGetter) if (property.HasGetter)
GeneratePropertyGetter(property.Field, @class, property.Name, GeneratePropertyGetter(property.Field, realOwner, property.Name,
property.Type); property.Type);
if (property.HasSetter) if (property.HasSetter)
GeneratePropertySetter(property.Field, @class, property.Name, GeneratePropertySetter(property.Field, realOwner, property.Name,
property.Type); property.Type);
} }
else else
{ {
if (property.HasGetter) if (property.HasGetter)
GeneratePropertyGetter(property.GetMethod, @class, property.Name, GeneratePropertyGetter(property.GetMethod, realOwner, property.Name,
property.Type); property.Type);
if (property.HasSetter) if (property.HasSetter)
GeneratePropertySetter(property.SetMethod, @class, property.Name, GeneratePropertySetter(property.SetMethod, realOwner, property.Name,
property.Type); property.Type);
} }
PopBlock(); PopBlock();
@ -285,6 +300,13 @@ namespace CppSharp.Generators.CLI
} }
else else
{ {
if (@class.IsValueType && decl is Field)
{
WriteLine("{0} = value;", decl.Name);
WriteCloseBraceIndent();
NewLine();
return;
}
var param = new Parameter var param = new Parameter
{ {
Name = "value", Name = "value",
@ -335,6 +357,13 @@ namespace CppSharp.Generators.CLI
} }
else else
{ {
if (@class.IsValueType && decl is Field)
{
WriteLine("return {0};", decl.Name);
WriteCloseBraceIndent();
NewLine();
return;
}
string variable; string variable;
if (decl is Variable) if (decl is Variable)
variable = string.Format("::{0}::{1}", variable = string.Format("::{0}::{1}",
@ -526,27 +555,28 @@ namespace CppSharp.Generators.CLI
GenerateStructMarshaling(baseClass, nativeVar); GenerateStructMarshaling(baseClass, nativeVar);
} }
foreach (var field in @class.Fields) foreach (var property in @class.Properties)
{ {
if (ASTUtils.CheckIgnoreField(field)) continue; if (property.Ignore || property.Field == null) continue;
var nativeField = string.Format("{0}{1}", var nativeField = string.Format("{0}{1}",
nativeVar, field.OriginalName); nativeVar, property.Field.OriginalName);
var ctx = new MarshalContext(Driver) var ctx = new MarshalContext(Driver)
{ {
ArgName = field.Name, ArgName = property.Name,
ReturnVarName = nativeField, ReturnVarName = nativeField,
ReturnType = field.QualifiedType ReturnType = property.QualifiedType
}; };
var marshal = new CLIMarshalNativeToManagedPrinter(ctx); var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
field.Visit(marshal); property.Visit(marshal);
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
WriteLine("{0} = {1};", field.Name, marshal.Context.Return); WriteLine("{0} = {1};",
Generator.GeneratedIdentifier(property.Field.OriginalName), marshal.Context.Return);
} }
} }
@ -665,10 +695,10 @@ namespace CppSharp.Generators.CLI
WriteLine("::{0} _native({1});", @class.QualifiedOriginalName, WriteLine("::{0} _native({1});", @class.QualifiedOriginalName,
string.Join(", ", names)); string.Join(", ", names));
GenerateValueTypeConstructorCallFields(@class); GenerateValueTypeConstructorCallProperties(@class);
} }
private void GenerateValueTypeConstructorCallFields(Class @class) private void GenerateValueTypeConstructorCallProperties(Class @class)
{ {
foreach (var @base in @class.Bases) foreach (var @base in @class.Bases)
{ {
@ -676,28 +706,28 @@ namespace CppSharp.Generators.CLI
continue; continue;
var baseClass = @base.Class; var baseClass = @base.Class;
GenerateValueTypeConstructorCallFields(baseClass); GenerateValueTypeConstructorCallProperties(baseClass);
} }
foreach (var field in @class.Fields) foreach (var property in @class.Properties)
{ {
if (ASTUtils.CheckIgnoreField(field)) continue; if (property.Ignore || property.Field == null) continue;
var varName = string.Format("_native.{0}", field.OriginalName); var varName = string.Format("_native.{0}", property.Field.OriginalName);
var ctx = new MarshalContext(Driver) var ctx = new MarshalContext(Driver)
{ {
ReturnVarName = varName, ReturnVarName = varName,
ReturnType = field.QualifiedType ReturnType = property.QualifiedType
}; };
var marshal = new CLIMarshalNativeToManagedPrinter(ctx); var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
field.Visit(marshal); property.Visit(marshal);
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);
WriteLine("this->{0} = {1};", field.Name, marshal.Context.Return); WriteLine("this->{0} = {1};", property.Name, marshal.Context.Return);
} }
} }
@ -749,7 +779,7 @@ namespace CppSharp.Generators.CLI
}; };
var marshal = new CLIMarshalManagedToNativePrinter(ctx); var marshal = new CLIMarshalManagedToNativePrinter(ctx);
marshal.MarshalValueClassFields(@class, valueMarshalName); marshal.MarshalValueClassProperties(@class, valueMarshalName);
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore); Write(marshal.Context.SupportBefore);

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

@ -1108,22 +1108,23 @@ namespace CppSharp.Generators.CSharp
} }
} }
private void GenerateClassProperties(Class @class) private void GenerateClassProperties(Class @class, bool onlyFieldProperties = false)
{ {
if (@class.IsValueType) if (@class.IsValueType)
{ {
foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore)) foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore))
{ {
GenerateProperties(@base.Class); GenerateClassProperties(@base.Class, true);
} }
} }
GenerateProperties(@class); GenerateProperties(@class, onlyFieldProperties);
} }
private void GenerateProperties(Class @class) private void GenerateProperties(Class @class, bool onlyFieldProperties = false)
{ {
foreach (var prop in @class.Properties.Where(p => !p.Ignore)) foreach (var prop in @class.Properties.Where(
p => !p.Ignore && (!onlyFieldProperties || p.Field != null)))
{ {
PushBlock(CSharpBlockKind.Property); PushBlock(CSharpBlockKind.Property);

5
src/Generator/Passes/FieldToPropertyPass.cs

@ -39,10 +39,7 @@ namespace CppSharp.Passes
Access = field.Access, Access = field.Access,
Field = field Field = field
}; };
if (@class.IsUnion) field.Name = Generator.GeneratedIdentifier(field.Name);
{
field.Name = Generator.GeneratedIdentifier(field.Name);
}
@class.Properties.Add(prop); @class.Properties.Add(prop);
@class.Properties.Add(prop); @class.Properties.Add(prop);

Loading…
Cancel
Save