Browse Source

Merge pull request #5 from esdrubal/master

Refactored marshal printers, TextGenerator fixes
pull/1/head
João Matos 12 years ago
parent
commit
37b09e2953
  1. 270
      src/Generator/Generators/CLI/CLIMarshal.cs
  2. 63
      src/Generator/Generators/CLI/CLISourcesTemplate.cs
  3. 12
      src/Generator/Types/TypeMap.cs
  4. 18
      src/Generator/Utils/TextGenerator.cs
  5. 11
      src/Generator/Utils/Utils.cs

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

@ -4,70 +4,91 @@ using Cxxi.Types;
namespace Cxxi.Generators.CLI namespace Cxxi.Generators.CLI
{ {
public interface IMarshalPrinter : ITypeVisitor<bool>, IDeclVisitor<bool> public abstract class MarshalPrinter : ITypeVisitor<bool>, IDeclVisitor<bool>
{ {
public MarshalContext Context { get; private set; }
protected MarshalPrinter(MarshalContext ctx)
{
Context = ctx;
}
public abstract bool VisitTagType(TagType tag, TypeQualifiers quals);
public abstract bool VisitArrayType(ArrayType array, TypeQualifiers quals);
public abstract bool VisitFunctionType(FunctionType function, TypeQualifiers quals);
public abstract bool VisitPointerType(PointerType pointer, TypeQualifiers quals);
public abstract bool VisitMemberPointerType(MemberPointerType member, TypeQualifiers quals);
public abstract bool VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals);
public abstract bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals);
public abstract bool VisitTemplateSpecializationType(TemplateSpecializationType template, TypeQualifiers quals);
public abstract bool VisitPrimitiveType(PrimitiveType type, TypeQualifiers quals);
public abstract bool VisitDeclaration(Declaration decl, TypeQualifiers quals);
public abstract bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals);
public abstract bool VisitDeclaration(Declaration decl);
public abstract bool VisitClassDecl(Class @class);
public abstract bool VisitFieldDecl(Field field);
public abstract bool VisitFunctionDecl(Function function);
public abstract bool VisitMethodDecl(Method method);
public abstract bool VisitParameterDecl(Parameter parameter);
public abstract bool VisitTypedefDecl(TypedefDecl typedef);
public abstract bool VisitEnumDecl(Enumeration @enum);
public abstract bool VisitVariableDecl(Variable variable);
public abstract bool VisitClassTemplateDecl(ClassTemplate template);
public abstract bool VisitFunctionTemplateDecl(FunctionTemplate template);
public abstract bool VisitMacroDefinition(MacroDefinition macro);
public abstract bool VisitNamespace(Namespace @namespace);
public abstract bool VisitEvent(Event @event);
} }
public class CLIMarshalNativeToManagedPrinter : IMarshalPrinter public class CLIMarshalNativeToManagedPrinter : MarshalPrinter
{ {
public TextGenerator Return;
Driver Driver { get; set; } public CLIMarshalNativeToManagedPrinter(MarshalContext marshalContext)
ITypeMapDatabase TypeMapDatabase { get; set; } : base(marshalContext)
MarshalContext Context { get; set; }
public CLIMarshalNativeToManagedPrinter(Driver driver, MarshalContext marshalContext)
{ {
Driver = driver;
TypeMapDatabase = driver.TypeDatabase;
Context = marshalContext;
Return = new TextGenerator();
Context.Return = Return;
Context.MarshalToManaged = this; Context.MarshalToManaged = this;
} }
public bool VisitTagType(TagType tag, TypeQualifiers quals) public override bool VisitTagType(TagType tag, TypeQualifiers quals)
{ {
var decl = tag.Declaration; var decl = tag.Declaration;
return decl.Visit(this); return decl.Visit(this);
} }
public bool VisitArrayType(ArrayType array, TypeQualifiers quals) public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
{ {
switch (array.SizeType) switch (array.SizeType)
{ {
case ArrayType.ArraySize.Constant: case ArrayType.ArraySize.Constant:
Return.Write("nullptr"); Context.Return.Write("nullptr");
break; break;
case ArrayType.ArraySize.Variable: case ArrayType.ArraySize.Variable:
Return.Write("nullptr"); Context.Return.Write("nullptr");
break; break;
} }
return true; return true;
} }
public bool VisitFunctionType(FunctionType function, TypeQualifiers quals) public override bool VisitFunctionType(FunctionType function, TypeQualifiers quals)
{ {
var returnType = function.ReturnType; var returnType = function.ReturnType;
return returnType.Visit(this, quals); return returnType.Visit(this, quals);
} }
public bool VisitPointerType(PointerType pointer, TypeQualifiers quals) public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
{ {
var pointee = pointer.Pointee; var pointee = pointer.Pointee;
if (pointee.IsPrimitiveType(PrimitiveType.Void, walkTypedefs: true)) if (pointee.IsPrimitiveType(PrimitiveType.Void, walkTypedefs: true))
{ {
Return.Write("IntPtr({0})", Context.ReturnVarName); Context.Return.Write("IntPtr({0})", Context.ReturnVarName);
return true; return true;
} }
if (pointee.IsPrimitiveType(PrimitiveType.Char)) if (pointee.IsPrimitiveType(PrimitiveType.Char))
{ {
Return.Write("clix::marshalString<clix::E_UTF8>({0})", Context.Return.Write("clix::marshalString<clix::E_UTF8>({0})",
Context.ReturnVarName); Context.ReturnVarName);
return true; return true;
} }
@ -75,7 +96,7 @@ namespace Cxxi.Generators.CLI
PrimitiveType primitive; PrimitiveType primitive;
if (pointee.IsPrimitiveType(out primitive, walkTypedefs: true)) if (pointee.IsPrimitiveType(out primitive, walkTypedefs: true))
{ {
Return.Write("IntPtr({0})", Context.ReturnVarName); Context.Return.Write("IntPtr({0})", Context.ReturnVarName);
return true; return true;
} }
@ -85,13 +106,13 @@ namespace Cxxi.Generators.CLI
return true; return true;
} }
public bool VisitMemberPointerType(MemberPointerType member, public override bool VisitMemberPointerType(MemberPointerType member,
TypeQualifiers quals) TypeQualifiers quals)
{ {
return false; return false;
} }
public bool VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals) public override bool VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
{ {
return VisitPrimitiveType(builtin.Type); return VisitPrimitiveType(builtin.Type);
} }
@ -113,7 +134,7 @@ namespace Cxxi.Generators.CLI
case PrimitiveType.UInt64: case PrimitiveType.UInt64:
case PrimitiveType.Float: case PrimitiveType.Float:
case PrimitiveType.Double: case PrimitiveType.Double:
Return.Write(Context.ReturnVarName); Context.Return.Write(Context.ReturnVarName);
return true; return true;
case PrimitiveType.WideChar: case PrimitiveType.WideChar:
return false; return false;
@ -122,12 +143,12 @@ namespace Cxxi.Generators.CLI
return false; return false;
} }
public bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals) public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
{ {
var decl = typedef.Declaration; var decl = typedef.Declaration;
TypeMap typeMap = null; TypeMap typeMap = null;
if (TypeMapDatabase.FindTypeMap(decl, out typeMap)) if (Context.Driver.TypeDatabase.FindTypeMap(decl, out typeMap))
{ {
typeMap.Type = typedef; typeMap.Type = typedef;
typeMap.CLIMarshalToManaged(Context); typeMap.CLIMarshalToManaged(Context);
@ -137,10 +158,10 @@ namespace Cxxi.Generators.CLI
FunctionType function; FunctionType function;
if (decl.Type.IsPointerTo(out function)) if (decl.Type.IsPointerTo(out function))
{ {
Return.Write("safe_cast<{0}>(", typedef); Context.Return.Write("safe_cast<{0}>(", typedef);
Return.Write("System::Runtime::InteropServices::Marshal::"); Context.Return.Write("System::Runtime::InteropServices::Marshal::");
Return.Write("GetDelegateForFunctionPointer("); Context.Return.Write("GetDelegateForFunctionPointer(");
Return.Write("IntPtr({0}), {1}::typeid))",Context.ReturnVarName, Context.Return.Write("IntPtr({0}), {1}::typeid))",Context.ReturnVarName,
typedef.ToString().TrimEnd('^')); typedef.ToString().TrimEnd('^'));
return true; return true;
} }
@ -148,11 +169,11 @@ namespace Cxxi.Generators.CLI
return decl.Type.Visit(this); return decl.Type.Visit(this);
} }
public bool VisitTemplateSpecializationType(TemplateSpecializationType template, public override bool VisitTemplateSpecializationType(TemplateSpecializationType template,
TypeQualifiers quals) TypeQualifiers quals)
{ {
TypeMap typeMap; TypeMap typeMap;
if (TypeMapDatabase.FindTypeMap(template, out typeMap)) if (Context.Driver.TypeDatabase.FindTypeMap(template, out typeMap))
{ {
typeMap.Type = template; typeMap.Type = template;
typeMap.CLIMarshalToManaged(Context); typeMap.CLIMarshalToManaged(Context);
@ -162,27 +183,27 @@ namespace Cxxi.Generators.CLI
return template.Template.Visit(this); return template.Template.Visit(this);
} }
public bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals) public override bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitPrimitiveType(PrimitiveType type, TypeQualifiers quals) public override bool VisitPrimitiveType(PrimitiveType type, TypeQualifiers quals)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitDeclaration(Declaration decl, TypeQualifiers quals) public override bool VisitDeclaration(Declaration decl, TypeQualifiers quals)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitDeclaration(Declaration decl) public override bool VisitDeclaration(Declaration decl)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
var instance = string.Empty; var instance = string.Empty;
@ -197,8 +218,8 @@ namespace Cxxi.Generators.CLI
public string QualifiedIdentifier(Declaration decl) public string QualifiedIdentifier(Declaration decl)
{ {
if (Driver.Options.GenerateLibraryNamespace) if (Context.Driver.Options.GenerateLibraryNamespace)
return string.Format("{0}::{1}", Driver.Options.OutputNamespace, return string.Format("{0}::{1}", Context.Driver.Options.OutputNamespace,
decl.QualifiedName); decl.QualifiedName);
return string.Format("{0}", decl.QualifiedName); return string.Format("{0}", decl.QualifiedName);
} }
@ -206,77 +227,77 @@ namespace Cxxi.Generators.CLI
public void WriteClassInstance(Class @class, string instance) public void WriteClassInstance(Class @class, string instance)
{ {
if (@class.IsRefType) if (@class.IsRefType)
Return.Write("gcnew "); Context.Return.Write("gcnew ");
Return.Write("{0}(", QualifiedIdentifier(@class)); Context.Return.Write("{0}(", QualifiedIdentifier(@class));
Return.Write("(::{0}*)", @class.QualifiedOriginalName); Context.Return.Write("(::{0}*)", @class.QualifiedOriginalName);
Return.Write("{0})", instance); Context.Return.Write("{0})", instance);
} }
public bool VisitFieldDecl(Field field) public override bool VisitFieldDecl(Field field)
{ {
return field.Type.Visit(this); return field.Type.Visit(this);
} }
public bool VisitFunctionDecl(Function function) public override bool VisitFunctionDecl(Function function)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitMethodDecl(Method method) public override bool VisitMethodDecl(Method method)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitParameterDecl(Parameter parameter) public override bool VisitParameterDecl(Parameter parameter)
{ {
return parameter.Type.Visit(this, parameter.QualifiedType.Qualifiers); return parameter.Type.Visit(this, parameter.QualifiedType.Qualifiers);
} }
public bool VisitTypedefDecl(TypedefDecl typedef) public override bool VisitTypedefDecl(TypedefDecl typedef)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitEnumDecl(Enumeration @enum) public override bool VisitEnumDecl(Enumeration @enum)
{ {
Return.Write("({0}){1}", ToCLITypeName(@enum), Context.Return.Write("({0}){1}", ToCLITypeName(@enum),
Context.ReturnVarName); Context.ReturnVarName);
return true; return true;
} }
public bool VisitVariableDecl(Variable variable) public override bool VisitVariableDecl(Variable variable)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private string ToCLITypeName(Declaration decl) private string ToCLITypeName(Declaration decl)
{ {
var typePrinter = new CLITypePrinter(Driver); var typePrinter = new CLITypePrinter(Context.Driver);
return typePrinter.VisitDeclaration(decl); return typePrinter.VisitDeclaration(decl);
} }
public bool VisitClassTemplateDecl(ClassTemplate template) public override bool VisitClassTemplateDecl(ClassTemplate template)
{ {
return template.TemplatedClass.Visit(this); return template.TemplatedClass.Visit(this);
} }
public bool VisitFunctionTemplateDecl(FunctionTemplate template) public override bool VisitFunctionTemplateDecl(FunctionTemplate template)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitMacroDefinition(MacroDefinition macro) public override bool VisitMacroDefinition(MacroDefinition macro)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitNamespace(Namespace @namespace) public override bool VisitNamespace(Namespace @namespace)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitEvent(Event @event) public override bool VisitEvent(Event @event)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -287,46 +308,32 @@ namespace Cxxi.Generators.CLI
} }
} }
public class CLIMarshalManagedToNativePrinter : ITypeVisitor<bool>, public class CLIMarshalManagedToNativePrinter : MarshalPrinter
IDeclVisitor<bool>
{ {
public TextGenerator SupportBefore; public readonly TextGenerator VarPrefix;
public TextGenerator SupportAfter; public readonly TextGenerator ArgumentPrefix;
public TextGenerator Return;
public TextGenerator VarPrefix;
public TextGenerator ArgumentPrefix;
ITypeMapDatabase TypeMapDatabase { get; set; }
MarshalContext Context { get; set; }
public CLIMarshalManagedToNativePrinter(ITypeMapDatabase typeMap, public CLIMarshalManagedToNativePrinter(MarshalContext ctx)
MarshalContext ctx) : base(ctx)
{ {
TypeMapDatabase = typeMap;
Context = ctx;
SupportBefore = new TextGenerator();
SupportAfter = new TextGenerator();
Return = new TextGenerator();
VarPrefix = new TextGenerator(); VarPrefix = new TextGenerator();
ArgumentPrefix = new TextGenerator(); ArgumentPrefix = new TextGenerator();
Context.Return = Return;
Context.MarshalToNative = this; Context.MarshalToNative = this;
} }
public bool VisitTagType(TagType tag, TypeQualifiers quals) public override bool VisitTagType(TagType tag, TypeQualifiers quals)
{ {
var decl = tag.Declaration; var decl = tag.Declaration;
return decl.Visit(this); return decl.Visit(this);
} }
public bool VisitArrayType(ArrayType array, TypeQualifiers quals) public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
{ {
return false; return false;
} }
public bool VisitFunctionType(FunctionType function, TypeQualifiers quals) public override bool VisitFunctionType(FunctionType function, TypeQualifiers quals)
{ {
var returnType = function.ReturnType; var returnType = function.ReturnType;
return returnType.Visit(this, quals); return returnType.Visit(this, quals);
@ -346,12 +353,12 @@ namespace Cxxi.Generators.CLI
sb.Append("System::Runtime::InteropServices::Marshal::"); sb.Append("System::Runtime::InteropServices::Marshal::");
sb.Append("GetFunctionPointerForDelegate("); sb.Append("GetFunctionPointerForDelegate(");
sb.AppendFormat("{0}).ToPointer())", Context.Parameter.Name); sb.AppendFormat("{0}).ToPointer())", Context.Parameter.Name);
Return.Write(sb.ToString()); Context.Return.Write(sb.ToString());
return true; return true;
} }
public bool VisitPointerType(PointerType pointer, TypeQualifiers quals) public override bool VisitPointerType(PointerType pointer, TypeQualifiers quals)
{ {
var pointee = pointer.Pointee; var pointee = pointer.Pointee;
@ -364,18 +371,18 @@ namespace Cxxi.Generators.CLI
if (isVoidPtr || isUInt8Ptr) if (isVoidPtr || isUInt8Ptr)
{ {
if (isUInt8Ptr) if (isUInt8Ptr)
Return.Write("({0})", "uint8*"); Context.Return.Write("({0})", "uint8*");
Return.Write("{0}.ToPointer()", Context.Parameter.Name); Context.Return.Write("{0}.ToPointer()", Context.Parameter.Name);
return true; return true;
} }
if (pointee.IsPrimitiveType(PrimitiveType.Char)) if (pointee.IsPrimitiveType(PrimitiveType.Char))
{ {
SupportBefore.Write( Context.SupportBefore.WriteLine(
"auto _{0} = clix::marshalString<clix::E_UTF8>({1});", "auto _{0} = clix::marshalString<clix::E_UTF8>({1});",
Context.ArgName, Context.Parameter.Name); Context.ArgName, Context.Parameter.Name);
Return.Write("_{0}.c_str()", Context.ArgName); Context.Return.Write("_{0}.c_str()", Context.ArgName);
return true; return true;
} }
@ -389,13 +396,13 @@ namespace Cxxi.Generators.CLI
return pointee.Visit(this, quals); return pointee.Visit(this, quals);
} }
public bool VisitMemberPointerType(MemberPointerType member, public override bool VisitMemberPointerType(MemberPointerType member,
TypeQualifiers quals) TypeQualifiers quals)
{ {
return false; return false;
} }
public bool VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals) public override bool VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
{ {
return VisitPrimitiveType(builtin.Type); return VisitPrimitiveType(builtin.Type);
} }
@ -417,7 +424,7 @@ namespace Cxxi.Generators.CLI
case PrimitiveType.UInt64: case PrimitiveType.UInt64:
case PrimitiveType.Float: case PrimitiveType.Float:
case PrimitiveType.Double: case PrimitiveType.Double:
Return.Write(Context.Parameter.Name); Context.Return.Write(Context.Parameter.Name);
return true; return true;
case PrimitiveType.WideChar: case PrimitiveType.WideChar:
return false; return false;
@ -426,12 +433,12 @@ namespace Cxxi.Generators.CLI
return false; return false;
} }
public bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals) public override bool VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
{ {
var decl = typedef.Declaration; var decl = typedef.Declaration;
TypeMap typeMap = null; TypeMap typeMap = null;
if (TypeMapDatabase.FindTypeMap(decl, out typeMap)) if (Context.Driver.TypeDatabase.FindTypeMap(decl, out typeMap))
{ {
typeMap.CLIMarshalToNative(Context); typeMap.CLIMarshalToNative(Context);
return typeMap.IsValueType; return typeMap.IsValueType;
@ -447,17 +454,17 @@ namespace Cxxi.Generators.CLI
PrimitiveType primitive; PrimitiveType primitive;
if (decl.Type.IsPrimitiveType(out primitive, walkTypedefs: true)) if (decl.Type.IsPrimitiveType(out primitive, walkTypedefs: true))
{ {
Return.Write("({0})", typedef.Declaration.Name); Context.Return.Write("({0})", typedef.Declaration.Name);
} }
return decl.Type.Visit(this); return decl.Type.Visit(this);
} }
public bool VisitTemplateSpecializationType(TemplateSpecializationType template, public override bool VisitTemplateSpecializationType(TemplateSpecializationType template,
TypeQualifiers quals) TypeQualifiers quals)
{ {
TypeMap typeMap = null; TypeMap typeMap = null;
if (TypeMapDatabase.FindTypeMap(template, out typeMap)) if (Context.Driver.TypeDatabase.FindTypeMap(template, out typeMap))
{ {
typeMap.Type = template; typeMap.Type = template;
typeMap.CLIMarshalToNative(Context); typeMap.CLIMarshalToNative(Context);
@ -467,27 +474,27 @@ namespace Cxxi.Generators.CLI
return template.Template.Visit(this); return template.Template.Visit(this);
} }
public bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals) public override bool VisitTemplateParameterType(TemplateParameterType param, TypeQualifiers quals)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitPrimitiveType(PrimitiveType type, TypeQualifiers quals) public override bool VisitPrimitiveType(PrimitiveType type, TypeQualifiers quals)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitDeclaration(Declaration decl, TypeQualifiers quals) public override bool VisitDeclaration(Declaration decl, TypeQualifiers quals)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitDeclaration(Declaration decl) public override bool VisitDeclaration(Declaration decl)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
if (@class.IsValueType) if (@class.IsValueType)
{ {
@ -504,7 +511,7 @@ namespace Cxxi.Generators.CLI
private void MarshalRefClass(Class @class) private void MarshalRefClass(Class @class)
{ {
TypeMap typeMap = null; TypeMap typeMap = null;
if (TypeMapDatabase.FindTypeMap(@class, out typeMap)) if (Context.Driver.TypeDatabase.FindTypeMap(@class, out typeMap))
{ {
typeMap.CLIMarshalToNative(Context); typeMap.CLIMarshalToNative(Context);
return; return;
@ -512,7 +519,7 @@ namespace Cxxi.Generators.CLI
if (!Context.Parameter.Type.IsPointer()) if (!Context.Parameter.Type.IsPointer())
{ {
Return.Write("*"); Context.Return.Write("*");
if (Context.Parameter.Type.IsReference()) if (Context.Parameter.Type.IsReference())
VarPrefix.Write("&"); VarPrefix.Write("&");
@ -523,13 +530,13 @@ namespace Cxxi.Generators.CLI
&& method.Conversion == MethodConversionKind.FunctionToInstanceMethod && method.Conversion == MethodConversionKind.FunctionToInstanceMethod
&& Context.ParameterIndex == 0) && Context.ParameterIndex == 0)
{ {
Return.Write("(::{0}*)", @class.QualifiedOriginalName); Context.Return.Write("(::{0}*)", @class.QualifiedOriginalName);
Return.Write("NativePtr"); Context.Return.Write("NativePtr");
return; return;
} }
Return.Write("(::{0}*)", @class.QualifiedOriginalName); Context.Return.Write("(::{0}*)", @class.QualifiedOriginalName);
Return.Write("{0}->NativePtr", Context.Parameter.Name); Context.Return.Write("{0}->NativePtr", Context.Parameter.Name);
} }
private void MarshalValueClass(Class @class) private void MarshalValueClass(Class @class)
@ -537,13 +544,12 @@ namespace Cxxi.Generators.CLI
var marshalVar = "_marshal" + Context.ParameterIndex++; var marshalVar = "_marshal" + Context.ParameterIndex++;
SupportBefore.WriteLine("auto {0} = ::{1}();", marshalVar, Context.SupportBefore.WriteLine("auto {0} = ::{1}();", marshalVar,
@class.QualifiedOriginalName); @class.QualifiedOriginalName);
SupportBefore.PushIndent();
MarshalValueClassFields(@class, marshalVar); MarshalValueClassFields(@class, marshalVar);
Return.Write(marshalVar); Context.Return.Write(marshalVar);
if (Context.Parameter.Type.IsPointer()) if (Context.Parameter.Type.IsPointer())
ArgumentPrefix.Write("&"); ArgumentPrefix.Write("&");
@ -577,20 +583,28 @@ namespace Cxxi.Generators.CLI
ParameterIndex = Context.ParameterIndex++ ParameterIndex = Context.ParameterIndex++
}; };
var marshal = new CLIMarshalManagedToNativePrinter(TypeMapDatabase, var marshal = new CLIMarshalManagedToNativePrinter(marshalCtx);
marshalCtx);
field.Visit(marshal); field.Visit(marshal);
Context.ParameterIndex = marshalCtx.ParameterIndex; Context.ParameterIndex = marshalCtx.ParameterIndex;
if (!string.IsNullOrWhiteSpace(marshal.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
SupportBefore.WriteLine(marshal.SupportBefore); Context.SupportBefore.Write(marshal.Context.SupportBefore);
if(field.Type.IsPointer())
{
Context.SupportBefore.WriteLine("if ({0} != nullptr)", fieldRef);
Context.SupportBefore.PushIndent();
}
Context.SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, field.OriginalName,
marshal.Context.Return);
SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, field.OriginalName, if(field.Type.IsPointer())
marshal.Return); Context.SupportBefore.PopIndent();
} }
public bool VisitFieldDecl(Field field) public override bool VisitFieldDecl(Field field)
{ {
Context.Parameter = new Parameter Context.Parameter = new Parameter
{ {
@ -601,59 +615,59 @@ namespace Cxxi.Generators.CLI
return field.Type.Visit(this); return field.Type.Visit(this);
} }
public bool VisitFunctionDecl(Function function) public override bool VisitFunctionDecl(Function function)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitMethodDecl(Method method) public override bool VisitMethodDecl(Method method)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitParameterDecl(Parameter parameter) public override bool VisitParameterDecl(Parameter parameter)
{ {
return parameter.Type.Visit(this); return parameter.Type.Visit(this);
} }
public bool VisitTypedefDecl(TypedefDecl typedef) public override bool VisitTypedefDecl(TypedefDecl typedef)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitEnumDecl(Enumeration @enum) public override bool VisitEnumDecl(Enumeration @enum)
{ {
Return.Write("(::{0}){1}", @enum.QualifiedOriginalName, Context.Return.Write("(::{0}){1}", @enum.QualifiedOriginalName,
Context.Parameter.Name); Context.Parameter.Name);
return true; return true;
} }
public bool VisitVariableDecl(Variable variable) public override bool VisitVariableDecl(Variable variable)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitClassTemplateDecl(ClassTemplate template) public override bool VisitClassTemplateDecl(ClassTemplate template)
{ {
return template.TemplatedClass.Visit(this); return template.TemplatedClass.Visit(this);
} }
public bool VisitFunctionTemplateDecl(FunctionTemplate template) public override bool VisitFunctionTemplateDecl(FunctionTemplate template)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitMacroDefinition(MacroDefinition macro) public override bool VisitMacroDefinition(MacroDefinition macro)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitNamespace(Namespace @namespace) public override bool VisitNamespace(Namespace @namespace)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public bool VisitEvent(Event @event) public override bool VisitEvent(Event @event)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

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

@ -186,20 +186,19 @@ namespace Cxxi.Generators.CLI
ArgName = param.Name, ArgName = param.Name,
}; };
var marshal = new CLIMarshalManagedToNativePrinter(Driver.TypeDatabase, var marshal = new CLIMarshalManagedToNativePrinter(ctx);
ctx);
param.Visit(marshal); param.Visit(marshal);
var variable = string.Format("((::{0}*)NativePtr)->{1}", var variable = string.Format("((::{0}*)NativePtr)->{1}",
@class.QualifiedOriginalName, field.OriginalName); @class.QualifiedOriginalName, field.OriginalName);
if (!string.IsNullOrWhiteSpace(marshal.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
WriteLine(marshal.SupportBefore); Write(marshal.Context.SupportBefore);
WriteLine("{0} = {1};", variable, marshal.Return); WriteLine("{0} = {1};", variable, marshal.Context.Return);
if (!string.IsNullOrWhiteSpace(marshal.SupportAfter)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportAfter))
WriteLine(marshal.SupportAfter); Write(marshal.Context.SupportAfter);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
NewLine(); NewLine();
@ -220,10 +219,10 @@ namespace Cxxi.Generators.CLI
ReturnType = field.Type ReturnType = field.Type
}; };
var marshal = new CLIMarshalNativeToManagedPrinter(Driver, ctx); var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
field.Visit(marshal); field.Visit(marshal);
WriteLine("return {0};", marshal.Return); WriteLine("return {0};", marshal.Context.Return);
WriteCloseBraceIndent(); WriteCloseBraceIndent();
NewLine(); NewLine();
@ -328,10 +327,10 @@ namespace Cxxi.Generators.CLI
ReturnType = param.Type ReturnType = param.Type
}; };
var marshal = new CLIMarshalNativeToManagedPrinter(Driver, ctx); var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
param.Visit(marshal); param.Visit(marshal);
returns.Add(marshal.Return); returns.Add(marshal.Context.Return);
} }
Write("{0}::raise(", @event.Name); Write("{0}::raise(", @event.Name);
@ -411,10 +410,16 @@ namespace Cxxi.Generators.CLI
ReturnType = field.Type ReturnType = field.Type
}; };
var marshal = new CLIMarshalNativeToManagedPrinter(Driver, ctx); var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
field.Visit(marshal); field.Visit(marshal);
WriteLine("{0} = {1};", field.Name, marshal.Return); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
Write(marshal.Context.SupportBefore);
WriteLine("{0} = {1};", field.Name, marshal.Context.Return);
if (!string.IsNullOrWhiteSpace(marshal.Context.SupportAfter))
Write(marshal.Context.SupportAfter);
} }
} }
@ -498,14 +503,13 @@ namespace Cxxi.Generators.CLI
ArgName = param.Name, ArgName = param.Name,
}; };
var marshal = new CLIMarshalManagedToNativePrinter(Driver.TypeDatabase, var marshal = new CLIMarshalManagedToNativePrinter(ctx);
ctx);
param.Visit(marshal); param.Visit(marshal);
if (!string.IsNullOrWhiteSpace(marshal.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
WriteLine(marshal.SupportBefore); Write(marshal.Context.SupportBefore);
names.Add(marshal.Return); names.Add(marshal.Context.Return);
} }
WriteLine("auto _native = ::{0}({1});", @class.QualifiedOriginalName, WriteLine("auto _native = ::{0}({1});", @class.QualifiedOriginalName,
@ -537,10 +541,10 @@ namespace Cxxi.Generators.CLI
ReturnType = field.Type ReturnType = field.Type
}; };
var marshal = new CLIMarshalNativeToManagedPrinter(Driver, ctx); var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
field.Visit(marshal); field.Visit(marshal);
WriteLine("this->{0} = {1};", field.Name, marshal.Return); WriteLine("this->{0} = {1};", field.Name, marshal.Context.Return);
} }
} }
@ -621,10 +625,10 @@ namespace Cxxi.Generators.CLI
ReturnType = retType ReturnType = retType
}; };
var marshal = new CLIMarshalNativeToManagedPrinter(Driver, ctx); var marshal = new CLIMarshalNativeToManagedPrinter(ctx);
function.ReturnType.Visit(marshal); function.ReturnType.Visit(marshal);
WriteLine("{0};", marshal.Return); WriteLine("{0};", marshal.Context.Return);
} }
} }
@ -677,21 +681,20 @@ namespace Cxxi.Generators.CLI
Function = function Function = function
}; };
var marshal = new CLIMarshalManagedToNativePrinter(Driver.TypeDatabase, var marshal = new CLIMarshalManagedToNativePrinter(ctx);
ctx);
param.Visit(marshal); param.Visit(marshal);
if (string.IsNullOrEmpty(marshal.Return)) if (string.IsNullOrEmpty(marshal.Context.Return))
throw new Exception("Cannot marshal argument of function"); throw new Exception("Cannot marshal argument of function");
if (!string.IsNullOrWhiteSpace(marshal.SupportBefore)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore))
WriteLine(marshal.SupportBefore); Write(marshal.Context.SupportBefore);
WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName, marshal.Return); WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName, marshal.Context.Return);
if (!string.IsNullOrWhiteSpace(marshal.SupportAfter)) if (!string.IsNullOrWhiteSpace(marshal.Context.SupportAfter))
WriteLine(marshal.SupportAfter); Write(marshal.Context.SupportAfter);
var argText = marshal.ArgumentPrefix + argName; var argText = marshal.ArgumentPrefix + argName;
return new ParamMarshal {Name = argText, Param = param}; return new ParamMarshal {Name = argText, Param = param};

12
src/Generator/Types/TypeMap.cs

@ -9,15 +9,21 @@ namespace Cxxi.Types
{ {
public MarshalContext(Driver driver) public MarshalContext(Driver driver)
{ {
Driver = driver;
SupportBefore = new TextGenerator();
SupportAfter = new TextGenerator();
Return = new TextGenerator();
} }
public Driver Driver { get; set; } public Driver Driver { get; private set; }
public CLIMarshalNativeToManagedPrinter MarshalToManaged; public CLIMarshalNativeToManagedPrinter MarshalToManaged;
public CLIMarshalManagedToNativePrinter MarshalToNative; public CLIMarshalManagedToNativePrinter MarshalToNative;
public TextGenerator Return; public TextGenerator SupportBefore { get; private set; }
public TextGenerator SupportAfter { get; private set; }
public TextGenerator Return { get; private set; }
public string ReturnVarName { get; set; } public string ReturnVarName { get; set; }
public Type ReturnType { get; set; } public Type ReturnType { get; set; }

18
src/Generator/Utils/TextGenerator.cs

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -24,16 +25,19 @@ namespace Cxxi
public void Write(string msg, params object[] args) public void Write(string msg, params object[] args)
{ {
if (isStartOfLine)
sb.Append(new string(' ', (int)CurrentIndent.Sum(u => u)));
if (args.Length > 0) if (args.Length > 0)
msg = string.Format(msg, args); msg = string.Format(msg, args);
if (msg.Length > 0) foreach(var line in msg.SplitAndKeep(Environment.NewLine))
isStartOfLine = false; {
if (isStartOfLine && !string.IsNullOrWhiteSpace(line))
sb.Append(new string(' ', (int) CurrentIndent.Sum(u => u)));
if (line.Length > 0)
isStartOfLine = line.EndsWith(Environment.NewLine);
sb.Append(msg); sb.Append(line);
}
} }
public void WriteLine(string msg, params object[] args) public void WriteLine(string msg, params object[] args)

11
src/Generator/Utils/Utils.cs

@ -164,6 +164,17 @@ namespace Cxxi
var str = Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled); var str = Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled);
return str.Trim().Split(); return str.Trim().Split();
} }
public static IEnumerable<string> SplitAndKeep(this string s, string seperator)
{
string[] obj = s.Split(new string[] { seperator }, StringSplitOptions.None);
for (int i = 0; i < obj.Length; i++)
{
string result = i == obj.Length - 1 ? obj[i] : obj[i] + seperator;
yield return result;
}
}
} }
public static class AssemblyHelpers public static class AssemblyHelpers

Loading…
Cancel
Save