Ejemplo n.º 1
0
        public bool TryResolveType(CppType cppType, out TypeInfo typeInfo, bool lookForward = true)
        {
            if (TryGetType(cppType.GetDisplayName(), out typeInfo))
            {
                return(true);
            }

            if (cppType is CppQualifiedType qualified)
            {
                return(TryResolveType(qualified.ElementType, out typeInfo, lookForward));
            }

            if (cppType is CppPointerType pointer)
            {
                if (TryResolveType(pointer.ElementType, out var innerTypeInfo, lookForward))
                {
                    typeInfo = new TypeInfo(cppType.GetDisplayName(), cppType, PointerType(innerTypeInfo.TypeSyntax));
                    _nativeMap.Add(typeInfo.Name, typeInfo);
                    return(true);
                }
            }

            if (lookForward)
            {
                _buildType(cppType).GetAwaiter().GetResult();
                return(TryResolveType(cppType, out typeInfo, false));
            }

            return(false);
        }
Ejemplo n.º 2
0
        internal string MapToManagedApiType(CppType nativeType)
        {
            string type = nativeType.GetDisplayName();

            if (IsKnownNativeType(nativeType))
            {
                return(RenameForApi(CleanType(type), false));
            }

            type = NativeToPinvokeType(nativeType);
            if (type.Contains("/*usize_t*/"))
            {
                return(nameof(UInt64));
            }
            if (type.Contains("/*size_t*/"))
            {
                return(nameof(Int64));
            }
            if (type.Contains("/*bool*/"))
            {
                return(nameof(Boolean));
            }

            return(type);
        }
Ejemplo n.º 3
0
        internal string NativeToPinvokeType(CppType nativeType)
        {
            string type  = nativeType.GetDisplayName();
            bool   isPtr = type.Trim().EndsWith("*");

            type = CleanType(type);

            if (_mappings.TryGetValue(type, out string managedType))
            {
                return(managedType + (isPtr ? "*" : ""));
            }

            if (isPtr && _mappings.TryGetValue(type + "*", out string managedTypePtr))
            {
                return(managedTypePtr);
            }

            if (_registeredTypes.Contains(type))
            {
                return("IntPtr");
            }

            Logger.LogWarning($"No C# equivalent for {type}");
            return(type + (isPtr ? "*" : ""));
        }
Ejemplo n.º 4
0
        protected TypeDesc GetTypeDesc(CppType type)
        {
            var t = new TypeDesc(type.GetDisplayName(), type);

            if (type is CppPointerType pointerType)
            {
                t.FunctionTypeRef = pointerType.ElementType as CppFunctionType;
            }
            return(t);
        }
Ejemplo n.º 5
0
        internal bool IsKnownNativeType(CppType nativeTtype)
        {
            var type = nativeTtype.GetDisplayName();

            if (_registeredTypes.Any(rt => rt == CleanType(type)))
            {
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// If a type defined under another type, then print the full name, e.g. Class1::Class2
        /// </summary>
        public static string GetFullTypeName(this CppType cppType)
        {
            string name = cppType.GetDisplayName();

            while (cppType.Parent is CppType parentType)
            {
                name    = parentType.GetDisplayName() + "::" + name;
                cppType = parentType;
            }
            return(name);
        }
Ejemplo n.º 7
0
        private static string GetCppType(CppType type)
        {
            var typeName = type.GetDisplayName();

            // remove the const
            typeName = typeName.Replace("const ", "");

            // replace the [] with a *
            int start;

            while ((start = typeName.IndexOf("[")) != -1)
            {
                var end = typeName.IndexOf("]");
                typeName = typeName.Substring(0, start) + "*" + typeName.Substring(end + 1);
            }

            return(typeName);
        }
 public static bool IsVoid(this CppType type) => type.GetDisplayName() == "void";
Ejemplo n.º 9
0
        public static string GetVType(CppType cppType)
        {
            // unwrap any const vars
            if (cppType.TypeKind == CppTypeKind.Qualified && cppType is CppQualifiedType cppQualType)
            {
                if (cppQualType.Qualifier == CppTypeQualifier.Const)
                {
                    return(GetVType(cppQualType.ElementType));
                }
            }

            if (cppType is CppClass cppClass && cppClass.ClassKind == CppClassKind.Union)
            {
                Console.WriteLine($"Found union we can't handle! [{cppType.Span}]");
                return("voidptr");
            }

            if (cppType.TypeKind == CppTypeKind.Enum || cppType.TypeKind == CppTypeKind.Primitive)
            {
                return(GetVType(cppType.GetDisplayName()));
            }

            if (cppType.TypeKind == CppTypeKind.Typedef && cppType is CppTypedef typeDefType)
            {
                if (typeDefType.IsPrimitiveType())
                {
                    return(typeDefType.ElementTypeAsPrimitive().GetVType());
                }
                else
                {
                    return(GetVType(typeDefType.ElementType));
                }
            }

            if (cppType.TypeKind == CppTypeKind.Pointer)
            {
                var cppPtrType = cppType as CppPointerType;

                // special V types
                if (cppPtrType.GetDisplayName() == "const char*" || cppPtrType.GetDisplayName() == "char*")
                {
                    return("byteptr");
                }

                if (cppPtrType.GetDisplayName() == "const void*" || cppPtrType.GetDisplayName() == "void*")
                {
                    return("voidptr");
                }

                // double pointer check
                if (cppPtrType.ElementType.TypeKind == CppTypeKind.Pointer)
                {
                    if (cppPtrType.ElementType.TypeKind == CppTypeKind.Pointer)
                    {
                        return($"&voidptr /* {cppPtrType.GetDisplayName()} */");
                    }
                    return($"&{GetVType(cppPtrType.ElementType)} /* {cppPtrType.GetDisplayName()} */");
                }

                // unwrap any const vars
                if (cppPtrType.ElementType.TypeKind == CppTypeKind.Qualified && cppPtrType.ElementType is CppQualifiedType qualType)
                {
                    if (qualType.Qualifier == CppTypeQualifier.Const)
                    {
                        if (qualType.ElementType is CppPrimitiveType qualPrimType && qualPrimType.Kind == CppPrimitiveKind.Void)
                        {
                            return($"voidptr");
                        }
                        return("&" + GetVType(qualType.ElementType));
                    }
                }

                // function pointers
                if (cppPtrType.ElementType.TypeKind == CppTypeKind.Function)
                {
                    var funcType = cppPtrType.ElementType as CppFunctionType;
                    if (funcType.Parameters.Count == 1 && funcType.Parameters[0].Type is CppPointerType cppPtrPtrType && cppPtrPtrType.ElementType.TypeKind == CppTypeKind.Function)
                    {
                        funcType = cppPtrPtrType.ElementType as CppFunctionType;
                    }

                    // HACK: for some reason, there can occassionally be function pointer args inside a function pointer argument
                    // for some reason. We just peel away the top function pointer and use that as the full type to fix the issue.
                    foreach (var p in funcType.Parameters)
                    {
                        if (p.Type is CppPointerType pType && pType.ElementType.TypeKind == CppTypeKind.Function)
                        {
                            funcType = pType.ElementType as CppFunctionType;
                        }
                    }

                    string GetReturnType()
                    {
                        // void return
                        if (funcType.ReturnType is CppPrimitiveType cppPrimType && cppPrimType.Kind == CppPrimitiveKind.Void)
                        {
                            return(null);
                        }
                        return(GetVType(funcType.ReturnType));
                    };

                    // easy case: no parameters
                    if (funcType.Parameters.Count == 0)
                    {
                        return($"fn() {GetReturnType()}".TrimEnd());
                    }

                    var sb = new StringBuilder();
                    sb.Append("fn(");
                    foreach (var p in funcType.Parameters)
                    {
                        var paramType = GetVType(p.Type);
                        if (paramType.Contains("fn"))
                        {
                            // TODO: typedef the function param
                            var typeDef = $"pub type Fn{V.ToPascalCase(p.Name)} {paramType}";
                        }
                        sb.Append(paramType);

                        if (funcType.Parameters.Last() != p)
                        {
                            sb.Append(", ");
                        }
                    }
                    sb.Append(")");

                    var ret = GetReturnType();
                    if (ret != null)
                    {
                        sb.Append($" {ret}");
                    }

                    // check for a function pointer that has a function as a param. This is currently invalid in V.
                    var definition = sb.ToString();
                    if (definition.LastIndexOf("fn") > 2)
                    {
                        return($"voidptr /* {definition} */");
                    }
                    return(sb.ToString());
                }
                else if (cppPtrType.ElementType.TypeKind == CppTypeKind.Typedef)
                {
                    // functions dont get passed with '&' so we have to see if this Typedef has a function in its lineage
                    if (cppPtrType.ElementType is CppTypedef td && td.IsFunctionType())
                    {
                        return(GetVType(cppPtrType.ElementType));
                    }
                    return("&" + GetVType(cppPtrType.ElementType));
                }

                return("&" + GetVType(cppPtrType.ElementType.GetDisplayName()));
            }             // end Pointer

            if (cppType.TypeKind == CppTypeKind.Array)
            {
                var arrType = cppType as CppArrayType;
                if (arrType.ElementType is CppClass arrParamClass)
                {
                    if (arrParamClass.Name.Contains("va_"))
                    {
                        Console.WriteLine($"Found unhandled vararg param! [{cppType}]");
                        return("voidptr /* ...voidptr */");
                    }
                }
                var eleType = GetVType(arrType.ElementType);
                if (arrType.Size > 0)
                {
                    return($"[{arrType.Size}]{eleType}");
                }
                return($"[]{eleType}");
            }

            return(GetVType(cppType.GetDisplayName()));
        }
Ejemplo n.º 10
0
 public static bool IsBool(this CppType type) => type.GetDisplayName() == "bool";