Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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();
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        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);
            }
        }
Ejemplo n.º 5
0
        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();
        }
Ejemplo n.º 6
0
        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);
            }
        }
Ejemplo n.º 7
0
        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);
            }
        }
Ejemplo n.º 8
0
        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();
        }
Ejemplo n.º 9
0
        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);
                }
            }
        }
Ejemplo n.º 10
0
        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();
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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);
            }
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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);
        }