MakeGenericType() 공개 메소드

public MakeGenericType ( ) : Type
리턴 Type
예제 #1
0
        internal static FieldInfo GetClassLiteralField(Type type)
        {
            Debug.Assert(type != Types.Void);
            if (classLiteralType == null)
            {
#if STATIC_COMPILER
                classLiteralType = JVM.CoreAssembly.GetType("ikvm.internal.ClassLiteral`1");
#elif !FIRST_PASS
                classLiteralType = typeof([email protected] <>);
#endif
            }
#if !STATIC_COMPILER
            if (!IsTypeBuilder(type))
            {
                return(classLiteralType.MakeGenericType(type).GetField("Value", BindingFlags.Public | BindingFlags.Static));
            }
#endif
            if (classLiteralField == null)
            {
                classLiteralField = classLiteralType.GetField("Value", BindingFlags.Public | BindingFlags.Static);
            }
#if !NOEMIT
            return(TypeBuilder.GetField(classLiteralType.MakeGenericType(type), classLiteralField));
#else
            return(null);
#endif
        }
예제 #2
0
파일: FakeTypes.cs 프로젝트: moayyaed/ikvm
 internal static Type GetAttributeReturnValueType(Type attributeType)
 {
     return(genericAttributeAnnotationReturnValueType.MakeGenericType(attributeType));
 }
예제 #3
0
파일: FakeTypes.cs 프로젝트: moayyaed/ikvm
 internal static Type GetAttributeMultipleType(Type attributeType)
 {
     return(genericAttributeAnnotationMultipleType.MakeGenericType(attributeType));
 }
예제 #4
0
파일: FakeTypes.cs 프로젝트: moayyaed/ikvm
 internal static Type GetDelegateType(Type delegateType)
 {
     return(genericDelegateInterfaceType.MakeGenericType(delegateType));
 }
예제 #5
0
파일: FakeTypes.cs 프로젝트: moayyaed/ikvm
 internal static Type GetEnumType(Type enumType)
 {
     return(genericEnumEnumType.MakeGenericType(enumType));
 }
예제 #6
0
        MethodInfo GetEnumeratorInfo(TypeModel model, out MethodInfo moveNext, out MethodInfo current)
        {
#if WINRT
            TypeInfo enumeratorType = null, iteratorType, expectedType = ExpectedType.GetTypeInfo();
#else
            Type enumeratorType = null, iteratorType, expectedType = ExpectedType;
#endif

            // try a custom enumerator
            MethodInfo getEnumerator = Helpers.GetInstanceMethod(expectedType, "GetEnumerator", null);
            Type       itemType      = Tail.ExpectedType;

            if (getEnumerator != null)
            {
                iteratorType = getEnumerator.ReturnType
#if WINRT
                               .GetTypeInfo()
#endif
                ;
                moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext", null);
                PropertyInfo prop = Helpers.GetProperty(iteratorType, "Current");
                current = prop == null ? null : Helpers.GetGetMethod(prop, false);
                if (moveNext == null && (model.MapType(ienumeratorType).IsAssignableFrom(iteratorType)))
                {
                    moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext", null);
                }
                // fully typed
                if (moveNext != null && moveNext.ReturnType == model.MapType(typeof(bool)) &&
                    current != null && current.ReturnType == itemType)
                {
                    return(getEnumerator);
                }
                moveNext = current = getEnumerator = null;
            }

#if !NO_GENERICS
            // try IEnumerable<T>
            Type tmp = model.MapType(typeof(System.Collections.Generic.IEnumerable <>), false);

            if (tmp != null)
            {
                tmp = tmp.MakeGenericType(itemType);

#if WINRT
                enumeratorType = tmp.GetTypeInfo();
#else
                enumeratorType = tmp;
#endif
            }
            ;
            if (enumeratorType != null && enumeratorType.IsAssignableFrom(expectedType))
            {
                getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator");

#if WINRT
                iteratorType = getEnumerator.ReturnType.GetTypeInfo();
#else
                iteratorType = getEnumerator.ReturnType;
#endif

                moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext");
                current  = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current"), false);
                return(getEnumerator);
            }
#endif
            // give up and fall-back to non-generic IEnumerable
            enumeratorType = model.MapType(ienumerableType);
            getEnumerator  = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator");
            iteratorType   = getEnumerator.ReturnType
#if WINRT
                             .GetTypeInfo()
#endif
            ;
            moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext");
            current  = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current"), false);
            return(getEnumerator);
        }
예제 #7
0
 internal static Type GetAttributeType(Type type)
 {
     return(genericType.MakeGenericType(type));
 }
예제 #8
0
        void WriteIL(LineWriter lw, MethodBase mb, MethodBody body, Type[] genericTypeArguments, Type[] genericMethodArguments)
        {
            ParameterInfo[] parameters = mb.GetParameters();
            int             level      = lw.Column;

            byte[] code = body.GetILAsByteArray();
            lw.GoToColumn(level);
            lw.WriteLine("// Code size       {0} (0x{0:x})", code.Length);
            lw.GoToColumn(level);
            lw.WriteLine(".maxstack  {0}", body.MaxStackSize);

            IList <LocalVariableInfo> locals = body.LocalVariables;

            if (locals.Count != 0)
            {
                lw.GoToColumn(level);
                lw.Write(".locals ");
                if (body.InitLocals)
                {
                    lw.Write("init ");
                }
                lw.Write("(");
                bool first = true;
                foreach (var local in locals)
                {
                    if (!first)
                    {
                        lw.WriteLine(",");
                        lw.GoToColumn(level + 9);
                    }
                    first = false;
                    WriteSignatureType(lw, local.LocalType, TypeLocation.Local);
                    if (local.IsPinned)
                    {
                        lw.Write(" pinned");
                    }
                    WriteCustomModifiers(lw, local.__GetCustomModifiers());
                    lw.Write(" V_{0}", local.LocalIndex);
                }
                lw.WriteLine(")");
            }

            var exceptions  = new List <ExceptionHandlingClause>();
            var exceptions2 = new List <ExceptionHandlingClause>();

            SortExceptions(body.ExceptionHandlingClauses, exceptions, exceptions2);

            Stack <ExceptionHandlingClause> activeExceptions = new Stack <ExceptionHandlingClause>();
            ExceptionHandlingClause         currentException = null;
            bool extraNewLine      = false;
            int  nextFlatException = 0;
            int  nextException     = 0;
            bool handler           = false;
            int  pos = 0;

            while (pos < code.Length)
            {
                if (extraNewLine)
                {
                    lw.WriteLine();
                    extraNewLine = false;
                }
                if (currentException != null)
                {
                    if (currentException.HandlerOffset == pos)
                    {
                        switch (currentException.Flags)
                        {
                        case ExceptionHandlingClauseOptions.Clause:
                            lw.GoToColumn(level - 2);
                            if (currentException.TryOffset + currentException.TryLength == pos)
                            {
                                lw.WriteLine("}  // end .try");
                            }
                            else
                            {
                                lw.WriteLine("}  // end handler");
                            }
                            lw.GoToColumn(level - 2);
                            lw.Write("catch ");
                            if (currentException.CatchType.__IsMissing || !currentException.CatchType.IsGenericType)
                            {
                                WriteTypeDefOrRef(lw, currentException.CatchType);
                            }
                            else
                            {
                                WriteSignatureType(lw, currentException.CatchType);
                            }
                            lw.WriteLine(" ");
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("{");
                            handler = true;
                            break;

                        case ExceptionHandlingClauseOptions.Finally:
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("}  // end .try");
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("finally");
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("{");
                            break;

                        case ExceptionHandlingClauseOptions.Fault:
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("}  // end .try");
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("fault");
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("{");
                            break;

                        case ExceptionHandlingClauseOptions.Filter:
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("}  // end filter");
                            lw.GoToColumn(level - 2);
                            lw.WriteLine("{  // handler");
                            handler = true;
                            break;

                        default:
                            throw new IKVM.Reflection.BadImageFormatException();
                        }
                    }
                    else if (currentException.FilterOffset == pos && pos != 0)
                    {
                        lw.GoToColumn(level - 2);
                        if (handler)
                        {
                            lw.WriteLine("}  // end handler");
                        }
                        else
                        {
                            lw.WriteLine("}  // end .try");
                        }
                        lw.GoToColumn(level - 2);
                        lw.WriteLine("filter");
                        lw.GoToColumn(level - 2);
                        lw.WriteLine("{");
                    }
                }
                while (nextException < exceptions.Count &&
                       exceptions[nextException].TryOffset == pos)
                {
                    activeExceptions.Push(currentException);
                    ExceptionHandlingClause prevException = currentException;
                    currentException = exceptions[nextException++];
                    if (prevException != null && currentException.TryOffset == prevException.TryOffset && currentException.TryLength == prevException.TryLength)
                    {
                        // another handler for the same block
                        continue;
                    }
                    handler = false;
                    lw.GoToColumn(level);
                    lw.WriteLine(".try");
                    lw.GoToColumn(level);
                    lw.WriteLine("{");
                    level += 2;
                }
                lw.GoToColumn(level);
                int currPos = pos;
                lw.Write("IL_{0:x4}:  ", pos);
                int   level1      = lw.Column;
                short opcodeValue = code[pos++];
                if (opcodeValue == 0xFE)
                {
                    opcodeValue = (short)(0xFE00 + code[pos++]);
                }
                OpCode opcode = opcodes[opcodeValue + 512];
                lw.Write("{0}", opcode.Name);
                switch (opcode.OperandType)
                {
                case OperandType.InlineNone:
                    break;

                case OperandType.InlineBrTarget:
                    lw.GoToColumn(level1 + 11);
                    lw.Write("IL_{0:x4}", ReadInt32(code, ref pos) + pos);
                    break;

                case OperandType.ShortInlineBrTarget:
                    lw.GoToColumn(level1 + 11);
                    lw.Write("IL_{0:x4}", (sbyte)code[pos++] + pos);
                    break;

                case OperandType.InlineMethod:
                {
                    lw.GoToColumn(level1 + 11);
                    int        token = ReadInt32(code, ref pos);
                    MethodBase methodOrConstructor = ResolveMethod(token, genericTypeArguments, genericMethodArguments);
                    if ((methodOrConstructor.CallingConvention & CallingConventions.Any) == CallingConventions.VarArgs)
                    {
                        CustomModifiers[] customModifiers;
                        Type[]            optionalParameterTypes = ResolveOptionalParameterTypes(token, genericTypeArguments, genericMethodArguments, out customModifiers);
                        WriteInlineMethod(lw, methodOrConstructor, optionalParameterTypes, customModifiers);
                    }
                    else
                    {
                        WriteInlineMethod(lw, methodOrConstructor, Type.EmptyTypes, null);
                    }
                }
                break;

                case OperandType.InlineField:
                    lw.GoToColumn(level1 + 11);
                    WriteInlineField(lw, ResolveField(ReadInt32(code, ref pos), genericTypeArguments, genericMethodArguments));
                    break;

                case OperandType.InlineI:
                    lw.GoToColumn(level1 + 11);
                    WriteInlineI(lw, ReadInt32(code, ref pos));
                    break;

                case OperandType.InlineI8:
                    lw.GoToColumn(level1 + 11);
                    WriteInlineI8(lw, ReadInt64(code, ref pos));
                    break;

                case OperandType.ShortInlineI:
                    lw.GoToColumn(level1 + 11);
                    lw.Write("{0}", (sbyte)code[pos++]);
                    break;

                case OperandType.InlineR:
                    lw.GoToColumn(level1 + 11);
                    WriteInlineR(lw, ReadDouble(code, ref pos), false);
                    break;

                case OperandType.ShortInlineR:
                    lw.GoToColumn(level1 + 11);
                    WriteShortInlineR(lw, ReadSingle(code, ref pos), false);
                    break;

                case OperandType.InlineType:
                    if (opcode == OpCodes.Constrained)
                    {
                        // "constrained." is too long to fit in the opcode column
                        lw.Write(" ");
                    }
                    else
                    {
                        lw.GoToColumn(level1 + 11);
                    }
                    WriteInlineType(lw, ReadInt32(code, ref pos), genericTypeArguments, genericMethodArguments);
                    break;

                case OperandType.InlineTok:
                {
                    int token = ReadInt32(code, ref pos);
                    switch (token >> 24)
                    {
                    case 0x01:
                    case 0x02:
                        lw.GoToColumn(level1 + 11);
                        WriteTypeDefOrRef(lw, ResolveType(token, genericTypeArguments, genericMethodArguments));
                        break;

                    case 0x1B:
                    {
                        Type type = ResolveType(token, genericTypeArguments, genericMethodArguments);
                        if (type.IsGenericTypeDefinition)
                        {
                            // HACK because typeof(Foo<>).MakeGenericType(typeof(Foo<>).GetGenericArguments()) == typeof(Foo<>)
                            // we need to inflate the builder here
                            type = type.MakeGenericType(type.GetGenericArguments());
                        }
                        lw.GoToColumn(level1 + 11);
                        WriteSignatureType(lw, type);
                        break;
                    }

                    case 0x04:
                    case 0x06:
                    case 0x0A:
                    case 0x2B:
                    {
                        MemberInfo member = ResolveMember(token, genericTypeArguments, genericMethodArguments);
                        if (member is FieldInfo)
                        {
                            lw.GoToColumn(level1 + 11);
                            lw.Write("field ");
                            WriteInlineField(lw, (FieldInfo)member);
                        }
                        else
                        {
                            var mb1 = (MethodBase)member;
                            lw.GoToColumn(level1 + 11);
                            if (mb1.__IsMissing || !mb1.IsGenericMethod || compat != CompatLevel.V20)
                            {
                                lw.Write("method ");
                            }
                            WriteInlineMethod(lw, mb1, Type.EmptyTypes, null);
                        }
                        break;
                    }

                    default:
                        throw new NotImplementedException("token type = " + (token >> 24));
                    }
                }
                break;

                case OperandType.InlineVar:
                    lw.GoToColumn(level1 + 11);
                    WriteInlineVar(lw, mb, opcode, parameters, ReadInt16(code, ref pos));
                    break;

                case OperandType.ShortInlineVar:
                    lw.GoToColumn(level1 + 11);
                    WriteInlineVar(lw, mb, opcode, parameters, code[pos++]);
                    break;

                case OperandType.InlineString:
                    lw.GoToColumn(level1 + 11);
                    WriteInlineString(lw, module.ResolveString(ReadInt32(code, ref pos)), level);
                    break;

                case OperandType.InlineSwitch:
                {
                    lw.GoToColumn(level1 + 11);
                    lw.WriteLine("( ");
                    int count  = ReadInt32(code, ref pos);
                    int offset = pos + 4 * count;
                    for (int i = 0; i < count - 1; i++)
                    {
                        lw.GoToColumn(level + 22);
                        lw.WriteLine("IL_{0:x4},", offset + ReadInt32(code, ref pos));
                    }
                    lw.GoToColumn(level + 22);
                    lw.Write("IL_{0:x4})", offset + ReadInt32(code, ref pos));
                }
                break;

                case OperandType.InlineSig:
                    lw.GoToColumn(level1 + 11);
                    WriteStandAloneMethodSig(lw, module.__ResolveStandAloneMethodSig(ReadInt32(code, ref pos), genericTypeArguments, genericMethodArguments), false, false);
                    break;

                default:
                    throw new InvalidOperationException();
                }
                lw.WriteLine();

                if (opcode == OpCodes.Leave || opcode == OpCodes.Leave_S)
                {
                    if (pos < code.Length)
                    {
                        lw.WriteLine();
                    }
                }
                else if (opcode != OpCodes.Switch && opcode != OpCodes.Rethrow && opcode != OpCodes.Endfilter && opcode != OpCodes.Endfinally)
                {
                    switch (opcode.FlowControl)
                    {
                    case FlowControl.Branch:
                    case FlowControl.Cond_Branch:
                    case FlowControl.Throw:
                    case FlowControl.Return:
                        extraNewLine = true;
                        break;
                    }
                }
                if (nextFlatException < exceptions2.Count && exceptions2[nextFlatException].HandlerOffset + exceptions2[nextFlatException].HandlerLength == currPos)
                {
                    if (extraNewLine && pos < code.Length)
                    {
                        extraNewLine = false;
                        lw.WriteLine();
                    }
                    lw.GoToColumn(level);
                    if (exceptions2[nextFlatException].FilterOffset == 0)
                    {
                        lw.Write(".try IL_{0:x4} to IL_{1:x4} catch ", exceptions2[nextFlatException].TryOffset, exceptions2[nextFlatException].TryOffset + exceptions2[nextFlatException].TryLength);
                        if (exceptions2[nextFlatException].CatchType.__IsMissing || !exceptions2[nextFlatException].CatchType.IsGenericType)
                        {
                            WriteTypeDefOrRef(lw, exceptions2[nextFlatException].CatchType);
                        }
                        else
                        {
                            WriteSignatureType(lw, exceptions2[nextFlatException].CatchType);
                        }
                        lw.WriteLine(" handler IL_{0:x4} to IL_{1:x4}", exceptions2[nextFlatException].HandlerOffset, exceptions2[nextFlatException].HandlerOffset + exceptions2[nextFlatException].HandlerLength);
                    }
                    else
                    {
                        lw.WriteLine(".try IL_{0:x4} to IL_{1:x4} filter IL_{2:x4} handler IL_{3:x4} to IL_{4:x4}",
                                     exceptions2[nextFlatException].TryOffset, exceptions2[nextFlatException].TryOffset + exceptions2[nextFlatException].TryLength,
                                     exceptions2[nextFlatException].FilterOffset,
                                     exceptions2[nextFlatException].HandlerOffset, exceptions2[nextFlatException].HandlerOffset + exceptions2[nextFlatException].HandlerLength);
                    }
                    nextFlatException++;
                }

                while (currentException != null && currentException.HandlerOffset + currentException.HandlerLength == pos)
                {
                    ExceptionHandlingClause prevException = currentException;
                    currentException = activeExceptions.Pop();
                    if (currentException == null || currentException.TryOffset != prevException.TryOffset || currentException.TryLength != prevException.TryLength)
                    {
                        if (extraNewLine && pos < code.Length)
                        {
                            extraNewLine = false;
                            lw.WriteLine();
                        }
                        level -= 2;
                        lw.GoToColumn(level);
                        lw.WriteLine("}  // end handler");
                        handler = false;
                    }
                    else
                    {
                        handler = true;
                    }
                }
            }
        }
예제 #9
0
        internal static bool IdentifyImmutable(TypeModel model, Type declaredType, out MethodInfo builderFactory, out MethodInfo add, out MethodInfo addRange, out MethodInfo finish)
        {
            builderFactory = add = addRange = finish = null;
            if (model == null || declaredType == null)
            {
                return(false);
            }
#if WINRT || COREFX
            TypeInfo declaredTypeInfo = declaredType.GetTypeInfo();
#else
            Type declaredTypeInfo = declaredType;
#endif

            // try to detect immutable collections; firstly, they are all generic, and all implement IReadOnlyCollection<T> for some T
            if (!declaredTypeInfo.IsGenericType)
            {
                return(false);
            }

#if WINRT || COREFX
            Type[] typeArgs = declaredTypeInfo.GenericTypeArguments, effectiveType;
#else
            Type[] typeArgs = declaredTypeInfo.GetGenericArguments(), effectiveType;
#endif
            switch (typeArgs.Length)
            {
            case 1:
                effectiveType = typeArgs;
                break;     // fine

            case 2:
                Type kvp = model.MapType(typeof(System.Collections.Generic.KeyValuePair <,>));
                if (kvp == null)
                {
                    return(false);
                }
                kvp           = kvp.MakeGenericType(typeArgs);
                effectiveType = new Type[] { kvp };
                break;

            default:
                return(false);    // no clue!
            }

            if (ResolveIReadOnlyCollection(declaredType, null) == null)
            {
                return(false);                                                        // no IReadOnlyCollection<T> found
            }
            // and we want to use the builder API, so for generic Foo<T> or IFoo<T> we want to use Foo.CreateBuilder<T>
            string name = declaredType.Name;
            int    i    = name.IndexOf('`');
            if (i <= 0)
            {
                return(false);
            }
            name = declaredTypeInfo.IsInterface ? name.Substring(1, i - 1) : name.Substring(0, i);

            Type outerType = model.GetType(declaredType.Namespace + "." + name, declaredTypeInfo.Assembly);
            // I hate special-cases...
            if (outerType == null && name == "ImmutableSet")
            {
                outerType = model.GetType(declaredType.Namespace + ".ImmutableHashSet", declaredTypeInfo.Assembly);
            }
            if (outerType == null)
            {
                return(false);
            }

#if WINRT
            foreach (MethodInfo method in outerType.GetTypeInfo().DeclaredMethods)
#else
            foreach (MethodInfo method in outerType.GetMethods())
#endif
            {
                if (!method.IsStatic || method.Name != "CreateBuilder" || !method.IsGenericMethodDefinition || method.GetParameters().Length != 0 ||
                    method.GetGenericArguments().Length != typeArgs.Length)
                {
                    continue;
                }

                builderFactory = method.MakeGenericMethod(typeArgs);
                break;
            }
            Type voidType = model.MapType(typeof(void));
            if (builderFactory == null || builderFactory.ReturnType == null || builderFactory.ReturnType == voidType)
            {
                return(false);
            }


            add = Helpers.GetInstanceMethod(builderFactory.ReturnType, "Add", effectiveType);
            if (add == null)
            {
                return(false);
            }

            finish = Helpers.GetInstanceMethod(builderFactory.ReturnType, "ToImmutable", Helpers.EmptyTypes);
            if (finish == null || finish.ReturnType == null || finish.ReturnType == voidType)
            {
                return(false);
            }

            if (!(finish.ReturnType == declaredType || Helpers.IsAssignableFrom(declaredType, finish.ReturnType)))
            {
                return(false);
            }

            addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { declaredType });
            if (addRange == null)
            {
                Type enumerable = model.MapType(typeof(System.Collections.Generic.IEnumerable <>), false);
                if (enumerable != null)
                {
                    addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { enumerable.MakeGenericType(effectiveType) });
                }
            }

            return(true);
        }
예제 #10
0
        internal TypeWrapper LoadGenericClass(string name)
        {
            // generic class name grammar:
            //
            // mangled(open_generic_type_name) "_$$$_" M(parameter_class_name) ( "_$$_" M(parameter_class_name) )* "_$$$$_"
            //
            // mangled() is the normal name mangling algorithm
            // M() is a replacement of "__" with "$$005F$$005F" followed by a replace of "." with "__"
            //
            int pos = name.IndexOf("_$$$_");

            if (pos <= 0 || !name.EndsWith("_$$$$_"))
            {
                return(null);
            }
            Type type = GetGenericTypeDefinition(DotNetTypeWrapper.DemangleTypeName(name.Substring(0, pos)));

            if (type == null)
            {
                return(null);
            }
            List <string> typeParamNames = new List <string>();

            pos += 5;
            int start = pos;
            int nest  = 0;

            for (;;)
            {
                pos = name.IndexOf("_$$", pos);
                if (pos == -1)
                {
                    return(null);
                }
                if (name.IndexOf("_$$_", pos, 4) == pos)
                {
                    if (nest == 0)
                    {
                        typeParamNames.Add(name.Substring(start, pos - start));
                        start = pos + 4;
                    }
                    pos += 4;
                }
                else if (name.IndexOf("_$$$_", pos, 5) == pos)
                {
                    nest++;
                    pos += 5;
                }
                else if (name.IndexOf("_$$$$_", pos, 6) == pos)
                {
                    if (nest == 0)
                    {
                        if (pos + 6 != name.Length)
                        {
                            return(null);
                        }
                        typeParamNames.Add(name.Substring(start, pos - start));
                        break;
                    }
                    nest--;
                    pos += 6;
                }
                else
                {
                    pos += 3;
                }
            }
            Type[] typeArguments = new Type[typeParamNames.Count];
            for (int i = 0; i < typeArguments.Length; i++)
            {
                string s = (string)typeParamNames[i];
                // only do the unmangling for non-generic types (because we don't want to convert
                // the double underscores in two adjacent _$$$_ or _$$$$_ markers)
                if (s.IndexOf("_$$$_") == -1)
                {
                    s = s.Replace("__", ".");
                    s = s.Replace("$$005F$$005F", "__");
                }
                int dims = 0;
                while (s.Length > dims && s[dims] == 'A')
                {
                    dims++;
                }
                if (s.Length == dims)
                {
                    return(null);
                }
                TypeWrapper tw = null;
                switch (s[dims])
                {
                case 'L':
                    tw = LoadClassByDottedNameFast(s.Substring(dims + 1));
                    tw.Finish();
                    break;

                case 'Z':
                    tw = PrimitiveTypeWrapper.BOOLEAN;
                    break;

                case 'B':
                    tw = PrimitiveTypeWrapper.BYTE;
                    break;

                case 'S':
                    tw = PrimitiveTypeWrapper.SHORT;
                    break;

                case 'C':
                    tw = PrimitiveTypeWrapper.CHAR;
                    break;

                case 'I':
                    tw = PrimitiveTypeWrapper.INT;
                    break;

                case 'F':
                    tw = PrimitiveTypeWrapper.FLOAT;
                    break;

                case 'J':
                    tw = PrimitiveTypeWrapper.LONG;
                    break;

                case 'D':
                    tw = PrimitiveTypeWrapper.DOUBLE;
                    break;
                }
                if (tw == null)
                {
                    return(null);
                }
                if (dims > 0)
                {
                    tw = tw.MakeArrayType(dims);
                }
                typeArguments[i] = tw.TypeAsSignatureType;
            }
            try
            {
                type = type.MakeGenericType(typeArguments);
            }
            catch (ArgumentException)
            {
                // one of the typeArguments failed to meet the constraints
                return(null);
            }
            TypeWrapper wrapper = GetWrapperFromType(type);

            if (wrapper != null && wrapper.Name != name)
            {
                // the name specified was not in canonical form
                return(null);
            }
            return(wrapper);
        }