Beispiel #1
0
        static string FormatIl2CppGeneric(TypeSig type)
        {
            string result = "";

            if (type.GetName().StartsWith("List"))
            {
                result = "Il2CppList<";
            }
            else
            if (type.GetName().StartsWith("Dictionary"))
            {
                result = "Il2CppDictionary<";
            }
            else
            {
                return("void*");
            }
            List <string> args = new List <string>();

            foreach (var arg in type.ToGenericInstSig().GenericArguments)
            {
                if (arg.IsGenericInstanceType)
                {
                    args.Add(FormatIl2CppGeneric(arg));
                }
                else
                {
                    args.Add(Il2CppTypeToCppType(arg));
                }
            }
            result += string.Join(", ", args.ToArray());
            result += ">*";
            return(result);
        }
Beispiel #2
0
        public static IList <TypeSig> PossibleTypeSigs(TypeSig returnType,
                                                       IList <TypeSig> typeGenerics, IList <TypeSig> methodGenerics)
        {
            IList <TypeSig> list = new List <TypeSig>();

            // Ignore [], &, * when comparing against generic types
            // Otherwise, String[] Blah<String>(...) won't consider that the
            // return type might be T[].
            Stack <String> modifiers;
            TypeSig        returnTypeBase = SigUtil.ToBaseSig(returnType, out modifiers);

            if (returnTypeBase == null)
            {
                throw new Exception(String.Format("Given TypeSig is not a TypeDefOrRefSig: {0}", returnType));
            }

            // Generic instance type
            if (returnTypeBase.IsGenericInstanceType)
            {
                var genericSig = returnTypeBase.ToGenericInstSig();
                var combos     = GenericUtils.CreateGenericParameterCombinations(
                    genericSig.GenericArguments, typeGenerics, methodGenerics);

                foreach (var combo in combos)
                {
                    list.Add(new GenericInstSig(genericSig.GenericType, combo));
                }

                return(list);
            }
            else             // Non-generic-instance type
            {
                list.Add(returnType);

                for (UInt16 g = 0; g < typeGenerics.Count; g++)
                {
                    var gtype = typeGenerics[g];
                    if (returnTypeBase.FullName.Equals(gtype.FullName))
                    {
                        list.Add(SigUtil.FromBaseSig(new GenericVar(g), modifiers));
                    }
                }

                for (UInt16 g = 0; g < methodGenerics.Count; g++)
                {
                    var gtype = methodGenerics[g];
                    if (returnTypeBase.FullName.Equals(gtype.FullName))
                    {
                        list.Add(SigUtil.FromBaseSig(new GenericMVar(g), modifiers));
                    }
                }

                return(list);
            }
        }
Beispiel #3
0
        private TypeSig RemapGenericType(TypeSig reference)
        {
            var typeDef = reference.TryGetTypeDef();

            if (typeDef != null)
            {
                if (reference.DefinitionAssembly != null && reference.DefinitionAssembly == Module.Assembly)
                {
                    return(reference);
                }
            }

            var genericInstSig = reference.ToGenericInstSig();

            if (genericInstSig != null)
            {
                return(RemapGenericInstSig(genericInstSig));
            }

            throw new NotImplementedException();
        }
        public static HashSet <TypeDef> UsedTypes(this TypeSig typeSig)
        {
            var types = new HashSet <TypeDef>();
            var td    = typeSig.GetNonNestedTypeRefScope().ResolveTypeDef();

            if (td != null)
            {
                types.Add(td);
                if (typeSig.IsGenericInstanceType)
                {
                    var gi = typeSig.ToGenericInstSig();
                    foreach (var gp in gi.GenericArguments)
                    {
                        foreach (var t in gp.UsedTypes())
                        {
                            types.Add(t);
                        }
                    }
                }
            }
            return(types);
        }
        public static TypeDef ToTypeDef(this TypeSig type)
        {
            TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDef();

            if (typeDef != null)
            {
                return(typeDef);
            }
            if (type.IsArray)
            {
                typeDef = type.Next.ToTypeDefOrRef().ResolveTypeDef();
            }
            if (typeDef != null)
            {
                return(typeDef);
            }
            if (type.IsGenericInstanceType)
            {
                typeDef = type.ToGenericInstSig().ToTypeDefOrRef().ResolveTypeDef();
            }
            return(typeDef);
        }
        public static string ParsedTypeSignatureStr(this TypeSig typeSig, bool useValueTypes = true, string context = null, bool typesOnly = false)
        {
            switch (typeSig.ElementType)
            {
            case ElementType.Object:
                return("DLL2SDK::mscorlib::System::Object");

            case ElementType.String:
                return("DLL2SDK::mscorlib::System::String");

            case ElementType.Void when useValueTypes:
                return("void");

            case ElementType.Boolean when useValueTypes:
                return("bool");

            case ElementType.Char when useValueTypes:
                return("wchar_t");

            case ElementType.I1 when useValueTypes:
                return("int8_t");

            case ElementType.U1 when useValueTypes:
                return("uint8_t");

            case ElementType.I2 when useValueTypes:
                return("int16_t");

            case ElementType.U2 when useValueTypes:
                return("uint16_t");

            case ElementType.I4 when useValueTypes:
                return("int32_t");

            case ElementType.U4 when useValueTypes:
                return("uint32_t");

            case ElementType.I8 when useValueTypes:
                return("int64_t");

            case ElementType.U8 when useValueTypes:
                return("uint64_t");

            case ElementType.R4 when useValueTypes:
                return("float");

            case ElementType.R8 when useValueTypes:
                return("double");

            case ElementType.I when useValueTypes:
                return("intptr_t");

            case ElementType.U when useValueTypes:
                return("uintptr_t");
            }

            var underlying = typeSig.GetNonNestedTypeRefScope().ResolveTypeDef();

            if (underlying?.IsEnum ?? false)
            {
                return(underlying.ParsedFullName());
            }

            if (typeSig.IsArray || typeSig.IsSZArray)
            {
                return($"DLL2SDK::Array<{typeSig.Next.ParsedReferenceTypeDefinition(context: context)}>");
            }

            if (typeSig.IsGenericParameter)
            {
                return(typeSig.ToGenericSig().GenericParam.Name.String.Parseable());
            }

            var genericCtx = new List <string>();

            if (typeSig.IsGenericInstanceType)
            {
                var gi = typeSig.ToGenericInstSig();
                genericCtx = new List <string>(gi.GenericArguments.Count);
                foreach (var t in gi.GenericArguments)
                {
                    genericCtx.Add(t.ParsedReferenceTypeDefinition(context: context));
                }
            }

            var typeDef = typeSig.TryGetTypeDef();

            if (typeDef?.HasGenericParameters ?? false)
            {
                var gi = typeDef.GenericParameters;
                genericCtx = new List <string>(gi.Count);
                foreach (var t in gi)
                {
                    genericCtx.Add(t.Name.String.Parseable());
                }
            }

            if (genericCtx.Count > 0)
            {
                var builder = new StringBuilder();
                if (!typesOnly)
                {
                    builder.Append(typeSig.ToTypeDefOrRef().ParsedFullName());
                }
                if (context == null)
                {
                    builder.Append("<");
                    builder.Append(string.Join(", ", genericCtx));
                    builder.Append(">");
                }
                else
                {
                    builder.Append(context);
                }
                return(builder.ToString());
            }

            if (typeSig.IsByRef || typeSig.IsPointer)
            {
                return($"{typeSig.Next.ParsedTypeSignatureStr(context: context)}");
            }

            return(typeSig.ToTypeDefOrRef().ParsedFullName());
        }
Beispiel #7
0
        public static void EscapeMethodTypeName(StringBuilder sb, TypeSig cntSig)
        {
            switch (cntSig.ElementType)
            {
            case ElementType.Void:
                sb.Append("void");
                break;

            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.U1:
            case ElementType.I2:
            case ElementType.U2:
            case ElementType.I4:
            case ElementType.U4:
            case ElementType.I8:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.String:
            case ElementType.I:
            case ElementType.U:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: false, hasModuleName: false));
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.ValueType:
            case ElementType.Class:
            case ElementType.Object:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: false, hasModuleName: false));
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.SZArray:
                sb.Append("System_SZArray_1_");
                EscapeTypeName(sb, cntSig.Next);
                break;

            case ElementType.Var:
            {
                var var = cntSig.ToGenericVar();
                sb.Append(var.GetName());
            }
            break;

            case ElementType.MVar:
            {
                var mvar = cntSig.ToGenericMVar();
                sb.Append(mvar.GetName());
            }
            break;

            case ElementType.GenericInst:
            {
                var sig = cntSig.ToGenericInstSig();
                sb.Append(EscapeTypeName(sig.GenericType.TypeDefOrRef, hasGen: false, hasModuleName: false));
                sb.Append("_");
                for (int i = 0; i < sig.GenericArguments.Count; i++)
                {
                    EscapeMethodTypeName(sb, sig.GenericArguments[i]);
                    if (i != sig.GenericArguments.Count - 1)
                    {
                        sb.Append("_ ");
                    }
                }
            }
            break;

            case ElementType.ByRef:
                sb.Append("ref_");
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            case ElementType.Ptr:
                sb.Append("ptr_");
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            case ElementType.Pinned:
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            case ElementType.CModReqd:
                EscapeMethodTypeName(sb, cntSig.Next);
                break;

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #8
0
        public static void EscapeTypeName(StringBuilder sb, TypeSig cntSig, TypeDef declaringType = null, int hasGen = 0, IList <TypeSig> genArgs = null, bool cppBasicType = false)
        {
            switch (cntSig.ElementType)
            {
            case ElementType.Void:
                sb.Append("void");
                break;

            case ElementType.Boolean:
            case ElementType.Char:
            case ElementType.I1:
            case ElementType.U1:
            case ElementType.I2:
            case ElementType.U2:
            case ElementType.I4:
            case ElementType.U4:
            case ElementType.I8:
            case ElementType.U8:
            case ElementType.R4:
            case ElementType.R8:
            case ElementType.String:
            case ElementType.I:
            case ElementType.U:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    if (declaringType != null && sig.TypeDef == declaringType)
                    {
                        sb.Append(GetConstantTypeName(cntSig.ElementType));
                    }
                    else
                    {
                        sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: hasGen-- > 0, genArgs: genArgs, cppBasicType: cppBasicType));
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.ValueType:
            case ElementType.Class:
            case ElementType.Object:
            {
                switch (cntSig)
                {
                case TypeDefOrRefSig sig:
                    if (sig.IsPrimitive && declaringType != null && sig.TypeDef == declaringType)
                    {
                        sb.Append(GetConstantTypeName(cntSig.ElementType));
                    }
                    else
                    {
                        sb.Append(EscapeTypeName(sig.TypeDefOrRef, hasGen: hasGen-- > 0, genArgs: genArgs, cppBasicType: cppBasicType));
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
            break;

            case ElementType.SZArray:
                sb.Append("::System_Private_CoreLib::System::SZArray_1<");
                EscapeTypeName(sb, cntSig.Next, declaringType, genArgs: genArgs, cppBasicType: true);
                sb.Append(">");
                break;

            case ElementType.Var:
            {
                var var = cntSig.ToGenericVar();
                if (genArgs != null)
                {
                    var sig = genArgs.OfType <GenericSig>().FirstOrDefault(x => x.Number == var.Number);
                    if (sig != null)
                    {
                        EscapeTypeName(sb, sig, cppBasicType: true);
                    }
                    else
                    {
                        EscapeTypeName(sb, genArgs[(int)var.Number], cppBasicType: true);
                    }
                }
                else
                {
                    if (cppBasicType)
                    {
                        sb.Append(var.GetName());
                    }
                    else
                    {
                        sb.Append($"::natsu::to_clr_type_t<{var.GetName()}>");
                    }
                }
            }
            break;

            case ElementType.MVar:
            {
                var mvar = cntSig.ToGenericMVar();
                if (genArgs != null)
                {
                    EscapeTypeName(sb, genArgs[(int)mvar.Number], cppBasicType: true);
                }
                else
                {
                    if (cppBasicType)
                    {
                        sb.Append(mvar.GetName());
                    }
                    else
                    {
                        sb.Append($"::natsu::to_clr_type_t<{mvar.GetName()}>");
                    }
                }
            }
            break;

            case ElementType.GenericInst:
            {
                var sig = cntSig.ToGenericInstSig();
                sb.Append(EscapeTypeName(sig.GenericType.TypeDefOrRef, hasGen: false, cppBasicType: cppBasicType));
                sb.Append("<");
                for (int i = 0; i < sig.GenericArguments.Count; i++)
                {
                    EscapeTypeName(sb, sig.GenericArguments[i], null, genArgs: genArgs, cppBasicType: true);
                    if (i != sig.GenericArguments.Count - 1)
                    {
                        sb.Append(", ");
                    }
                }
                sb.Append(">");
            }
            break;

            case ElementType.ByRef:
                sb.Append("::natsu::gc_ref<");
                sb.Append(EscapeVariableTypeName(cntSig.Next, declaringType, hasGen, genArgs));
                sb.Append(">");
                break;

            case ElementType.Ptr:
                sb.Append("::natsu::gc_ptr<");
                sb.Append(EscapeVariableTypeName(cntSig.Next, declaringType, hasGen, genArgs));
                sb.Append(">");
                break;

            case ElementType.Pinned:
                EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                break;

            case ElementType.CModReqd:
            {
                var modifier = ((ModifierSig)cntSig).Modifier;
                var modName  = modifier.FullName;
                if (modName == "System.Runtime.InteropServices.InAttribute")
                {
                    EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                }
                else if (modName == "System.Runtime.CompilerServices.IsVolatile")
                {
                    sb.Append("::natsu::clr_volatile<");
                    EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                    sb.Append(">");
                }
                else
                {
                    EscapeTypeName(sb, cntSig.Next, declaringType, hasGen, genArgs, cppBasicType: cppBasicType);
                }
                break;
            }

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #9
0
        public static StackType GetStackType(TypeSig type, IList <TypeSig> genArgs = null)
        {
            StackTypeCode code;

            switch (type.ElementType)
            {
            case ElementType.Void:
                code = StackTypeCode.Void;
                break;

            case ElementType.Boolean:
                code = StackTypeCode.Int32;
                break;

            case ElementType.Char:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I1:
                code = StackTypeCode.Int32;
                break;

            case ElementType.U1:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I2:
                code = StackTypeCode.Int32;
                break;

            case ElementType.U2:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I4:
                code = StackTypeCode.Int32;
                break;

            case ElementType.U4:
                code = StackTypeCode.Int32;
                break;

            case ElementType.I8:
                code = StackTypeCode.Int64;
                break;

            case ElementType.U8:
                code = StackTypeCode.Int64;
                break;

            case ElementType.R4:
                code = StackTypeCode.F;
                break;

            case ElementType.R8:
                code = StackTypeCode.F;
                break;

            case ElementType.String:
                code = StackTypeCode.O;
                break;

            case ElementType.Ptr:
                code = StackTypeCode.NativeInt;
                break;

            case ElementType.ByRef:
                code = StackTypeCode.Ref;
                break;

            case ElementType.ValueType:
                code = StackTypeCode.ValueType;
                break;

            case ElementType.Class:
                code = StackTypeCode.O;
                break;

            case ElementType.Array:
                code = StackTypeCode.O;
                break;

            case ElementType.TypedByRef:
                code = StackTypeCode.ValueType;
                break;

            case ElementType.I:
                code = StackTypeCode.NativeInt;
                break;

            case ElementType.U:
                code = StackTypeCode.NativeInt;
                break;

            case ElementType.R:
                code = StackTypeCode.F;
                break;

            case ElementType.Object:
                code = StackTypeCode.O;
                break;

            case ElementType.SZArray:
                code = StackTypeCode.O;
                break;

            case ElementType.Var:
            {
                var var = type.ToGenericVar();
                if (genArgs != null)
                {
                    var sig = genArgs.OfType <GenericSig>().FirstOrDefault(x => x.Number == var.Number);
                    if (sig != null)
                    {
                        code = GetStackType(sig).Code;
                    }
                    else
                    {
                        code = GetStackType(genArgs[(int)var.Number]).Code;
                    }
                }
                else
                {
                    code = StackTypeCode.Runtime;
                }
            }
            break;

            case ElementType.MVar:
            {
                var mvar = type.ToGenericMVar();
                if (genArgs != null)
                {
                    code = GetStackType(genArgs[(int)mvar.Number]).Code;
                }
                else
                {
                    code = StackTypeCode.Runtime;
                }
            }
            break;

            case ElementType.GenericInst:
            {
                var gen = type.ToGenericInstSig();
                code = GetStackType(gen.GenericType, genArgs).Code;
                break;
            }

            case ElementType.CModReqd:
            case ElementType.CModOpt:
            case ElementType.Pinned:
                return(GetStackType(type.Next, genArgs));

            default:
                throw new NotSupportedException();
            }

            return(new StackType {
                Code = code, Name = EscapeVariableTypeName(type, genArgs: genArgs), TypeSig = type, GenArgs = genArgs
            });
        }
Beispiel #10
0
        public static void AddTexts(TypeSig type, IList <TextRun> target)
        {
            if (type.IsSZArray)
            {
                if (type.Next != null)
                {
                    AddTexts(type.Next, target);
                    target.Add(new TextRun("[]"));
                    return;
                }
            }
            else if (type.IsArray)
            {
                if (type.Next != null)
                {
                    AddTexts(type.Next, target);
                    target.Add(new TextRun("["));
                    var arraySig = type.ToArraySig();
                    for (var i = 1; i < arraySig.Rank; i++)
                    {
                        target.Add(new TextRun(","));
                    }
                    target.Add(new TextRun("]"));
                    return;
                }
            }

            string text;
            string cssClass;

            var keyword = TypeSigAsKeyword(type);

            if (!string.IsNullOrEmpty(keyword))
            {
                text     = keyword;
                cssClass = "d-keyword";
            }
            else
            {
                text = type.TypeName;
                // Remove generic parameter count
                // ex) List`1 => List
                var generic = text.LastIndexOf('`');
                if (generic > 0)
                {
                    text = text.Substring(0, generic);
                }

                switch (type.ElementType)
                {
                case ElementType.ValueType:
                    cssClass = "d-valuetype";
                    break;

                case ElementType.Class:
                    var classSig = type.ToClassSig();
                    if (classSig.IsTypeDef)
                    {
                        var typeDef = classSig.TypeDef;
                        if (typeDef.IsInterface)
                        {
                            cssClass = "d-interface";
                        }
                        else if (typeDef.IsSealed)
                        {
                            cssClass = "d-sealedtype";
                        }
                        else
                        {
                            cssClass = "d-type";
                        }
                    }
                    else
                    {
                        cssClass = "d-type";
                    }
                    break;

                case ElementType.GenericInst:
                    var genericInstSig = type.ToGenericInstSig();
                    if (genericInstSig.GenericType.IsTypeDef)
                    {
                        var genericTypeSig = genericInstSig.GenericType.TypeDef.ToTypeSig();
                        AddTexts(genericTypeSig, target);
                    }
                    else
                    {
                        target.Add(new TextRun(text, "d-type"));
                    }
                    target.Add(new TextRun("<"));
                    var _isFirst = true;
                    foreach (var genericArgType in genericInstSig.GenericArguments)
                    {
                        if (_isFirst)
                        {
                            _isFirst = false;
                        }
                        else
                        {
                            target.Add(new TextRun(", "));
                        }
                        AddTexts(genericArgType, target);
                    }
                    target.Add(new TextRun(">"));
                    return;

                case ElementType.I:
                case ElementType.U:
                    cssClass = "d-valuetype";
                    break;

                case ElementType.Var:
                    cssClass = "d-typegenericparameter";
                    break;

                case ElementType.MVar:
                    cssClass = "d-methodgenericparameter";
                    break;

                default:
                    cssClass = string.Empty;
                    break;
                }
            }

            target.Add(new TextRun(text, cssClass));
        }