コード例 #1
0
        private TypeReference SetCachedType(Type type, TypeReference typeRef, GenericImportKind importKind)
        {
            if (importKind == GenericImportKind.Definition)
            {
                return(typeRef);
            }

            return(CachedTypes[type] = typeRef);
        }
コード例 #2
0
        private bool TryGetCachedType(Type type, out TypeReference typeRef, GenericImportKind importKind)
        {
            if (importKind == GenericImportKind.Definition)
            {
                typeRef = null;
                return(false);
            }

            return(CachedTypes.TryGetValue(type, out typeRef));
        }
コード例 #3
0
        private MethodReference _ImportReference(MethodBase method, IGenericParameterProvider context, GenericImportKind importKind)
        {
            if (CachedMethods.TryGetValue(method, out MethodReference methodRef) && importKind == GenericImportKind.Open)
            {
                return(methodRef);
            }

            if (method is DynamicMethod dm)
            {
                return(new DynamicMethodReference(Module, dm));
            }

            if (UseDefault)
            {
                return(CachedMethods[method] = Default.ImportReference(method, context));
            }

            if (method.IsGenericMethod && !method.IsGenericMethodDefinition ||
                method.IsGenericMethod && method.IsGenericMethodDefinition && importKind == GenericImportKind.Open)
            {
                GenericInstanceMethod gim = new GenericInstanceMethod(_ImportReference((method as MethodInfo).GetGenericMethodDefinition(), context, GenericImportKind.Definition));
                foreach (Type arg in method.GetGenericArguments())
                {
                    // Generic arguments for the generic instance are often given by the next higher provider.
                    gim.GenericArguments.Add(_ImportReference(arg, context));
                }

                return(CachedMethods[method] = gim);
            }

            Type declType = method.DeclaringType;

            methodRef = new MethodReference(
                method.Name,
                _ImportReference(typeof(void), context),
                declType != null ? _ImportReference(declType, context, GenericImportKind.Definition) : ImportModuleType(method.Module, context)
                );

            methodRef.HasThis      = (method.CallingConvention & CallingConventions.HasThis) != 0;
            methodRef.ExplicitThis = (method.CallingConvention & CallingConventions.ExplicitThis) != 0;
            if ((method.CallingConvention & CallingConventions.VarArgs) != 0)
            {
                methodRef.CallingConvention = MethodCallingConvention.VarArg;
            }

            MethodBase methodOrig = method;

            if (declType != null && declType.IsGenericType)
            {
                // In methods of generic types, all generic parameters are already filled in.
                // Meanwhile, cecil requires generic parameter references.
                // Luckily the metadata tokens match up.
                method = method.Module.ResolveMethod(method.MetadataToken);
            }

            if (method.IsGenericMethodDefinition)
            {
                foreach (Type param in method.GetGenericArguments())
                {
                    methodRef.GenericParameters.Add(new GenericParameter(param.Name, methodRef));
                }
            }

            methodRef.ReturnType = _ImportReference((method as MethodInfo)?.ReturnType ?? typeof(void), methodRef);

            foreach (ParameterInfo param in method.GetParameters())
            {
                methodRef.Parameters.Add(new ParameterDefinition(
                                             param.Name,
                                             (Mono.Cecil.ParameterAttributes)param.Attributes,
                                             _ImportReference(param.ParameterType, methodRef)
                                             ));
            }

            return(CachedMethods[methodOrig] = methodRef);
        }
コード例 #4
0
        private TypeReference _ImportReference(Type type, IGenericParameterProvider context, GenericImportKind importKind = GenericImportKind.Open)
        {
            if (TryGetCachedType(type, out TypeReference typeRef, importKind))
            {
                return(_IsGenericInstance(type, importKind) ? _ImportGenericInstance(type, context, typeRef) : typeRef);
            }

            if (UseDefault)
            {
                return(SetCachedType(type, Default.ImportReference(type, context), importKind));
            }

            if (type.HasElementType)
            {
                if (type.IsByRef)
                {
                    return(SetCachedType(type, new ByReferenceType(_ImportReference(type.GetElementType(), context)), importKind));
                }

                if (type.IsPointer)
                {
                    return(SetCachedType(type, new PointerType(_ImportReference(type.GetElementType(), context)), importKind));
                }

                if (type.IsArray)
                {
                    ArrayType at = new ArrayType(_ImportReference(type.GetElementType(), context), type.GetArrayRank());
                    if (type != type.GetElementType().MakeArrayType())
                    {
                        // Non-SzArray
                        // TODO: Find a way to get the bounds without instantiating the array type!

                        /*
                         * Array a = Array.CreateInstance(type, new int[type.GetArrayRank()]);
                         * if (
                         *  at.Rank > 1
                         *  && a.IsFixedSize
                         * ) {
                         *  for (int i = 0; i < at.Rank; i++)
                         *      at.Dimensions[i] = new ArrayDimension(a.GetLowerBound(i), a.GetUpperBound(i));
                         * }
                         */
                        // For now, always assume [0...,0...,
                        // Array.CreateInstance only accepts lower bounds anyway.
                        for (int i = 0; i < at.Rank; i++)
                        {
                            at.Dimensions[i] = new ArrayDimension(0, null);
                        }
                    }
                    return(CachedTypes[type] = at);
                }
            }

            if (_IsGenericInstance(type, importKind))
            {
                return(_ImportGenericInstance(type, context,
                                              _ImportReference(type.GetGenericTypeDefinition(), context, GenericImportKind.Definition)));
            }

            if (type.IsGenericParameter)
            {
                return(SetCachedType(type, ImportGenericParameter(type, context), importKind));
            }

            if (ElementTypes.TryGetValue(type, out typeRef))
            {
                return(SetCachedType(type, typeRef, importKind));
            }

            typeRef = new TypeReference(
                string.Empty,
                type.Name,
                Module,
                ImportReference(type.Assembly.GetName()),
                type.IsValueType
                );

            if (type.IsNested)
            {
                typeRef.DeclaringType = _ImportReference(type.DeclaringType, context, importKind);
            }
            else if (type.Namespace != null)
            {
                typeRef.Namespace = type.Namespace;
            }

            if (type.IsGenericType)
            {
                foreach (Type param in type.GetGenericArguments())
                {
                    typeRef.GenericParameters.Add(new GenericParameter(param.Name, typeRef));
                }
            }

            return(SetCachedType(type, typeRef, importKind));
        }
コード例 #5
0
 private bool _IsGenericInstance(Type type, GenericImportKind importKind)
 {
     return(type.IsGenericType && !type.IsGenericTypeDefinition ||
            type.IsGenericType && type.IsGenericTypeDefinition && importKind == GenericImportKind.Open);
 }