/// <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}'."); } }
/// <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}'."); } }
/// <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}'."); } }