Example #1
0
        //--------------------------------------------------------------------------------------------------

        Definitions.TypeDefinition _GetTypeDefinition(string id)
        {
            Definitions.TypeDefinition cached;
            if (_TypeCache.TryGetValue(id, out cached))
            {
                return(cached);
            }

            var(element, type) = _Db.FindById(id);
            if (element == null)
            {
                return(null);
            }

            var td = new Definitions.TypeDefinition();

            Definitions.TypeDefinition std;
            switch (type)
            {
            case CastXml.Items1ChoiceType.FundamentalType:
                td.Name = ((CastXml.ItemsFundamentalType)element).name;
                break;

            case CastXml.Items1ChoiceType.Typedef:
                var typedef = (CastXml.ItemsTypedef)element;

                // Check for known types
                if (Configuration.KnownTypes.Any(kt => kt.NativeFqn == typedef.name))
                {
                    td.Name = typedef.name;
                }
                else
                {
                    std = _GetTypeDefinition(typedef.type);
                    if (std == null)
                    {
                        return(null);
                    }

                    if (std.Name.Contains("<") && !typedef.name.Contains("<"))
                    {
                        // Only supress typedef resolve if the typedef resolves an template
                        td.Name = typedef.name;
                    }
                    else
                    {
                        td.Name        = std.Name;
                        td.IsPointer   = std.IsPointer;
                        td.IsReference = std.IsReference;
                        td.IsHandle    = std.IsHandle;
                    }
                }
                break;

            case CastXml.Items1ChoiceType.ElaboratedType:
                return(_GetTypeDefinition(((CastXml.ItemsElaboratedType)element).type));

            case CastXml.Items1ChoiceType.Class:
            case CastXml.Items1ChoiceType.Struct:
                td.Name = ((CastXml.Record)element).name;
                break;

            case CastXml.Items1ChoiceType.Enumeration:
                td.Name = ((CastXml.ItemsEnumeration)element).name;
                break;

            case CastXml.Items1ChoiceType.PointerType:
                td.IsPointer = true;
                std          = _GetTypeDefinition(((CastXml.ItemsPointerType)element).type);
                if (std == null)
                {
                    return(null);
                }

                td.Name     = std.Name;
                td.IsHandle = std.IsHandle;
                td.IsConst  = std.IsConst;
                break;

            case CastXml.Items1ChoiceType.ReferenceType:
                td.IsReference = true;
                std            = _GetTypeDefinition(((CastXml.ItemsReferenceType)element).type);
                if (std == null)
                {
                    return(null);
                }

                td.Name     = std.Name;
                td.IsHandle = std.IsHandle;
                td.IsConst  = std.IsConst;
                break;

            case CastXml.Items1ChoiceType.CvQualifiedType:
                td.IsConst = true;
                std        = _GetTypeDefinition(((CastXml.ItemsCvQualifiedType)element).type);
                if (std == null)
                {
                    return(null);
                }

                td.Name        = std.Name;
                td.IsPointer   = std.IsPointer;
                td.IsReference = std.IsReference;
                td.IsHandle    = std.IsHandle;
                break;

            default:
                return(null);
            }

            // Is handled?
            if (td.Name.StartsWith("Handle_"))
            {
                td.Name     = td.Name.Replace("Handle_", "");
                td.IsHandle = true;
            }
            else if (td.Name.StartsWith("Handle("))
            {
                td.Name     = td.Name.Replace("Handle(", "").TrimEnd(')');
                td.IsHandle = true;
            }
            else if (td.Name.StartsWith("handle<"))
            {
                td.Name     = td.Name.Replace("handle<", "").TrimEnd('>').TrimStart(':');
                td.IsHandle = true;
            }

            _TypeCache.Add(id, td);

            return(td);
        }
        //--------------------------------------------------------------------------------------------------

        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);
        }