private void GenerateValueTypeConstructorCall(Method method, Class @class) { var names = new List <string>(); foreach (var param in method.Parameters) { var ctx = new MarshalContext(Driver) { Parameter = param, ArgName = param.Name, }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); param.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } names.Add(marshal.Context.Return); } WriteLine("::{0} _native({1});", @class.QualifiedOriginalName, string.Join(", ", names)); GenerateValueTypeConstructorCallFields(@class); }
private void GenerateValueTypeConstructorCall(Method method, Class @class) { var names = new List <string>(); var paramIndex = 0; foreach (var param in method.Parameters) { var ctx = new MarshalContext(Context, CurrentIndentation) { Function = method, Parameter = param, ArgName = param.Name, ParameterIndex = paramIndex++ }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); param.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } names.Add(marshal.Context.Return); } WriteLine($@"{typePrinter.PrintTag(@class)}::{ @class.QualifiedOriginalName} _native({string.Join(", ", names)});"); GenerateValueTypeConstructorCallProperties(@class); }
private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex, Function function = null) { if (param.Type is BuiltinType) { return(new ParamMarshal { Name = param.Name, Param = param }); } var argName = "arg" + paramIndex.ToString(CultureInfo.InvariantCulture); if (param.Usage == ParameterUsage.Out) { var paramType = param.Type; if (paramType.IsReference()) { paramType = (paramType as PointerType).Pointee; } var typePrinter = new CppTypePrinter(Driver.TypeDatabase); var type = paramType.Visit(typePrinter); WriteLine("{0} {1};", type, argName); } else { var ctx = new MarshalContext(Driver) { Parameter = param, ParameterIndex = paramIndex, ArgName = argName, Function = function }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); param.Visit(marshal); if (string.IsNullOrEmpty(marshal.Context.Return)) { throw new Exception("Cannot marshal argument of function"); } if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName, marshal.Context.Return); argName = marshal.ArgumentPrefix + argName; } return(new ParamMarshal { Name = argName, Param = param }); }
private void MarshalValueClassProperty(Property property, string marshalVar) { var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, property.Name); var marshalCtx = new MarshalContext(Context.Context, Context.Indentation) { ArgName = fieldRef, ParameterIndex = Context.ParameterIndex++, MarshalVarPrefix = Context.MarshalVarPrefix, ReturnVarName = $"{marshalVar}.{property.Field.OriginalName}" }; var marshal = new CLIMarshalManagedToNativePrinter(marshalCtx); property.Visit(marshal); Context.ParameterIndex = marshalCtx.ParameterIndex; if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Context.Before.Write(marshal.Context.Before); } if (!string.IsNullOrWhiteSpace(marshal.Context.Return)) { Type type; Class @class; var isRef = property.Type.IsPointerTo(out type) && !(type.TryGetClass(out @class) && @class.IsValueType) && !type.IsPrimitiveType(); if (isRef) { Context.Before.WriteLine("if ({0} != nullptr)", fieldRef); Context.Before.Indent(); } Context.Before.WriteLine("{0}.{1} = {2};", marshalVar, property.Field.OriginalName, marshal.Context.Return); if (isRef) { Context.Before.Unindent(); } } }
private void MarshalValueClassField(Field field, string marshalVar) { var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, field.Name); var marshalCtx = new MarshalContext(Context.Driver) { ArgName = fieldRef, ParameterIndex = Context.ParameterIndex++ }; var marshal = new CLIMarshalManagedToNativePrinter(marshalCtx); field.Visit(marshal); Context.ParameterIndex = marshalCtx.ParameterIndex; if (!string.IsNullOrWhiteSpace(marshal.Context.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); if (field.Type.IsPointer()) { Context.SupportBefore.PopIndent(); } }
private ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex, Function function = null) { var paramMarshal = new ParamMarshal { Name = param.Name, Param = param }; if (param.Type is BuiltinType) { return(paramMarshal); } var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture); var isRef = param.IsOut || param.IsInOut; var paramType = param.Type; // Get actual type if the param type is a typedef but not a function type because function types have to be typedef. // We need to get the actual type this early before we visit any marshalling code to ensure we hit the marshalling // logic for the actual type and not the typedef. // This fixes issues where typedefs to primitive pointers are involved. FunctionType functionType; var paramTypeAsTypedef = paramType as TypedefType; if (paramTypeAsTypedef != null && !paramTypeAsTypedef.Declaration.Type.IsPointerTo(out functionType)) { paramType = param.Type.Desugar(); } // Since both pointers and references to types are wrapped as CLI // tracking references when using in/out, we normalize them here to be able // to use the same code for marshaling. if (paramType is PointerType && isRef) { if (!paramType.IsReference()) { paramMarshal.Prefix = "&"; } paramType = (paramType as PointerType).Pointee; } var effectiveParam = new Parameter(param) { QualifiedType = new QualifiedType(paramType) }; var ctx = new MarshalContext(Context, CurrentIndentation) { Parameter = effectiveParam, ParameterIndex = paramIndex, ArgName = argName, Function = function }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); effectiveParam.Visit(marshal); if (string.IsNullOrEmpty(marshal.Context.Return)) { throw new Exception($"Cannot marshal argument of function '{function.QualifiedOriginalName}'"); } if (isRef) { var typePrinter = new CppTypePrinter(Context) { ResolveTypeMaps = false }; var type = paramType.Visit(typePrinter); if (param.IsInOut) { if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return); } else { WriteLine("{0} {1};", type, argName); } } else { if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName, marshal.Context.Return); paramMarshal.Prefix = marshal.ArgumentPrefix; } paramMarshal.Name = argName; return(paramMarshal); }
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 ParamMarshal GenerateFunctionParamMarshal(Parameter param, int paramIndex, Function function = null) { var paramMarshal = new ParamMarshal { Name = param.Name, Param = param }; if (param.Type is BuiltinType) { return(paramMarshal); } var argName = Generator.GeneratedIdentifier("arg") + paramIndex.ToString(CultureInfo.InvariantCulture); var isRef = param.IsOut || param.IsInOut; // Since both pointers and references to types are wrapped as CLI // tracking references when using in/out, we normalize them here to be able // to use the same code for marshaling. var paramType = param.Type; if (paramType is PointerType && isRef) { if (!paramType.IsReference()) { paramMarshal.Prefix = "&"; } paramType = (paramType as PointerType).Pointee; } var effectiveParam = new Parameter(param) { QualifiedType = new QualifiedType(paramType) }; var ctx = new MarshalContext(Context) { Parameter = effectiveParam, ParameterIndex = paramIndex, ArgName = argName, Function = function }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); effectiveParam.Visit(marshal); if (string.IsNullOrEmpty(marshal.Context.Return)) { throw new Exception(string.Format("Cannot marshal argument of function '{0}'", function.QualifiedOriginalName)); } if (isRef) { var typePrinter = new CppTypePrinter(); var type = paramType.Visit(typePrinter); if (param.IsInOut) { if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("{0} {1} = {2};", type, argName, marshal.Context.Return); } else { WriteLine("{0} {1};", type, argName); } } else { if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } WriteLine("auto {0}{1} = {2};", marshal.VarPrefix, argName, marshal.Context.Return); paramMarshal.Prefix = marshal.ArgumentPrefix; } paramMarshal.Name = argName; return(paramMarshal); }
public override void CLIMarshalToNative(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 entryString = (ctx.Parameter != null) ? ctx.Parameter.Name : ctx.ArgName; var tmpVarName = "_tmp" + entryString; var cppTypePrinter = new CppTypePrinter(); var nativeType = type.Type.Visit(cppTypePrinter); ctx.SupportBefore.WriteLine("auto {0} = std::vector<{1}>();", tmpVarName, nativeType); ctx.SupportBefore.WriteLine("for each({0} _element in {1})", managedType, entryString); ctx.SupportBefore.WriteStartBraceIndent(); { var param = new Parameter { Name = "_element", QualifiedType = type }; var elementCtx = new MarshalContext(ctx.Context) { Parameter = param, ArgName = param.Name, }; var marshal = new CLIMarshalManagedToNativePrinter(elementCtx); type.Type.Visit(marshal); if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) ctx.SupportBefore.Write(marshal.Context.SupportBefore); if (isPointerToPrimitive) ctx.SupportBefore.WriteLine("auto _marshalElement = {0}.ToPointer();", marshal.Context.Return); else ctx.SupportBefore.WriteLine("auto _marshalElement = {0};", marshal.Context.Return); ctx.SupportBefore.WriteLine("{0}.push_back(_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 CLIMarshalToNative(MarshalContext ctx) { var templateType = Type as TemplateSpecializationType; var type = templateType.Arguments[0].Type; var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name : ctx.ArgName; var tmpVarName = "_tmp" + entryString; var cppTypePrinter = new CppTypePrinter(ctx.Driver.TypeDatabase); var nativeType = type.Type.Visit(cppTypePrinter); ctx.SupportBefore.WriteLine("auto {0} = Vector<{1}>();", tmpVarName, nativeType); ctx.SupportBefore.WriteLine("for each({0} _element in {1})", type.ToString(), entryString); ctx.SupportBefore.WriteStartBraceIndent(); { var param = new Parameter { Name = "_element", QualifiedType = type }; var elementCtx = new MarshalContext(ctx.Driver) { Parameter = param, ArgName = param.Name, }; var marshal = new CLIMarshalManagedToNativePrinter(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}.Push(_marshalElement);", tmpVarName); } ctx.SupportBefore.WriteCloseBraceIndent(); ctx.Return.Write(tmpVarName); }
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"; args.Add(string.Format("{0} {1}", type, argName)); WriteLine("void {0}::{1}::set({2})", QualifiedIdentifier(@class), name, string.Join(", ", args)); WriteStartBraceIndent(); if (decl is Function && !isIndexer) { var func = decl as Function; GenerateFunctionCall(func, @class); } else { if (@class.IsValueType && decl is Field) { WriteLine("{0} = value;", decl.Name); WriteCloseBraceIndent(); NewLine(); return; } var param = new Parameter { Name = "value", QualifiedType = new QualifiedType(type) }; var ctx = new MarshalContext(Driver) { Parameter = param, ArgName = param.Name, }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); param.Visit(marshal); 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); } if (isIndexer) { variable += string.Format("({0})", indexParameter.Name); } if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } if (isIndexer && decl.Type.IsPointer()) { WriteLine("*({0}) = {1};", variable, marshal.Context.Return); } else { WriteLine("{0} = {1};", variable, marshal.Context.Return); } } WriteCloseBraceIndent(); NewLine(); }
private void MarshalValueClassProperty(Property property, string marshalVar) { var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, property.Name); var marshalCtx = new MarshalContext(Context.Driver) { ArgName = fieldRef, ParameterIndex = Context.ParameterIndex++, MarshalVarPrefix = Context.MarshalVarPrefix }; var marshal = new CLIMarshalManagedToNativePrinter(marshalCtx); property.Visit(marshal); Context.ParameterIndex = marshalCtx.ParameterIndex; if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) Context.SupportBefore.Write(marshal.Context.SupportBefore); Type type; Class @class; var isRef = property.Type.IsPointerTo(out type) && !(type.TryGetClass(out @class) && @class.IsValueType) && !type.IsPrimitiveType(); if (isRef) { Context.SupportBefore.WriteLine("if ({0} != nullptr)", fieldRef); Context.SupportBefore.PushIndent(); } Context.SupportBefore.WriteLine("{0}.{1} = {2};", marshalVar, property.Field.OriginalName, marshal.Context.Return); if (isRef) Context.SupportBefore.PopIndent(); }
private void MarshalValueClassField(Field field, string marshalVar) { var fieldRef = string.Format("{0}.{1}", Context.Parameter.Name, field.Name); var marshalCtx = new MarshalContext(Context.Driver) { ArgName = fieldRef, ParameterIndex = Context.ParameterIndex++, MarshalVarPrefix = Context.MarshalVarPrefix }; var marshal = new CLIMarshalManagedToNativePrinter(marshalCtx); field.Visit(marshal); Context.ParameterIndex = marshalCtx.ParameterIndex; if (!string.IsNullOrWhiteSpace(marshal.Context.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); if(field.Type.IsPointer()) Context.SupportBefore.PopIndent(); }
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($"{indexParameter.Type} {indexParameter.Name}"); } var function = decl as Function; var argName = function != null && !isIndexer ? function.Parameters[0].Name : "value"; args.Add($"{type} {argName}"); WriteLine("void {0}::{1}::set({2})", QualifiedIdentifier(@class), name, string.Join(", ", args)); WriteOpenBraceAndIndent(); if (decl is Function && !isIndexer) { var func = decl as Function; var @void = new BuiltinType(PrimitiveType.Void); GenerateFunctionCall(func, @class, @void); } else { if (@class.IsValueType && decl is Field) { WriteLine("{0} = value;", decl.Name); UnindentAndWriteCloseBrace(); NewLine(); return; } var param = new Parameter { Name = "value", QualifiedType = new QualifiedType(type) }; string variable; if (decl is Variable) { variable = $"::{@class.QualifiedOriginalName}::{decl.OriginalName}"; } else { variable = $"(({typePrinter.PrintTag(@class)}::{@class.QualifiedOriginalName}*)NativePtr)->{decl.OriginalName}"; } var ctx = new MarshalContext(Context, CurrentIndentation) { Parameter = param, ArgName = param.Name, ReturnVarName = variable }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); param.Visit(marshal); if (isIndexer) { var ctx2 = new MarshalContext(Context, CurrentIndentation) { Parameter = indexParameter, ArgName = indexParameter.Name }; var marshal2 = new CLIMarshalManagedToNativePrinter(ctx2); indexParameter.Visit(marshal2); variable += string.Format("({0})", marshal2.Context.Return); } if (!string.IsNullOrWhiteSpace(marshal.Context.Before)) { Write(marshal.Context.Before); } if (marshal.Context.Return.StringBuilder.Length > 0) { if (isIndexer && decl.Type.IsPointer()) { WriteLine("*({0}) = {1};", variable, marshal.Context.Return); } else { WriteLine("{0} = {1};", variable, marshal.Context.Return); } } } UnindentAndWriteCloseBrace(); NewLine(); }
private void GeneratePropertySetter <T>(T decl, Class @class, string name, Type type) where T : Declaration, ITypedDecl { if (decl == null) { return; } WriteLine("void {0}::{1}::set({2} value)", QualifiedIdentifier(@class), name, type); WriteStartBraceIndent(); if (decl is Function) { var func = decl as Function; if (func.Parameters[0].Name != "value") { WriteLine("auto {0} = value;", func.Parameters[0].Name); } GenerateFunctionCall(func, @class); } else { if (@class.IsValueType && decl is Field) { WriteLine("{0} = value;", decl.Name); WriteCloseBraceIndent(); NewLine(); return; } var param = new Parameter { Name = "value", QualifiedType = decl.QualifiedType }; var ctx = new MarshalContext(Driver) { Parameter = param, ArgName = param.Name, }; var marshal = new CLIMarshalManagedToNativePrinter(ctx); param.Visit(marshal); 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); } if (!string.IsNullOrWhiteSpace(marshal.Context.SupportBefore)) { Write(marshal.Context.SupportBefore); } WriteLine("{0} = {1};", variable, marshal.Context.Return); } WriteCloseBraceIndent(); NewLine(); }
public override void CLIMarshalToNative(MarshalContext ctx) { var templateType = Type as TemplateSpecializationType; var type1 = templateType.Arguments[0].Type; var type2 = templateType.Arguments[1].Type; var entryString = (ctx.Parameter != null) ? ctx.Parameter.Name : ctx.ArgName; var tmpVarName = "_tmp" + entryString; var cppTypePrinter = new CppTypePrinter(ctx.Driver.TypeDatabase); var nativeType1 = type1.Type.Visit(cppTypePrinter); var nativeType2 = type2.Type.Visit(cppTypePrinter); ctx.SupportBefore.WriteLine("auto {0} = HashMap<{1}, {2}>();", tmpVarName, nativeType1, nativeType2); ctx.SupportBefore.WriteLine("auto _keys = {0}->Keys->GetEnumerator();", entryString); ctx.SupportBefore.WriteLine("while (_keys.MoveNext())"); ctx.SupportBefore.WriteStartBraceIndent(); { ctx.SupportBefore.WriteLine("{0} _key = _keys.Current;", type1.ToString()); ctx.SupportBefore.WriteLine("{0} _val = {1}[_key];", type2.ToString(), entryString); var param1 = new Parameter { Name = "_key", QualifiedType = type1 }; var elementCtx1 = new MarshalContext(ctx.Driver) { Parameter = param1, ArgName = param1.Name, }; var marshal1 = new CLIMarshalManagedToNativePrinter(elementCtx1); type1.Type.Visit(marshal1); if (!string.IsNullOrWhiteSpace(marshal1.Context.SupportBefore)) ctx.SupportBefore.Write(marshal1.Context.SupportBefore); ctx.SupportBefore.WriteLine("auto _marshalKey = {0};", marshal1.Context.Return); var param2 = new Parameter { Name = "_val", QualifiedType = type2 }; var elementCtx2 = new MarshalContext(ctx.Driver) { Parameter = param2, ArgName = param2.Name, }; var marshal2 = new CLIMarshalManagedToNativePrinter(elementCtx2); type2.Type.Visit(marshal2); if (!string.IsNullOrWhiteSpace(marshal2.Context.SupportBefore)) ctx.SupportBefore.Write(marshal2.Context.SupportBefore); ctx.SupportBefore.WriteLine("auto _marshalValue = {0};", marshal2.Context.Return); ctx.SupportBefore.WriteLine("{0}[_marshalKey] = _marshalValue;", tmpVarName); } ctx.SupportBefore.WriteCloseBraceIndent(); ctx.Return.Write(tmpVarName); }