예제 #1
0
        /// <summary>
        /// Takes a Flame method and converts it to a Cecil method reference.
        /// For this to work, <paramref name="field"/> cannot reference
        /// non-Cecil types or methods.
        /// </summary>
        /// <param name="field">
        /// The method to convert to a method reference.
        /// </param>
        /// <returns>
        /// A method reference.
        /// </returns>
        public static Mono.Cecil.MethodReference ImportReference(
            this Mono.Cecil.ModuleDefinition module,
            IMethod method)
        {
            if (method is ClrMethodDefinition)
            {
                var def = ((ClrMethodDefinition)method).Definition;
                return(module == null ? def : module.ImportReference(def));
            }
            else if (method is IndirectMethodSpecialization)
            {
                var specialization = (IndirectMethodSpecialization)method;
                return(CloneMethodWithDeclaringType(
                           module.ImportReference(specialization.Declaration),
                           module.ImportReference(specialization.ParentType)));
            }
            else if (method is DirectMethodSpecialization)
            {
                var specialization = (DirectMethodSpecialization)method;
                var genInst        = new Mono.Cecil.GenericInstanceMethod(
                    module.ImportReference(specialization.Declaration));

                foreach (var item in specialization.GenericArguments)
                {
                    genInst.GenericArguments.Add(module.ImportReference(item));
                }
                return(genInst);
            }
            else
            {
                throw new NotSupportedException($"Cannot import ill-understood method '{method.FullName}'.");
            }
        }
예제 #2
0
 /// <summary>
 /// Takes a Flame field and converts it to a Cecil field reference.
 /// For this to work, <paramref name="field"/> cannot reference
 /// non-Cecil types or methods.
 /// </summary>
 /// <param name="field">
 /// The field to convert to a field reference.
 /// </param>
 /// <returns>
 /// A field reference.
 /// </returns>
 public static Mono.Cecil.FieldReference ImportReference(
     this Mono.Cecil.ModuleDefinition module,
     IField field)
 {
     if (field is ClrFieldDefinition)
     {
         var def = ((ClrFieldDefinition)field).Definition;
         return(module == null ? def : module.ImportReference(def));
     }
     else if (field is IndirectFieldSpecialization)
     {
         var specialization = (IndirectFieldSpecialization)field;
         var declarationRef = module.ImportReference(specialization.Declaration);
         var typeRef        = module.ImportReference(specialization.ParentType);
         return(new Mono.Cecil.FieldReference(
                    declarationRef.Name,
                    module.ImportReference(declarationRef.FieldType, typeRef), typeRef));
     }
     else
     {
         throw new NotSupportedException($"Cannot import ill-understood field '{field.FullName}'.");
     }
 }
예제 #3
0
        /// <summary>
        /// Takes a Flame type and converts it to a Cecil type reference.
        /// For this to work, <paramref name="type"/> cannot reference
        /// non-Cecil types.
        /// </summary>
        /// <param name="type">
        /// The type to convert to a type reference.
        /// </param>
        /// <returns>
        /// A type reference.
        /// </returns>
        public static Mono.Cecil.TypeReference ImportReference(
            this Mono.Cecil.ModuleDefinition module,
            IType type)
        {
            if (type is ClrTypeDefinition)
            {
                var typeRef = ((ClrTypeDefinition)type).Definition;
                // The module can be null for testing purposes.
                return(module == null ? typeRef : module.ImportReference(typeRef));
            }
            else if (type is ClrGenericParameter)
            {
                // There's no need to "import" generic parameters: they can only be
                // used in the same place where they are defined.
                return(((ClrGenericParameter)type).Definition);
            }
            else if (type is PointerType)
            {
                var pointerType = (PointerType)type;
                var elemType    = pointerType.ElementType;
                var elemTypeRef = module.ImportReference(elemType);
                if (pointerType.Kind == PointerKind.Reference)
                {
                    return(new Mono.Cecil.ByReferenceType(elemTypeRef));
                }
                else if (pointerType.Kind == PointerKind.Box)
                {
                    if (elemType.IsReferenceType())
                    {
                        var def = module.ImportReference(elemTypeRef);
                        return(module == null ? def : module.ImportReference(def));
                    }
                    else
                    {
                        return(module.ImportReference(module.TypeSystem.Object));
                    }
                }
                else
                {
                    return(new Mono.Cecil.PointerType(elemTypeRef));
                }
            }

            IType elementType;

            if (ClrArrayType.TryGetArrayElementType(type, out elementType))
            {
                // Handle arrays.
                int rank;
                ClrArrayType.TryGetArrayRank(type, out rank);
                return(new Mono.Cecil.ArrayType(module.ImportReference(elementType), rank));
            }
            else if (type is TypeSpecialization)
            {
                // Handle generics.
                var instance = new Mono.Cecil.GenericInstanceType(
                    module.ImportReference(
                        type.GetRecursiveGenericDeclaration()));

                foreach (var item in type.GetRecursiveGenericArguments())
                {
                    instance.GenericArguments.Add(module.ImportReference(item));
                }

                return(instance);
            }
            else
            {
                throw new NotSupportedException($"Cannot import ill-understood type '{type.FullName}'.");
            }
        }