private void GenerateValueTypeConstructorCallProperties(Class @class) { foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared)) { GenerateValueTypeConstructorCallProperties(@base.Class); } foreach (var property in @class.Properties) { if (!property.IsDeclared || property.Field == null) { continue; } var varName = $"_native.{property.Field.OriginalName}"; var ctx = new MarshalContext(Context, CurrentIndentation) { ReturnVarName = varName, ReturnType = property.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); property.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("this->{0} = {1};", property.Name, marshal.Context.Return); } }
private void GenerateEventRaiseWrapper(Event @event, Class @class) { var args = typePrinter.VisitParameters(@event.Parameters, hasNames: true); WriteLine("void {0}::_{1}Raise({2})", QualifiedIdentifier(@class), @event.Name, args); WriteOpenBraceAndIndent(); var returns = new List <string>(); foreach (var param in @event.Parameters) { var ctx = new MarshalContext(Context, CurrentIndentation) { ReturnVarName = param.Name, ReturnType = param.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); param.Visit(marshal); returns.Add(marshal.Context.Return); } Write("{0}::raise(", @event.Name); Write("{0}", string.Join(", ", returns)); WriteLine(");"); UnindentAndWriteCloseBrace(); }
private void GenerateStructMarshaling(Class @class, string nativeVar) { foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared)) { GenerateStructMarshaling(@base.Class, nativeVar); } foreach (var property in @class.Properties.Where(p => !ASTUtils.CheckIgnoreProperty(p))) { if (property.Field == null) { continue; } var nativeField = string.Format("{0}{1}", nativeVar, property.Field.OriginalName); var ctx = new MarshalContext(Driver) { ArgName = property.Name, ReturnVarName = nativeField, ReturnType = property.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); property.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("{0} = {1};", property.Field.Name, marshal.Context.Return); } }
private void GenerateValueTypeConstructorCallProperties(Class @class) { foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.ExplicityIgnored)) { GenerateValueTypeConstructorCallProperties(@base.Class); } foreach (var property in @class.Properties) { if (property.ExplicityIgnored || property.Field == null) { continue; } var varName = string.Format("_native.{0}", property.Field.OriginalName); var ctx = new MarshalContext(Driver) { ReturnVarName = varName, ReturnType = property.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); property.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("this->{0} = {1};", property.Name, marshal.Context.Return); } }
private void GeneratePropertyGetter <T>(T decl, Class @class, string name, Type type) where T : Declaration, ITypedDecl { if (decl == null) { return; } WriteLine("{0} {1}::{2}::get()", type, QualifiedIdentifier(@class), name); WriteStartBraceIndent(); if (decl is Function) { var func = decl as Function; GenerateFunctionCall(func, @class); } else { string variable; if (decl is Variable) { variable = string.Format("::{0}::{1}", @class.QualifiedOriginalName, decl.OriginalName); } else { variable = string.Format("((::{0}*)NativePtr)->{1}", @class.QualifiedOriginalName, decl.OriginalName); } var ctx = new MarshalContext(Driver) { Declaration = decl, ArgName = decl.Name, ReturnVarName = variable, ReturnType = decl.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); decl.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("return {0};", marshal.Context.Return); } WriteCloseBraceIndent(); NewLine(); }
private void GenerateStructMarshaling(Class @class, string nativeVar) { foreach (var @base in @class.Bases) { if ([email protected] || @base.Class.Ignore) { continue; } var baseClass = @base.Class; GenerateStructMarshaling(baseClass, nativeVar); } foreach (var field in @class.Fields) { if (ASTUtils.CheckIgnoreField(field)) { continue; } var nativeField = string.Format("{0}{1}", nativeVar, field.OriginalName); var ctx = new MarshalContext(Driver) { ArgName = field.Name, ReturnVarName = nativeField, ReturnType = field.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); field.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("{0} = {1};", field.Name, marshal.Context.Return); } }
private void GenerateStructMarshaling(Class @class, string nativeVar) { foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared)) { GenerateStructMarshaling(@base.Class, nativeVar); } int paramIndex = 0; foreach (var property in @class.Properties.Where( p => !ASTUtils.CheckIgnoreProperty(p) && !CLIHeaders.TypeIgnored(p.Type))) { if (property.Field == null) { continue; } var nativeField = string.Format("{0}{1}", nativeVar, property.Field.OriginalName); var ctx = new MarshalContext(Context, CurrentIndentation) { ArgName = property.Name, ReturnVarName = nativeField, ReturnType = property.QualifiedType, ParameterIndex = paramIndex++ }; ctx.PushMarshalKind(MarshalKind.NativeField); var marshal = new CLIMarshalNativeToManagedPrinter(ctx); property.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("{0} = {1};", property.Field.Name, marshal.Context.Return); } }
private void GeneratePropertyGetter <T>(T decl, Class @class, string name, Type type) where T : Declaration, ITypedDecl { if (decl == null) { return; } var method = decl as Method; 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)); } WriteLine("{0} {1}::{2}::get({3})", type, QualifiedIdentifier(@class), name, string.Join(", ", args)); WriteOpenBraceAndIndent(); if (decl is Function) { var func = decl as Function; if (isIndexer && func.Type.IsAddress()) { GenerateFunctionCall(func, @class, type); } else { GenerateFunctionCall(func, @class); } } else { if (@class.IsValueType && decl is Field) { WriteLine($"return {decl.Name};"); UnindentAndWriteCloseBrace(); NewLine(); return; } string variable; if (decl is Variable) { variable = $"::{@class.QualifiedOriginalName}::{decl.OriginalName}"; } else if (CLIGenerator.ShouldGenerateClassNativeField(@class)) { variable = $"NativePtr->{decl.OriginalName}"; } else { variable = $"(({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)NativePtr)->{decl.OriginalName}"; } var ctx = new MarshalContext(Context, CurrentIndentation) { ArgName = decl.Name, ReturnVarName = variable, ReturnType = decl.QualifiedType }; ctx.PushMarshalKind(MarshalKind.NativeField); var marshal = new CLIMarshalNativeToManagedPrinter(ctx); decl.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine($"return {marshal.Context.Return};"); } UnindentAndWriteCloseBrace(); NewLine(); }
public void GenerateFunctionCall(Function function, Class @class = null, Type publicRetType = null) { CheckArgumentRange(function); if (function.OperatorKind == CXXOperatorKind.EqualEqual || function.OperatorKind == CXXOperatorKind.ExclaimEqual) { WriteLine("bool {0}Null = ReferenceEquals({0}, nullptr);", function.Parameters[0].Name); WriteLine("bool {0}Null = ReferenceEquals({0}, nullptr);", function.Parameters[1].Name); WriteLine("if ({0}Null || {1}Null)", function.Parameters[0].Name, function.Parameters[1].Name); WriteLineIndent("return {0}{1}Null && {2}Null{3};", function.OperatorKind == CXXOperatorKind.EqualEqual ? string.Empty : "!(", function.Parameters[0].Name, function.Parameters[1].Name, function.OperatorKind == CXXOperatorKind.EqualEqual ? string.Empty : ")"); } var retType = function.ReturnType; if (publicRetType == null) { publicRetType = retType.Type; } var needsReturn = !publicRetType.IsPrimitiveType(PrimitiveType.Void); const string valueMarshalName = "_this0"; var isValueType = @class != null && @class.IsValueType; if (isValueType && !IsNativeFunctionOrStaticMethod(function)) { WriteLine($"auto {valueMarshalName} = {typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}();"); var param = new Parameter { Name = "(*this)", Namespace = function.Namespace }; var ctx = new MarshalContext(Context, CurrentIndentation) { Parameter = param }; ctx.VarPrefix.Write(valueMarshalName); var marshal = new CLIMarshalManagedToNativePrinter(ctx); marshal.MarshalValueClassProperties(@class, valueMarshalName); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } } var @params = GenerateFunctionParamsMarshal(function.Parameters, function); var returnIdentifier = Helpers.ReturnIdentifier; if (needsReturn) { if (retType.Type.IsReference()) { Write("auto &{0} = ", returnIdentifier); } else { Write("auto {0} = ", returnIdentifier); } } if (function.OperatorKind == CXXOperatorKind.Conversion || function.OperatorKind == CXXOperatorKind.ExplicitConversion) { var method = function as Method; var typeName = method.ConversionType.Visit(new CppTypePrinter(Context)); WriteLine("({0}) {1};", typeName, @params[0].Name); } else if (function.IsOperator && function.OperatorKind != CXXOperatorKind.Subscript) { var opName = function.Name.Replace("operator", "").Trim(); switch (Operators.ClassifyOperator(function)) { case CXXOperatorArity.Unary: WriteLine("{0} {1};", opName, @params[0].Name); break; case CXXOperatorArity.Binary: WriteLine("{0} {1} {2};", @params[0].Name, opName, @params[1].Name); break; } } else { if (IsNativeFunctionOrStaticMethod(function)) { Write($"::{function.QualifiedOriginalName}("); } else { if (isValueType) { Write($"{valueMarshalName}."); } else if (IsNativeMethod(function)) { Write($"(({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)NativePtr)->"); } Write("{0}(", function.OriginalName); } GenerateFunctionParams(@params); WriteLine(");"); } foreach (var paramInfo in @params) { var param = paramInfo.Param; if (param.Usage != ParameterUsage.Out && param.Usage != ParameterUsage.InOut) { continue; } if (param.Type.IsPointer() && !param.Type.GetFinalPointee().IsPrimitiveType()) { param.QualifiedType = new QualifiedType(param.Type.GetFinalPointee()); } var nativeVarName = paramInfo.Name; var ctx = new MarshalContext(Context, CurrentIndentation) { ArgName = nativeVarName, ReturnVarName = nativeVarName, ReturnType = param.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); param.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("{0} = {1};", param.Name, marshal.Context.Return); } if (isValueType && !IsNativeFunctionOrStaticMethod(function)) { GenerateStructMarshaling(@class, valueMarshalName + "."); } if (needsReturn) { var retTypeName = retType.Visit(CTypePrinter).ToString(); var isIntPtr = retTypeName.Contains("IntPtr"); if (retType.Type.IsPointer() && (isIntPtr || retTypeName.EndsWith("^", StringComparison.Ordinal))) { WriteLine("if ({0} == nullptr) return {1};", returnIdentifier, isIntPtr ? "::System::IntPtr()" : "nullptr"); } var ctx = new MarshalContext(Context, CurrentIndentation) { ArgName = returnIdentifier, ReturnVarName = returnIdentifier, ReturnType = retType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); retType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } // Special case for indexer - needs to dereference if the internal // function is a pointer type and the property is not. if (retType.Type.IsPointer() && retType.Type.GetPointee().Equals(publicRetType) && publicRetType.IsPrimitiveType()) { WriteLine("return *({0});", marshal.Context.Return); } else if (retType.Type.IsReference() && publicRetType.IsReference()) { WriteLine("return ({0})({1});", publicRetType, marshal.Context.Return); } else { WriteLine("return {0};", marshal.Context.Return); } } }
private void GeneratePropertyGetter <T>(T decl, Class @class, string name, Type type) where T : Declaration, ITypedDecl { if (decl == null) { return; } var method = decl as Method; 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)); } WriteLine("{0} {1}::{2}::get({3})", type, QualifiedIdentifier(@class), name, string.Join(", ", args)); WriteStartBraceIndent(); if (decl is Function) { var func = decl as Function; if (isIndexer && func.Type.IsAddress()) { GenerateFunctionCall(func, @class, type); } else { GenerateFunctionCall(func, @class); } } else { if (@class.IsValueType && decl is Field) { WriteLine("return {0};", decl.Name); WriteCloseBraceIndent(); NewLine(); return; } string variable; if (decl is Variable) { variable = string.Format("::{0}::{1}", @class.QualifiedOriginalName, decl.OriginalName); } else { variable = string.Format("((::{0}*)NativePtr)->{1}", @class.QualifiedOriginalName, decl.OriginalName); } var ctx = new MarshalContext(Context) { Declaration = decl, ArgName = decl.Name, ReturnVarName = variable, ReturnType = decl.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); decl.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("return {0};", marshal.Context.Return); } WriteCloseBraceIndent(); NewLine(); }
public override void CLIMarshalToManaged(MarshalContext ctx) { var templateType = Type as TemplateSpecializationType; var type = templateType.Arguments[0].Type; var isPointerToPrimitive = type.Type.IsPointerToPrimitiveType(); var managedType = isPointerToPrimitive ? new CILType(typeof(System.IntPtr)) : type.Type; var tmpVarName = "_tmp" + ctx.ArgName; ctx.SupportBefore.WriteLine( "auto {0} = gcnew System::Collections::Generic::List<{1}>();", tmpVarName, managedType); ctx.SupportBefore.WriteLine("for(auto _element : {0})", ctx.ReturnVarName); ctx.SupportBefore.WriteStartBraceIndent(); { var elementCtx = new MarshalContext(ctx.Context) { ReturnVarName = "_element", ReturnType = type }; var marshal = new CLIMarshalNativeToManagedPrinter(elementCtx); type.Type.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) ctx.SupportBefore.Write(marshal.Context.SupportBefore); ctx.SupportBefore.WriteLine("auto _marshalElement = {0};", marshal.Context.Return); if (isPointerToPrimitive) ctx.SupportBefore.WriteLine("{0}->Add({1}(_marshalElement));", tmpVarName, managedType); else ctx.SupportBefore.WriteLine("{0}->Add(_marshalElement);", tmpVarName); } ctx.SupportBefore.WriteCloseBraceIndent(); ctx.Return.Write(tmpVarName); }
public void GenerateFunctionCall(Function function, Class @class = null) { var retType = function.ReturnType; var needsReturn = !retType.Type.IsPrimitiveType(PrimitiveType.Void); const string valueMarshalName = "_this0"; var isValueType = @class != null && @class.IsValueType; if (isValueType && !IsNativeFunctionOrStaticMethod(function)) { WriteLine("auto {0} = ::{1}();", valueMarshalName, @class.QualifiedOriginalName); var param = new Parameter { Name = "(*this)" }; var ctx = new MarshalContext(Driver) { MarshalVarPrefix = valueMarshalName, Parameter = param }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); marshal.MarshalValueClassProperties(@class, valueMarshalName); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } } var @params = GenerateFunctionParamsMarshal(function.Parameters, function); if (needsReturn) { Write("auto {0}{1} = ", (function.ReturnType.Type.IsReference())? "&": string.Empty, Generator.GeneratedIdentifier("ret")); } if (function.OperatorKind == CXXOperatorKind.Conversion) { var method = function as Method; var typePrinter = new CppTypePrinter(Driver.TypeDatabase); var typeName = method.ConversionType.Visit(typePrinter); WriteLine("({0}) {1};", typeName, @params[0].Name); } else if (function.IsOperator) { var opName = function.Name.Replace("operator", "").Trim(); switch (Operators.ClassifyOperator(function)) { case CXXOperatorArity.Unary: WriteLine("{0} {1};", opName, @params[0].Name); break; case CXXOperatorArity.Binary: WriteLine("{0} {1} {2};", @params[0].Name, opName, @params[1].Name); break; } } else { if (IsNativeFunctionOrStaticMethod(function)) { Write("::{0}(", function.QualifiedOriginalName); } else { if (isValueType) { Write("{0}.", valueMarshalName); } else if (IsNativeMethod(function)) { Write("((::{0}*)NativePtr)->", @class.QualifiedOriginalName); } Write("{0}(", function.OriginalName); } GenerateFunctionParams(@params); WriteLine(");"); } foreach (var paramInfo in @params) { var param = paramInfo.Param; if (param.Usage != ParameterUsage.Out && param.Usage != ParameterUsage.InOut) { continue; } var nativeVarName = paramInfo.Name; var ctx = new MarshalContext(Driver) { ArgName = nativeVarName, ReturnVarName = nativeVarName, ReturnType = param.QualifiedType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); param.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("{0} = {1};", param.Name, marshal.Context.Return); } if (isValueType && !IsNativeFunctionOrStaticMethod(function)) { GenerateStructMarshaling(@class, valueMarshalName + "."); } if (needsReturn) { var retTypeName = retType.Visit(TypePrinter); var isIntPtr = retTypeName.Contains("IntPtr"); if (retType.Type.IsPointer() && (isIntPtr || retTypeName.EndsWith("^"))) { WriteLine("if ({0} == nullptr) return {1};", Generator.GeneratedIdentifier("ret"), isIntPtr ? "System::IntPtr()" : "nullptr"); } var ctx = new MarshalContext(Driver) { ArgName = Generator.GeneratedIdentifier("ret"), ReturnVarName = Generator.GeneratedIdentifier("ret"), ReturnType = retType }; var marshal = new CLIMarshalNativeToManagedPrinter(ctx); function.ReturnType.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("return {0};", marshal.Context.Return); } }
public override void CLIMarshalToManaged(MarshalContext ctx) { var templateType = Type as TemplateSpecializationType; var type = templateType.Arguments[0].Type; var tmpVarName = "_tmp" + ctx.ArgName; ctx.SupportBefore.WriteLine("auto {0} = gcnew System::Collections::Generic::HashSet<{1}>();", tmpVarName, type.ToString()); ctx.SupportBefore.WriteLine("for(auto _element : {0})", ctx.ReturnVarName); ctx.SupportBefore.WriteStartBraceIndent(); { var elementCtx = new MarshalContext(ctx.Driver) { ReturnVarName = "_element", ReturnType = type }; var marshal = new CLIMarshalNativeToManagedPrinter(elementCtx); type.Type.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) ctx.SupportBefore.Write(marshal.Context.SupportBefore); ctx.SupportBefore.WriteLine("auto _marshalElement = {0};", marshal.Context.Return); ctx.SupportBefore.WriteLine("{0}.Add(_marshalElement);", tmpVarName); } ctx.SupportBefore.WriteCloseBraceIndent(); ctx.Return.Write(tmpVarName); }
public override void CLIMarshalToManaged(MarshalContext ctx) { var templateType = Type as TemplateSpecializationType; var keyType = templateType.Arguments[0].Type; var valueType = templateType.Arguments[1].Type; var tmpVarName = "_tmp" + ctx.ArgName; ctx.SupportBefore.WriteLine("auto {0} = gcnew System::Collections::Generic::Dictionary<{1}, {2}>();", tmpVarName, keyType.ToString(), valueType.ToString()); ctx.SupportBefore.WriteLine("for(auto _it = {0}.Begin(); _it != {0}.End(); ++_it)", ctx.ReturnVarName); ctx.SupportBefore.WriteStartBraceIndent(); { ctx.SupportBefore.WriteLine("auto& _key = _it->first;"); ctx.SupportBefore.WriteLine("auto& _val = _it->second;"); var keyCtx = new MarshalContext(ctx.Driver) { ReturnVarName = "_key", ReturnType = keyType }; var valueCtx = new MarshalContext(ctx.Driver) { ReturnVarName = "_val", ReturnType = valueType }; var marshalKey = new CLIMarshalNativeToManagedPrinter(keyCtx); keyType.Type.Visit(marshalKey); if (!string.IsNullOrWhiteSpace(marshalKey.Context.SupportBefore)) ctx.SupportBefore.Write(marshalKey.Context.SupportBefore); ctx.SupportBefore.WriteLine("auto _marshalKey = {0};", marshalKey.Context.Return); var marshalValue = new CLIMarshalNativeToManagedPrinter(valueCtx); valueType.Type.Visit(marshalValue); if (!string.IsNullOrWhiteSpace(marshalValue.Context.SupportBefore)) ctx.SupportBefore.Write(marshalValue.Context.SupportBefore); ctx.SupportBefore.WriteLine("auto _marshalValue = {0};", marshalValue.Context.Return); ctx.SupportBefore.WriteLine("{0}->Add(_marshalKey, _marshalValue);", tmpVarName); } ctx.SupportBefore.WriteCloseBraceIndent(); ctx.Return.Write(tmpVarName); }