private Dictionary <string, string> GenerateVTable(Definitions.ClassDefinition classDefinition)
        {
            Dictionary <string, string> VTable;

            if (classDefinition.ClassType.BaseClassType == null)
            {
                VTable = new Dictionary <string, string>();
                for (int x = 0; x < classDefinition.Methods.Count; x++)
                {
                    string MethodName = classDefinition.Methods.ItemAt(x).Name;
                    VTable.Add(MethodName, classDefinition.Name);
                }
            }
            else
            {
                VTable = GenerateVTable(Analysis.Environment.Classes.Lookup(classDefinition.ClassType.BaseClassType.Name));
                for (int x = 0; x < classDefinition.Methods.Count; x++)
                {
                    string MethodName = classDefinition.Methods.ItemAt(x).Name;
                    if (VTable.ContainsKey(MethodName))
                    {
                        VTable[MethodName] = classDefinition.Name;
                    }
                    else
                    {
                        VTable.Add(MethodName, classDefinition.Name);
                    }
                }
            }
            return(VTable);
        }
        private int SizeOf(Definitions.ClassDefinition classDefinition)
        {
            int Size = classDefinition.Fields.Count * 4;

            if (classDefinition.ClassType.BaseClassType != null)
            {
                Size += SizeOf(Analysis.Environment.Classes.Lookup(classDefinition.ClassType.BaseClassType.Name));
            }
            return(Size);
        }
        //--------------------------------------------------------------------------------------------------

        void GenerateClassSource(StringWriter w, Definitions.ClassDefinition cd)
        {
            w.WriteLine();
            w.WriteLine("//---------------------------------------------------------------------");
            w.WriteLine($"//  Class  {cd.Name}");
            w.WriteLine("//---------------------------------------------------------------------");
            w.WriteLine();

            // write methods
            foreach (var fd in cd.Functions)
            {
                if (fd.IsDestructor || !fd.IsPublic)
                {
                    continue;
                }

                for (int i = fd.Parameters.Count; i >= (fd.Parameters.Count - fd.DefaultParameterCount); i--)
                {
                    if (cd.Functions.Any(ffd => (ffd != fd) && ffd.IsEqual(fd, i)))
                    {
                        break;
                    }

                    GenerateFunctionSource(w, fd, i);
                }
            }
            w.WriteLine();

            // Downcast method
            if (cd.IsTransient)
            {
                w.WriteLine($"{cd.Fqn}^ {cd.Fqn}::CreateDowncasted({cd.Native}* instance)");
                w.WriteLine("{");

                if (cd.DerivedClasses.Any())
                {
                    w.WriteLine("\tif( instance == nullptr )");
                    w.WriteLine("\t\treturn nullptr;");
                    w.WriteLine("");

                    foreach (var derivedClass in cd.DerivedClasses)
                    {
                        w.WriteLine($"\tif (instance->IsKind(STANDARD_TYPE({derivedClass.Native})))");
                        w.WriteLine($"\t\treturn {derivedClass.Fqn}::CreateDowncasted(({derivedClass.Native}*)instance);");
                    }
                    w.WriteLine("");
                }

                w.WriteLine($"\treturn gcnew {cd.Fqn}( instance );");
                w.WriteLine("}");
                w.WriteLine();
            }

            w.WriteLine();
        }
Exemple #4
0
        //--------------------------------------------------------------------------------------------------

        void _AddFunction(Definitions.ClassDefinition klass, CastXml.Method method, int funcType)
        {
            var fName   = funcType == 0 ? method.name : klass.Name;
            var logName = klass.Name + "::" + fName;

            if (Configuration.Ignore.Contains(klass.Name + "::" + fName) || Configuration.Ignore.Contains("*::" + fName))
            {
                Logger.WriteLine(true, "Function " + logName + " ignored by definition.");
                return;
            }

            if (fName.StartsWith("_CSFDB_"))
            {
                Logger.WriteLine(true, "Function " + logName + " ignored because it begins with _CSFDB_");
                return;
            }

            // Create function
            var f = new Definitions.FunctionDefintion()
            {
                Class         = klass,
                Name          = fName,
                Type          = (funcType == 0) ? _GetTypeDefinition(method.returns) : _VoidTypeDefinition,
                IsStatic      = method.IsStatic,
                IsPublic      = method.IsPublic,
                IsConstructor = funcType == 1,
                IsDestructor  = funcType == 2,
                IsOperator    = false,
                IsTemplate    = fName.Contains('<'),
                IsAbstract    = method.IsPureVirtual,
            };

            if (f.Type == null)
            {
                Logger.WriteLine(true, string.Format("\tFunction " + logName + " ignored because of an unknown return type (FunctionType?)."));
                return;
            }

            Logger.WriteLine(true, string.Format("\tRelevant function: [{0}] {1} type='{2}'", method.id, fName, f.Type.Name));

            // Get parameters
            int unnamedCount = 1;

            if (method.Argument != null)
            {
                foreach (var p in method.Argument)
                {
                    var fp = new Definitions.ParameterDefinition
                    {
                        Type = _GetTypeDefinition(p.type)
                    };

                    if (fp.Type == null)
                    {
                        Logger.WriteLine(true, string.Format("\tFunction " + logName + " ignored because of an unknown parameter type (FunctionType?)."));
                        return;
                    }

                    if (string.IsNullOrEmpty(p.name))
                    {
                        fp.Name = $"parameter{unnamedCount}";
                        unnamedCount++;
                    }
                    else
                    {
                        fp.Name = p.name;
                    }

                    if (Configuration.NameReplacements.ContainsKey(fp.Name))
                    {
                        fp.Name = Configuration.NameReplacements[fp.Name];
                    }

                    if (!string.IsNullOrEmpty(p.@default))
                    {
                        fp.Default = [email protected](TrimChars);

                        // Make sure any type is interpreted as native, not wrapped
                        if (fp.Default.StartsWith("opencascade::handle<"))
                        {
                            fp.Default = fp.Default.Insert(20, "::");
                        }
                        else if (fp.Default.EndsWith("()")) // Constructor
                        {
                            fp.Default = "::" + fp.Default;
                        }

                        fp.HasDefault = true;
                    }

                    Logger.WriteLine(true, $"\t\tRelevant parameter: {fp.Name} type='{fp.Type.Name}' default='{fp.Default}'");

                    f.Parameters.Add(fp);
                }

                if (f.Parameters.All(pd => pd.Type.IsVoid && !pd.Type.IsPointer))
                {
                    // Only one void parameter, thats equivalent to no parameter
                    Logger.WriteLine(true, "\t\tFunction " + logName + " cleared all parameters because it has only one of type void.");
                    f.Parameters.Clear();
                }
            }

            if (!klass.Functions.Any(other => f.IsEqual(other)))
            {
                klass.Functions.Add(f);
            }
        }
Exemple #5
0
        //--------------------------------------------------------------------------------------------------

        Definitions.ClassDefinition _AddClass(CastXml.Record record, string package, bool isStruct, string overrideName = null)
        {
            string className = string.IsNullOrEmpty(overrideName) ? record.name : overrideName;

            if (string.IsNullOrEmpty(className) || className.StartsWith("Handle_"))
            {
                return(null);
            }

            if (Configuration.Ignore.Contains(className))
            {
                Logger.WriteLine(true, "Class " + className + " ignored by definition.");
                return(null);
            }

            if (Configuration.KnownTypes.Any(def => def.NativeFqn == className))
            {
                Logger.WriteLine(true, "Class " + className + " already in known types list.");
                return(null);
            }

            if (Configuration.ClassOptInList.ContainsKey(package))
            {
                // OptIn-Package
                if (!Configuration.ClassOptInList[package].Contains(className))
                {
                    Logger.WriteLine(true, "Class " + className + " ignored beacause of opt-in package.");
                    return(null);
                }
            }

            var c = new Definitions.ClassDefinition()
            {
                Name       = className,
                Package    = package,
                IsStruct   = isStruct,
                IsAbstract = record.IsAbstract
            };

            Definitions.ClassItems.Add(c);

            // Search for base class
            var baseClassToCopyIds = new List <string>();

            if (record.Base != null)
            {
                foreach (var baseElement in record.Base)
                {
                    var baseTypeId       = baseElement.type;
                    var baseClassElement = _Db.Classes.FirstOrDefault(e => e.id == baseTypeId);
                    if (baseClassElement != null)
                    {
                        var baseClassName = baseClassElement.name;
                        // Take base class name only if it is not template.
                        if (baseClassName.Contains("<"))
                        {
                            baseClassToCopyIds.Add(baseTypeId);
                            continue;
                        }
                        c.BaseClassName = baseClassName;
                        break;
                    }
                }
            }

            var classId = record.id;

            Logger.WriteLine(true, $"Relevant class: [{classId}] {className} : {c.BaseClassName}");

            // Search for constructors in class
            var constructors = from item in _Db.Constructors
                               where item.context == classId
                               select item;

            foreach (var f in constructors)
            {
                _AddFunction(c, f, 1);
            }

            // Search for destructors in class
            var destructors = from item in _Db.Destructors
                              where item.context == classId
                              select item;

            foreach (var f in destructors)
            {
                _AddFunction(c, f, 2);
            }

            // Search for functions in class
            var functions = from item in _Db.Methods
                            where item.context == classId
                            select item;

            foreach (var f in functions)
            {
                _AddFunction(c, f, 0);
            }

            // Search for functions in base class to copy
            // e.g. if the base class was templated
            foreach (var id in baseClassToCopyIds)
            {
                var baseFuncs = from item in _Db.Methods
                                where item.context == id
                                select item;

                foreach (var f in baseFuncs)
                {
                    _AddFunction(c, f, 0);
                }
            }

            // Search for inner enums
            var enums = from item in _Db.Enumerations
                        where item.context == classId
                        select item;

            foreach (var e in enums)
            {
                _AddEnum(e, e.id, package, c);
            }

            _AddInclude(record.file);
            return(c);
        }
Exemple #6
0
        //--------------------------------------------------------------------------------------------------

        bool _AddEnum(CastXml.ItemsEnumeration enumeration, string enumId, string package, Definitions.ClassDefinition c = null)
        {
            var name = enumeration.name;

            if (string.IsNullOrEmpty(name))
            {
                return(true);
            }

            if (Configuration.KnownTypes.Any(def => def.NativeFqn == name))
            {
                Logger.WriteLine(true, "Enum " + name + " already in known types list.");
                return(true);
            }

            if (Configuration.ClassOptInList.ContainsKey(package))
            {
                // OptIn-Package
                if (!Configuration.ClassOptInList[package].Contains(name))
                {
                    Logger.WriteLine(true, "Enum " + name + " ignored beacause of opt-in package.");
                    return(true);
                }
            }

            Logger.WriteLine(true, $"Relevant enum: [{enumeration.id}] [{enumId}] {name}");

            var e = new Definitions.EnumDefinition()
            {
                Name       = name,
                Package    = package,
                OuterClass = c
            };

            if (c == null)
            {
                Definitions.EnumItems.Add(e);
            }
            else
            {
                if (e.Name.Contains("::"))
                {
                    e.Name = e.Name.Remove(0, e.Name.LastIndexOf(":", StringComparison.Ordinal));
                }
                c.InnerEnums.Add(e);
            }

            foreach (var enumValue in enumeration.EnumValue)
            {
                e.Enumerators.Add(enumValue.name, enumValue.init.ToString());
            }

            _AddInclude(enumeration.file);

            return(true);
        }
        //--------------------------------------------------------------------------------------------------

        void GenerateClassHeaderInstance(StringWriter w, Definitions.ClassDefinition cd)
        {
            if (cd.IsStatic)
            {
                return;
            }

            // write default constructor, if the native class doesn't have one
            if (!cd.HasDefaultConstructor)
            {
                // Only create a default constructor, if the class does not have any constructor
                // AND the class isn't abstract AND does not define the constructor inaccessible
                // AND any constructor was found bit ignored.
                if (!(cd.HasConstructor || cd.IsAbstract || cd.HasUnaccessibleConstructor || cd.HasAbstractFunctions || Configuration.Ignore.Contains(cd.Name + "::" + cd.Name)))
                {
                    // Create public default constructor
                    w.WriteLine("public:");
                    w.WriteLine("\t" + cd.Name + "()");
                    w.WriteLine($"\t\t: {cd.SuperClassFqn}(InitMode::Uninitialized)");
                    w.WriteLine("\t{");
                    w.WriteLine("\t\t_NativeInstance = new " + cd.Native + "();");
                    w.WriteLine("\t}");
                    w.WriteLine();
                }
            }

            if (cd.IsBase || Configuration.Unseal.Contains(cd.Name))
            {
                // Default constructor (uninitialized)
                w.WriteLine("protected:");
                w.WriteLine($"\t{cd.Name}(InitMode init)");
                w.WriteLine($"\t\t: {cd.SuperClassFqn}( init )");
                w.WriteLine("\t{}");
                w.WriteLine();
            }

            w.WriteLine("public:");

            // Constructor for instance pointer
            w.WriteLine("\t" + cd.Name + "(" + cd.Native + "* nativeInstance)");
            if (cd.BaseClass == null && !cd.IsTransient)
            {
                w.WriteLine($"\t\t: {cd.SuperClassFqn}( nativeInstance, true )");
            }
            else
            {
                w.WriteLine($"\t\t: {cd.SuperClassFqn}( nativeInstance )");
            }
            w.WriteLine("\t{}");
            w.WriteLine();

            // Constructor for instance reference
            w.WriteLine($"\t{cd.Name}({cd.Native}& nativeInstance)");
            if (cd.BaseClass == null && !cd.IsTransient)
            {
                w.WriteLine($"\t\t: {cd.SuperClassFqn}( &nativeInstance, false )");
            }
            else
            {
                w.WriteLine($"\t\t: {cd.SuperClassFqn}( nativeInstance )");
            }
            w.WriteLine("\t{}");
            w.WriteLine();

            // Create property for instance reference
            w.WriteLine($"\tproperty {cd.Native}* NativeInstance");
            w.WriteLine("\t{");
            w.WriteLine("\t\t" + cd.Native + "* get()");
            w.WriteLine("\t\t{");
            w.WriteLine($"\t\t\treturn static_cast<{cd.Native}*>(_NativeInstance);");
            w.WriteLine("\t\t}");
            w.WriteLine("\t}");
            w.WriteLine();

            // Create Downcast function
            if (cd.IsTransient)
            {
                w.WriteLine("\tstatic " + cd.Fqn + "^ CreateDowncasted(" + cd.Native + "* instance);");
                w.WriteLine();
            }
        }
        void GenerateClassHeader(StringWriter w, Definitions.ClassDefinition cd, bool inner = false)
        {
            if (!inner)
            {
                w.WriteLine("//---------------------------------------------------------------------");
                w.WriteLine("//  Class  " + cd.Name);
                w.WriteLine("//---------------------------------------------------------------------");
            }

            if (!inner)
            {
                w.Write("public ");
            }

            w.Write("ref class {0}", cd.Name);

            if (!(cd.IsBase || cd.IsAbstract || Configuration.Unseal.Contains(cd.Name)))
            {
                w.Write(" sealed");
            }

            // Has baseclass
            if (!cd.IsStatic)
            {
                w.Write($" : public {cd.SuperClassFqn}");
            }
            w.WriteLine();
            w.WriteLine("{");

            // Write macro
            w.WriteLine();
            w.WriteLine("#ifdef Include_" + (inner ? (cd.OuterClass.Name + "_") : "") + cd.Name + "_h");
            w.WriteLine("public:");
            w.WriteLine("\tInclude_" + (inner ? (cd.OuterClass.Name + "_") : "") + cd.Name + "_h");
            w.WriteLine("#endif");
            w.WriteLine();

            // Write instance handling
            GenerateClassHeaderInstance(w, cd);

            w.WriteLine("public:");

            // write inner enums
            foreach (var ed in cd.InnerEnums)
            {
                GenerateEnumHeader(w, ed, true);
            }

            // write inner classes
            foreach (var icd in cd.InnerClasses)
            {
                GenerateClassHeader(w, icd, true);
            }

            // write methods
            foreach (var fd in cd.Functions)
            {
                if (fd.IsDestructor || !fd.IsPublic)
                {
                    continue;
                }

                for (int i = fd.Parameters.Count; i >= (fd.Parameters.Count - fd.DefaultParameterCount); i--)
                {
                    if (cd.Functions.Any(ffd => (ffd != fd) && ffd.IsEqual(fd, i)))
                    {
                        break;
                    }

                    w.Write("\t");
                    GenerateFunctionDeclaration(w, fd, i);
                }
            }

            w.WriteLine("}}; // class {0}", cd.Name);
            w.WriteLine();
        }
        //--------------------------------------------------------------------------------------------------

        bool GenerateTypeDecl(StringWriter w, Definitions.TypeDefinition type, Definitions.ClassDefinition klass, bool isReturnType)
        {
            if (string.IsNullOrWhiteSpace(type.Name))
            {
                return(false);
            }

            if (type.IsKnownType)
            {
                // Known type
                if (type.KnownTypeDef.Type == Definitions.KnownTypes.Void)
                {
                    if (type.IsPointer)
                    {
                        w.Write("System::IntPtr");
                    }
                    else
                    {
                        w.Write("void");
                    }
                }
                else if (type.KnownTypeDef.Type == Definitions.KnownTypes.VoidPtr)
                {
                    w.Write("System::IntPtr");
                }
                else if (type.KnownTypeDef.IsValueType)
                {
                    w.Write(type.KnownTypeDef.Fqn);
                    if (!isReturnType && (type.IsPointer || type.IsReference) && !type.IsConst)
                    {
                        w.Write("%");
                    }
                }
                else
                {
                    w.Write(type.KnownTypeDef.Fqn + "^");
                }
            }
            else if (klass.HasInnerEnum(type.Name))
            {
                // Known enum
                w.Write(klass.InnerEnum(type.Name).Fqn);

                if (!isReturnType && type.IsReference)
                {
                    w.Write("%");
                }
            }
            else if (type.IsEnum(klass))
            {
                // Known enum
                w.Write(type.Fqn(klass));

                if (!isReturnType && type.IsReference)
                {
                    w.Write("%");
                }
            }
            else if (Definitions.ClassItems.Any(cd => cd.Name.Equals(type.Name)))
            {
                // Known class
                w.Write(Definitions.ClassItems.First(cd => cd.Name.Equals(type.Name)).Fqn + "^");
            }
            else if (klass.InnerClasses.Any(cd => cd.Name.Equals(type.Name)))
            {
                // Known inner class
                w.Write(klass.InnerClasses.First(cd => cd.Name.Equals(type.Name)).Fqn + "^");
            }
            else
            {
                // Unknown class, write as native
                if (!Configuration.UnknownTypes.Contains(type.Name))
                {
                    type.IsUnknown = true;
                    Configuration.UnknownTypes.Add(type.Name);
                    Logger.WriteLine(true, "Unknown type: " + type.Name);
                }
                return(false);
            }
            w.Write(" ");
            return(true);
        }