예제 #1
0
        void AddForwardReference(List <ManagedClass> forwardRefs, TypeRefDefinition type, HeaderDefinition header)
        {
            if (type.IsBasic)
            {
                return;
            }

            switch (type.Kind)
            {
            case TypeKind.Pointer:
            case TypeKind.LValueReference:
                AddForwardReference(forwardRefs, type.Referenced, header);
                return;
            }

            var target = type.Target;

            if (target == null)
            {
                return;
            }
            if (target.IsExcluded || target.MarshalAsStruct || target.Header == header)
            {
                return;
            }

            var targetManaged = DotNetParser.GetManaged(target);

            if (!forwardRefs.Contains(targetManaged))
            {
                forwardRefs.Add(targetManaged);
            }
        }
예제 #2
0
        // If the type is defined in a conditionally compiled header, return the condition string.
        private string GetTypeConditional(TypeRefDefinition type)
        {
            var target = type.Target;

            if (target == null && type.Referenced != null)
            {
                target = type.Referenced.Target;
            }

            if (target == null)
            {
                return(null);
            }

            string headerConditional;
            string targetHeaderName = DotNetParser.GetManaged(target.Header).Name;

            if (headerConditionals.TryGetValue(targetHeaderName, out headerConditional))
            {
                return(headerConditional);
            }

            return(null);
        }
예제 #3
0
        void WriteMethodDefinition(ManagedMethod method, int numParameters, int overloadIndex, int level,
                                   ManagedParameter outValueParameter)
        {
            var nativeMethod = method.Native;

            if (nativeMethod.IsConstructor)
            {
                if (method.Parent.BaseClass == null)
                {
                    Write("_native = ");
                }
                Write($"{GetFullNameC(method.Parent.Native)}_new");
            }
            else
            {
                if (!nativeMethod.IsVoid)
                {
                    if (outValueParameter != null)
                    {
                        // Temporary variable
                        WriteLine(string.Format("{0} {1};",
                                                DotNetParser.GetManaged(outValueParameter.Native.Type.Referenced.Target).Name,
                                                outValueParameter.Name));
                        WriteTabs(level + 2);
                    }
                    else
                    {
                        Write($"return {BulletParser.GetTypeMarshalConstructorStartCS(nativeMethod)}");
                    }
                }

                Write($"{GetFullNameC(method.Parent.Native)}_{method.Native.Name}");
            }

            if (overloadIndex != 0)
            {
                Write((overloadIndex + 1).ToString());
            }

            Write('(');

            var parameters = method.Parameters.Take(numParameters)
                             .Select(p => GetParameterMarshal(p));

            if (outValueParameter != null)
            {
                parameters = parameters.Concat(new[] { $"out {outValueParameter.Name }" });
            }

            // The first parameter is the instance pointer (if not constructor or static method)
            if (!nativeMethod.IsConstructor && !nativeMethod.IsStatic)
            {
                parameters = new[] { "_native" }.Concat(parameters);
            }

            Write(ListToLines(parameters, WriteTo.CS, level + 2));

            if (nativeMethod.IsConstructor && method.Parent.BaseClass != null)
            {
                Write(")");
                if (method.Parent.BaseClass.Native.HasPreventDelete)
                {
                    Write(", false");
                }
                WriteLine(")");
                WriteLine(level + 1, "{");
            }
            else
            {
                if (!nativeMethod.IsConstructor && !nativeMethod.IsVoid)
                {
                    Write(BulletParser.GetTypeMarshalConstructorEndCS(nativeMethod));
                }
                WriteLine(");");
            }

            // Cache property values
            if (nativeMethod.IsConstructor)
            {
                var methodParent = method.Parent;
                while (methodParent != null)
                {
                    foreach (var cachedProperty in methodParent.CachedProperties.OrderBy(p => p.Key))
                    {
                        foreach (var param in method.Parameters)
                        {
                            if (param.Name.ToLower().Equals(cachedProperty.Key.ToLower()) &&
                                GetName(param.Native.Type).Equals(GetName(cachedProperty.Value.Property.Type)))
                            {
                                WriteLine(level + 2,
                                          $"{cachedProperty.Value.CacheFieldName} = {param.Name};");
                            }
                        }
                    }
                    methodParent = methodParent.BaseClass;
                }
            }

            // Return temporary variable
            if (outValueParameter != null)
            {
                WriteLine(level + 2, $"return {outValueParameter.Name};");
            }
        }
예제 #4
0
        public override void Output()
        {
            var headers = DotNetParser.Headers.Values;

            if (headers.Count != 0)
            {
                Directory.CreateDirectory(Project.CppCliProjectPathFull);
            }

            foreach (var header in headers)
            {
                string headerFilename = Path.Combine(Project.CppCliProjectPathFull, header.Name + ".h");
                OpenFile(headerFilename, WriteTo.Header);
                WriteLine("#pragma once");
                WriteLine();

                // Write includes
                if (header.Native.Includes.Count != 0)
                {
                    foreach (var include in header.Native.Includes)
                    {
                        string includeName = DotNetParser.GetManaged(include).Name;
                        WriteLine($"#include \"{includeName}.h\"");
                    }
                    WriteLine();
                }

                // Write namespace
                WriteLine($"namespace {Project.NamespaceName}");
                WriteLine("{");
                hasHeaderWhiteSpace = true;

                // Find forward references
                var forwardRefs = new List <ManagedClass>();
                foreach (var c in header.Classes)
                {
                    FindForwardReferences(forwardRefs, c);
                }

                // Remove redundant forward references (header file already included)
                forwardRefs.RemoveAll(fr => header.Native.Includes.Contains(fr.Header.Native));
                forwardRefs.Sort((r1, r2) => r1.Name.CompareTo(r2.Name));

                // Write forward references
                var forwardRefHeaders = new List <ManagedHeader>();
                foreach (ManagedClass c in forwardRefs)
                {
                    WriteLine(1, $"ref class {c.Name};");
                    if (!forwardRefHeaders.Contains(c.Header))
                    {
                        forwardRefHeaders.Add(c.Header);
                    }
                    hasHeaderWhiteSpace = false;
                }
                forwardRefHeaders.Add(header);
                forwardRefHeaders.Sort((r1, r2) => r1.Name.CompareTo(r2.Name));


                string sourceFilename = Path.Combine(Project.CppCliProjectPathFull, header.Name + ".cpp");
                OpenFile(sourceFilename, WriteTo.Source);
                WriteLine("#include \"StdAfx.h\"");
                WriteLine();

                string headerConditional;
                if (headerConditionals.TryGetValue(header.Name, out headerConditional))
                {
                    WriteLine($"#ifndef {headerConditional}");
                    WriteLine();
                }

                // Write statements to include forward referenced types
                if (forwardRefHeaders.Count != 0)
                {
                    foreach (var refHeader in forwardRefHeaders)
                    {
                        bool hasHeaderConditional = false;
                        if (headerConditionals.ContainsKey(refHeader.Name))
                        {
                            hasHeaderConditional = true;
                            if (headerConditionals.ContainsKey(header.Name) &&
                                headerConditionals[refHeader.Name] == headerConditionals[header.Name])
                            {
                                hasHeaderConditional = false;
                            }
                        }
                        if (hasHeaderConditional)
                        {
                            Write("#ifndef ");
                            WriteLine(headerConditionals[refHeader.Name]);
                        }
                        WriteLine($"#include \"{refHeader.Name}.h\"");
                        if (hasHeaderConditional)
                        {
                            WriteLine("#endif");
                        }
                    }
                    hasSourceWhiteSpace = false;
                }

                // Write classes
                var currentAccess = RefAccessSpecifier.Public;
                WriteClasses(header.Classes, ref currentAccess, 0);

                if (headerConditionals.ContainsKey(header.Name))
                {
                    WriteLine();
                    WriteLine("#endif");
                }

                WriteLine("};", WriteTo.Header);
                CloseFile(WriteTo.Header);
                CloseFile(WriteTo.Source);
            }

            Console.WriteLine("Write complete");
        }