private MethodDefinition InjectPropertySet(FieldDefinition field, string name, bool isPublic = true)
    {
        MethodAttributes methodAttributes = MethodAttributes.HideBySig | MethodAttributes.Virtual;

        if (isPublic)
        {
            methodAttributes = MethodAttributes.Public | methodAttributes;
        }
        else
        {
            methodAttributes = MethodAttributes.Private | methodAttributes;
        }

        var set          = new MethodDefinition("set_" + name, methodAttributes, typeSystem.Void);
        var instructions = set.Body.Instructions;

        instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
        instructions.Add(Instruction.Create(OpCodes.Ldarg_1));
        instructions.Add(Instruction.Create(OpCodes.Stfld, field));
        instructions.Add(Instruction.Create(OpCodes.Ret));
        set.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, field.FieldType));
        set.SemanticsAttributes = MethodSemanticsAttributes.Setter;
        set.CustomAttributes.Add(new CustomAttribute(msCoreReferenceFinder.CompilerGeneratedReference));
        return(set);
    }
    private MethodDefinition InjectPropertyGet(FieldDefinition field, string name, bool isPublic = true)
    {
        MethodAttributes methodAttributes = MethodAttributes.HideBySig | MethodAttributes.Virtual;

        if (isPublic)
        {
            methodAttributes = MethodAttributes.Public | methodAttributes;
        }
        else
        {
            methodAttributes = MethodAttributes.Private | methodAttributes;
        }

        var get          = new MethodDefinition("get_" + name, methodAttributes, field.FieldType);
        var instructions = get.Body.Instructions;

        instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
        instructions.Add(Instruction.Create(OpCodes.Ldfld, field));
        instructions.Add(Instruction.Create(OpCodes.Stloc_0));
        var inst = Instruction.Create(OpCodes.Ldloc_0);

        instructions.Add(Instruction.Create(OpCodes.Br_S, inst));
        instructions.Add(inst);
        instructions.Add(Instruction.Create(OpCodes.Ret));
        get.Body.Variables.Add(new VariableDefinition(field.FieldType));
        get.Body.InitLocals     = true;
        get.SemanticsAttributes = MethodSemanticsAttributes.Getter;
        get.CustomAttributes.Add(new CustomAttribute(msCoreReferenceFinder.CompilerGeneratedReference));
        return(get);
    }
 public MethodDefinition createMethod(String sMethodName, MethodAttributes maMethodAttributes,
                                      TypeReference trReturnType)
 {
     var newMethod = new MethodDefinition(sMethodName, maMethodAttributes, trReturnType);
     newMethod.Body.CilWorker.Emit(OpCodes.Ret);
     return newMethod;
 }
        private void AddConstructor()
        {
            var baseCtor = this.module.Import(this.module.TypeSystem.Object.Resolve().GetConstructors().First());
            const MethodAttributes methodAttributes =
                MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig |
                MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
            var ctor = new MethodDefinition(
                ".ctor", methodAttributes, this.module.TypeSystem.Void);

            foreach (var prop in this.properties)
            {
                prop.CtorParameter = new ParameterDefinition(prop.Name, ParameterAttributes.None, prop.GenericParameter);
                ctor.Parameters.Add(prop.CtorParameter);
            }

            var ctorBody = ctor.Body;

            ctorBody.MaxStackSize = 8;
            var ilproc = ctorBody.GetILProcessor();

            ilproc.Emit(OpCodes.Ldarg_0);
            ilproc.Emit(OpCodes.Call, baseCtor);

            foreach (var prop in this.properties)
            {
                ilproc.Emit(OpCodes.Ldarg_0);
                ilproc.Emit(OpCodes.Ldarg, prop.CtorParameter);
                ilproc.Emit(OpCodes.Stfld, prop.FieldIlReference);
            }

            ilproc.Emit(OpCodes.Ret);

            this.definition.Methods.Add(ctor);
        }
        static TypeDefinition TryGenerateExternalContainerType(TypeDefinition type, Context context, TypeReference objectReference, MethodReference preserveAttributeConstructor)
        {
            if (type.Module == context.Module || type.IsPublic)
            {
                return(null);
            }

            var externalTypeContainer = new TypeDefinition
                                        (
                Context.kNamespace,
                Utility.GetSanitizedName(type.FullName, "_Container__"),
                TypeAttributes.Class | TypeAttributes.NotPublic,
                objectReference
                                        );

            var baseEmptyConstructor = context.Module.ImportReference(objectReference.Resolve().GetConstructors().First());
            const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
            var constructor = new MethodDefinition(".ctor", methodAttributes, context.ImportReference(typeof(void)));

            constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Call, baseEmptyConstructor));
            constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
            constructor.CustomAttributes.Add(new CustomAttribute(preserveAttributeConstructor));
            externalTypeContainer.Methods.Add(constructor);

            var containerField = new FieldDefinition(ReflectedMemberPropertyName.ContainerFieldName, FieldAttributes.Public, objectReference);

            containerField.CustomAttributes.Add(new CustomAttribute(preserveAttributeConstructor));
            externalTypeContainer.Fields.Add(containerField);

            context.Module.Types.Add(externalTypeContainer);

            return(externalTypeContainer);
        }
Exemple #6
0
        /// <summary>
        /// Injects the initializer.
        /// </summary>
        /// <param name="initializer">The initializer.</param>
        /// <exception cref="InjectionException">No module class found</exception>
        private void InjectInitializer(MethodReference initializer)
        {
            const MethodAttributes Attributes = MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;

            if (initializer == null)
            {
                throw new ArgumentNullException(nameof(initializer));
            }

            var initializerReturnType = InjectionTargetAssembly.MainModule.Import(initializer.ReturnType);

            // Create a new method .cctor (a static constructor) inside the Assembly
            var cctor = new MethodDefinition(".cctor", Attributes, initializerReturnType);
            var il    = cctor.Body.GetILProcessor();

            il.Append(il.Create(OpCodes.Call, initializer));
            il.Append(il.Create(OpCodes.Ret));

            var moduleClass = InjectionTargetAssembly.MainModule.Types.FirstOrDefault(t => t.Name == "<Module>");

            if (moduleClass == null)
            {
                throw new InjectionException("No module class found");
            }

            moduleClass.Methods.Add(cctor);
        }
        /// <summary>
        /// Adds a rewritable property to the <paramref name="typeDef">target type</paramref>.
        /// </summary>
        /// <param name="typeDef">The target type that will hold the newly-created property.</param>
        /// <param name="propertyName">The name of the property itself.</param>
        /// <param name="propertyType">The <see cref="TypeReference"/> instance that describes the property type.</param>
        public static void AddProperty(this TypeDefinition typeDef, string propertyName,
                                       TypeReference propertyType)
        {
            var fieldName   = string.Format("__{0}_backingField", propertyName);
            var actualField = new FieldDefinition(fieldName, FieldAttributes.Private,
                                                  propertyType);


            typeDef.Fields.Add(actualField);


            FieldReference backingField = actualField;

            if (typeDef.GenericParameters.Count > 0)
            {
                backingField = GetBackingField(fieldName, typeDef, propertyType);
            }

            var getterName = string.Format("get_{0}", propertyName);
            var setterName = string.Format("set_{0}", propertyName);


            const MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig |
                                                MethodAttributes.SpecialName | MethodAttributes.NewSlot |
                                                MethodAttributes.Virtual;

            var module   = typeDef.Module;
            var voidType = module.Import(typeof(void));

            // Implement the getter and the setter
            var getter = AddPropertyGetter(propertyType, getterName, attributes, backingField);
            var setter = AddPropertySetter(propertyType, attributes, backingField, setterName, voidType);

            typeDef.AddProperty(propertyName, propertyType, getter, setter);
        }
Exemple #8
0
 public FluentMethodBuilder(ModuleDefinition module, string name)
 {
     _module     = module;
     _name       = name;
     _visibility = MethodAttributes.Public;
     _returnType = _module.Import(typeof(void));
 }
Exemple #9
0
        public static void AddParameterlessConstructor(this TypeDefinition @this)
        {
            TypeReference baseType = @this.BaseType;
            Func <MethodDefinition, bool> findCtor = new Func <MethodDefinition, bool>(definition =>
                                                                                       definition.Name.Equals(".ctor") &&
                                                                                       definition.Parameters.Count == 0);

            bool isDefaultConstructorAlreadyDefined = @this.Methods.Any(findCtor);

            if (isDefaultConstructorAlreadyDefined)
            {
                return;
            }

            const MethodAttributes methodAttributes =
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName |
                MethodAttributes.RTSpecialName;

            MethodReference serializableContructor = baseType.ReferenceMethod(findCtor);

            if (serializableContructor == null)
            {
                return;
            }

            MethodDefinition serializationConstr = new MethodDefinition(".ctor", methodAttributes, @this.Module.TypeSystem.Void);

            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Call, @this.Module.ImportReference(serializableContructor)));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
            @this.Methods.Add(serializationConstr);
        }
Exemple #10
0
 public static Func <MethodDefinition, bool> MethodAttributeSetter(Mono.Cecil.MethodAttributes attrs)
 {
     return(method => {
         method.Attributes = (method.Attributes & ~attrs) | attrs;
         return true;
     });
 }
        public MethodDefinition createMethod(String sMethodName, MethodAttributes maMethodAttributes,
                                             TypeReference trReturnType)
        {
            var newMethod = new MethodDefinition(sMethodName, maMethodAttributes, trReturnType);

            newMethod.Body.GetILProcessor().Emit(OpCodes.Ret);
            return(newMethod);
        }
        private static void CreatePropertyInterface(this ModuleDefinition module, Type type, string namespaceName)
        {
// public interface Int32Property
// {
//     void Allocate(ref BlobBuilder builder, ref BlobVariable<Int32> blobVariable);
// }
// .class interface public abstract auto ansi
//   EntitiesBT.Editor.Int32Property
// {
//
//   .method public hidebysig virtual newslot abstract instance void
//     Allocate(
//       valuetype [Unity.Entities]Unity.Entities.BlobBuilder& builder,
//       valuetype [EntitiesBT.Runtime]EntitiesBT.Variable.BlobVariable`1<int32>& blobVariable
//     ) cil managed
//   {
//     // Can't find a body
//   } // end of method Int32Property::Allocate
// } // end of class EntitiesBT.Editor.Int32Property

            const TypeAttributes interfaceAttributes = TypeAttributes.Class
                                                       | TypeAttributes.Interface
                                                       | TypeAttributes.Public
                                                       | TypeAttributes.Abstract
                                                       | TypeAttributes.AutoClass
                                                       | TypeAttributes.AnsiClass;
            var interfaceType = new TypeDefinition(namespaceName, $"{type.Name}Property", interfaceAttributes, module.TypeSystem.Object);

            const MethodAttributes methodAttributes = MethodAttributes.Public
                                                      | MethodAttributes.HideBySig
                                                      | MethodAttributes.Virtual
                                                      | MethodAttributes.NewSlot
                                                      | MethodAttributes.Abstract;
            var allocateMethod   = new MethodDefinition("Allocate", methodAttributes, module.TypeSystem.Void);
            var builderParameter = new ParameterDefinition(
                "builder"
                , ParameterAttributes.None
                , module.ImportReference(typeof(BlobBuilder)).MakeByReferenceType()
                );
            var blobVariableParameter = new ParameterDefinition(
                "blobVariable"
                , ParameterAttributes.None
                , module.ImportReference(typeof(BlobVariable <>).MakeGenericType(type)).MakeByReferenceType()
                );

            allocateMethod.Parameters.Add(builderParameter);
            allocateMethod.Parameters.Add(blobVariableParameter);
            interfaceType.Methods.Add(allocateMethod);
            module.Types.Add(interfaceType);

            foreach (var propertyType in _PROPERTY_TYPES.Value)
            {
                module.CreatePropertyClass(namespaceName, type, propertyType, new InterfaceImplementation(interfaceType));
            }
        }
Exemple #13
0
        /// <summary>
        /// Create a module initializer in an assembly that contains a global::Module.Init() method.
        /// </summary>
        /// <param name="targetAssembly">The assembly to create the module initializer.</param>
        static void Main(FileInfo targetAssembly)
        {
            //https://www.coengoedegebure.com/module-initializers-in-dotnet/
            Console.WriteLine($"Processing {targetAssembly}");
            using (var symbolStream = GetSymbolInformation(targetAssembly.FullName, out ISymbolReaderProvider reader,
                                                           out ISymbolWriterProvider writer))
            {
                var module = ModuleDefinition.ReadModule(targetAssembly.FullName, new ReaderParameters
                {
                    ReadSymbols          = symbolStream != null || reader is EmbeddedPortablePdbReaderProvider,
                    SymbolReaderProvider = reader,
                    SymbolStream         = symbolStream,
                    InMemory             = true,
                });

                var type = module.GetType("Module");
                if (type == null)
                {
                    Console.WriteLine("Could not find global::Module class");
                    return;
                }

                var initMethod = type.GetMethods().FirstOrDefault(x => x.Name == "Init");
                if (initMethod == null)
                {
                    Console.WriteLine("Could not find Init() method on global::Module class");
                    return;
                }


                var assemblyModuleClass = module.GetType("<Module>");
                if (assemblyModuleClass == null)
                {
                    Console.WriteLine("Could not find <Module> class");
                    return;
                }

                const MethodAttributes Attributes =
                    MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
                var cctor = new MethodDefinition(".cctor", Attributes, module.ImportReference(typeof(void)));
                var il    = cctor.Body.GetILProcessor();
                il.Append(il.Create(OpCodes.Call, initMethod));
                il.Append(il.Create(OpCodes.Ret));

                assemblyModuleClass.Methods.Add(cctor);

                module.Write(targetAssembly.FullName, new WriterParameters
                {
                    WriteSymbols         = writer != null,
                    SymbolWriterProvider = writer,
                });
                Console.WriteLine($"Wrote updated assembly '{targetAssembly.FullName}'");
            }
        }
        /// <summary>
        /// Adds the default constructor. For Binary Deserialization for a class that inherits from a types that implements
        /// ISerializable interface must override the constructor this signature:
        /// <code>
        /// protected Class ( SerializationInfo info,	 StreamingContext context  ) //On the base class
        ///
        /// public CTOR(SerializationInfo info,	 StreamingContext context) : base(info,context)
        /// </code>
        /// </summary>
        /// <param name="this">The TypeDefinition.</param>
        public static void AddDefaultConstructor(this TypeDefinition @this)
        {
            TypeReference baseType = @this.BaseType;

            bool isDefaultConstructorToBeAdded =
               @this
               .BaseType
               .Resolve()
               .Interfaces
               .Any(reference => reference.InterfaceType.FullName == typeof(ISerializable).FullName);

            if (!isDefaultConstructorToBeAdded) return;

            if (@this.Module == null) return;

            Func<MethodDefinition, bool> findCtor = new Func<MethodDefinition, bool>(definition =>
                                                           definition.Name.Equals(".ctor") &&
                                                           definition.Parameters.Count == 2 &&
                                                           definition.Parameters.Any(
                                                               par =>
                                                               par.Name.Equals("info") || par.Name.Equals("context")));

            bool isDefaultConstructorAlreadyDefined = @this.Methods.Any(findCtor);

            if (isDefaultConstructorAlreadyDefined) return;

            const MethodAttributes methodAttributes =
                MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName |
                MethodAttributes.RTSpecialName;

            MethodReference serializableContructor = baseType.ReferenceMethod(findCtor);

            if (serializableContructor==null) return;

            TypeReference serializationInfo = @this.Module.Import(serializableContructor.Parameters[0].ParameterType);

            TypeReference streamingContext = @this.Module.Import(serializableContructor.Parameters[1].ParameterType);

            MethodDefinition serializationConstr = new MethodDefinition(".ctor", methodAttributes, @this.Module.TypeSystem.Void);
            ParameterDefinition par1 = new ParameterDefinition(serializableContructor.Parameters[0].Name, serializableContructor.Parameters[0].Attributes, serializationInfo);
            ParameterDefinition par2 = new ParameterDefinition(serializableContructor.Parameters[1].Name, serializableContructor.Parameters[1].Attributes, streamingContext);

            serializationConstr.Parameters.Add(par1);
            serializationConstr.Parameters.Add(par2);

            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_2));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Call, @this.Module.Import(serializableContructor)));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
            serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
            @this.Methods.Add(serializationConstr);
        }
Exemple #15
0
        protected MethodDefinition NewExplicitMethod(MethodInfo method)
        {
            MethodAttributes attributes = MethodAttributes.SpecialName | MethodAttributes.Private | MethodAttributes.Virtual;
            MethodDefinition definition = new MethodDefinition(method.DeclaringType.FullName + "." + method.Name, attributes, Import(method.ReturnType));

            foreach (ParameterInfo pi in method.GetParameters())
            {
                definition.Parameters.Add(new ParameterDefinition(pi.Name, Mono.Cecil.ParameterAttributes.None, Import(pi.ParameterType)));
            }
            definition.Overrides.Add(_context.Import(method));
            return(definition);
        }
Exemple #16
0
        internal void AddOrReplaceIoc(ILProcessor il)
        {
            var mod         = il.Body.Method.DeclaringType.Module;
            var myNamespace = mod.Types.Select(t => t.Namespace)
                              .Where(n => !string.IsNullOrWhiteSpace(n)).OrderBy(n => n.Length).First();
            const TAttr attr = TAttr.Class | TAttr.Public | TAttr.Sealed
                               | TAttr.Abstract | TAttr.BeforeFieldInit;
            var objBase = mod.ImportReference(typeof(object));
            var type    = new TypeDefinition(myNamespace, IocName, attr, objBase);
            var oldType = mod.Types.FirstOrDefault(t => t.FullName == type.FullName);

            if (oldType != null)
            {
                mod.Types.Remove(oldType);
            }
            mod.Types.Add(type);
            var         vesselRef = mod.ImportReference(typeof(IVessel));
            const FAttr fieldAttr = FAttr.Static | FAttr.Private;
            var         contField = new FieldDefinition(IocField, fieldAttr, vesselRef);

            type.Fields.Add(contField);
            const MAttr getAttrs = MAttr.Static | MAttr.Public
                                   | MAttr.SpecialName | MAttr.HideBySig;
            var getMethod = new MethodDefinition(IocMethod, getAttrs, vesselRef);

            type.Methods.Add(getMethod);
            ScopeMethod = getMethod;
            IocType     = type;
            var gmil = getMethod.Body.GetILProcessor();

            gmil.Append(gmil.Create(OpCodes.Ldsfld, contField));
            gmil.Append(gmil.Create(OpCodes.Ret));
            var         voidRef     = mod.ImportReference(typeof(void));
            const MAttr constrAttrs = MAttr.Static | MAttr.SpecialName | MAttr.Private
                                      | MAttr.RTSpecialName | MAttr.HideBySig;
            var constr = new MethodDefinition(Defaults.StaticConstrName, constrAttrs, voidRef);

            type.Methods.Add(constr);
            var cil       = constr.Body.GetILProcessor();
            var multiMeth = typeof(DefaultVessel).GetConstructors().First();
            var multiRef  = mod.ImportReference(multiMeth);

            cil.Append(cil.Create(OpCodes.Newobj, multiRef));
            cil.Append(cil.Create(OpCodes.Stsfld, contField));
            cil.Append(cil.Create(OpCodes.Ret));
            il.Append(il.Create(OpCodes.Call, getMethod));
            il.Append(il.Create(OpCodes.Pop));
            il.Append(il.Create(OpCodes.Ret));
        }
Exemple #17
0
        /// <summary>
        ///     Creates a property getter method implementation with the
        ///     <paramref name="propertyType" /> as the return type.
        /// </summary>
        /// <param name="propertyType">Represents the <see cref="TypeReference">return type</see> for the getter method.</param>
        /// <param name="getterName">The getter method name.</param>
        /// <param name="attributes">The method attributes associated with the getter method.</param>
        /// <param name="backingField">The field that will store the instance that the getter method will retrieve.</param>
        /// <returns>A <see cref="MethodDefinition" /> representing the getter method itself.</returns>
        private static MethodDefinition AddPropertyGetter(TypeReference propertyType,
                                                          string getterName, MethodAttributes attributes, FieldReference backingField)
        {
            var getter = new MethodDefinition(getterName, attributes, propertyType)
            {
                IsPublic       = true,
                ImplAttributes = MethodImplAttributes.Managed | MethodImplAttributes.IL
            };

            var IL = getter.Body.Instructions;

            IL.Add(Instruction.Create(OpCodes.Ldarg_0));
            IL.Add(Instruction.Create(OpCodes.Ldfld, backingField));
            IL.Add(Instruction.Create(OpCodes.Ret));

            return(getter);
        }
        /// <summary>
        /// Creates a property getter method implementation with the
        /// <paramref name="propertyType"/> as the return type.
        /// </summary>
        /// <param name="propertyType">Represents the <see cref="TypeReference">return type</see> for the getter method.</param>
        /// <param name="getterName">The getter method name.</param>
        /// <param name="attributes">The method attributes associated with the getter method.</param>
        /// <param name="backingField">The field that will store the instance that the getter method will retrieve.</param>
        /// <returns>A <see cref="MethodDefinition"/> representing the getter method itself.</returns>
        private static MethodDefinition AddPropertyGetter(TypeReference propertyType,
                                                          string getterName, MethodAttributes attributes, FieldReference backingField)
        {
            var getter = new MethodDefinition(getterName, attributes, propertyType)
            {
                IsPublic       = true,
                ImplAttributes = (MethodImplAttributes.Managed | MethodImplAttributes.IL)
            };

            var IL = getter.GetILGenerator();

            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Ldfld, backingField);
            IL.Emit(OpCodes.Ret);

            return(getter);
        }
Exemple #19
0
        static string GetJavaAccess(MethodAttributes access)
        {
            switch (access)
            {
            case MethodAttributes.Public:
                return("public");

            case MethodAttributes.FamORAssem:
                return("protected");

            case MethodAttributes.Family:
                return("protected");

            default:
                return("private");
            }
        }
        private static void CreatePropertyClass(this ModuleDefinition module, string namespaceName, Type valueType, Type propertyType, InterfaceImplementation @interface)
        {
// .class public auto ansi beforefieldinit
//   EntitiesBT.Editor.Int32CustomViariableProperty
//     extends class [EntitiesBT.Runtime]EntitiesBT.Variable.CustomVariableProperty`1<int32>
//     implements EntitiesBT.Editor.Int32Property
// {
//
//   .method public hidebysig specialname rtspecialname instance void
//     .ctor() cil managed
//   {
//     .maxstack 8
//
//     IL_0000: ldarg.0      // this
//     IL_0001: call         instance void class [EntitiesBT.Runtime]EntitiesBT.Variable.CustomVariableProperty`1<int32>::.ctor()
//     IL_0006: nop
//     IL_0007: ret
//
//   } // end of method Int32CustomViariableProperty::.ctor
// } // end of class EntitiesBT.Editor.Int32CustomViariableProperty

            const TypeAttributes classAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit;
            var baseType  = propertyType.MakeGenericType(valueType);
            var classType = new TypeDefinition(namespaceName, $"{valueType.Name}{propertyType.Name}", classAttributes, module.ImportReference(baseType));

            classType.Interfaces.Add(@interface);

            const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
            var ctor = new MethodDefinition(".ctor", methodAttributes, module.TypeSystem.Void);
            var il   = ctor.Body.GetILProcessor();

            il.Append(il.Create(OpCodes.Ldarg_0));
            // call the base constructor
            il.Append(il.Create(OpCodes.Call, module.ImportReference(baseType.GetConstructor(Array.Empty <Type>()))));
            il.Append(il.Create(OpCodes.Nop));
            il.Append(il.Create(OpCodes.Ret));

            var serializableAttribute = new CustomAttribute(module.ImportReference(
                                                                typeof(SerializableAttribute).GetConstructor(Array.Empty <Type>())
                                                                ));

            classType.CustomAttributes.Add(serializableAttribute);
            classType.Methods.Add(ctor);
            module.Types.Add(classType);
        }
        private void AddConstructor(TypeDefinition type, IDictionary <FieldReference, FieldDefinition> fields)
        {
            const MethodAttributes methodAttributes = MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Public;
            MethodDefinition       ctor             = new MethodDefinition(".ctor", methodAttributes, Import(typeof(void)));

            AddMethodParameters(ctor, fields.Values);

            ILProcessor cil = ctor.Body.GetILProcessor();

            cil.Emit(OpCodes.Ldarg_0);
            cil.Emit(OpCodes.Call, DefaultObjectConstructor());

            EmitFieldInitialization(ctor, fields.Values, ctor.Parameters);

            cil.Emit(OpCodes.Ret);

            type.Methods.Add(ctor);
        }
        /// <summary>
        /// Adds a new method to the <paramref name="typeDef">target type</paramref>.
        /// </summary>
        /// <param name="typeDef">The type that will hold the newly-created method.</param>
        /// <param name="attributes">The <see cref="Mono.Cecil.MethodAttributes"/> parameter that describes the characteristics of the method.</param>
        /// <param name="methodName">The name to be given to the new method.</param>
        /// <param name="returnType">The method return type.</param>
        /// <param name="callingConvention">The calling convention of the method being created.</param>
        /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param>
        /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns>
        public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName,
                                                    MethodAttributes attributes, MethodCallingConvention callingConvention, Type returnType, params Type[] parameterTypes)
        {
            var method = new MethodDefinition(methodName, attributes, null)
            {
                CallingConvention = callingConvention
            };

            typeDef.Methods.Add(method);

            // Match the parameter types
            method.AddParameters(parameterTypes);

            // Match the return type
            method.SetReturnType(returnType);

            return(method);
        }
        private void InjectInitializer(MethodReference callee)
        {
            Debug.Assert(Assembly != null);
            TypeReference          voidRef    = Assembly.MainModule.Import(callee.ReturnType);
            const MethodAttributes attributes = MethodAttributes.Static
                                                | MethodAttributes.SpecialName
                                                | MethodAttributes.RTSpecialName;
            var         cctor = new MethodDefinition(".cctor", attributes, voidRef);
            ILProcessor il    = cctor.Body.GetILProcessor();

            il.Append(il.Create(OpCodes.Call, callee));
            il.Append(il.Create(OpCodes.Ret));

            TypeDefinition moduleClass = Find(Assembly.MainModule.Types, t => t.Name == "<Module>");

            moduleClass.Methods.Add(cctor);

            Debug.Assert(moduleClass != null, "Found no module class!");
        }
Exemple #24
0
        /// <summary>
        /// Creates a module init for a C# assembly.
        /// </summary>
        /// <param name="method">The method to add to the module init.</param>
        private void CreateModuleInit(MethodDefinition method)
        {
            const MethodAttributes ModuleInitAttributes = MethodAttributes.Private
                                                          | MethodAttributes.HideBySig
                                                          | MethodAttributes.Static
                                                          | MethodAttributes.Assembly
                                                          | MethodAttributes.SpecialName
                                                          | MethodAttributes.RTSpecialName;

            var moduleType = assembly.MainModule.GetTypeResolved("<Module>");

            // Get or create ModuleInit method
            var cctor = moduleType.Methods.FirstOrDefault(moduleTypeMethod => moduleTypeMethod.Name == ".cctor");

            if (cctor == null)
            {
                cctor = new MethodDefinition(".cctor", ModuleInitAttributes, method.ReturnType);
                moduleType.Methods.Add(cctor);
            }

            bool isCallAlreadyDone = cctor.Body.Instructions.Any(instruction => instruction.OpCode == OpCodes.Call && instruction.Operand == method);

            // If the method is not called, we can add it
            if (!isCallAlreadyDone)
            {
                var ilProcessor    = cctor.Body.GetILProcessor();
                var retInstruction = cctor.Body.Instructions.FirstOrDefault(instruction => instruction.OpCode == OpCodes.Ret);
                var callMethod     = ilProcessor.Create(OpCodes.Call, method);

                if (retInstruction == null)
                {
                    // If a ret instruction is not present, add the method call and ret
                    ilProcessor.Append(callMethod);
                    ilProcessor.Emit(OpCodes.Ret);
                }
                else
                {
                    // If a ret instruction is already present, just add the method to call before
                    ilProcessor.InsertBefore(retInstruction, callMethod);
                }
            }
        }
Exemple #25
0
        public static void Inject(AssemblyDefinition lib)
        {
            const MethodAttributes Attributes = MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
            var initializer = getInititializer(lib);

            if (initializer == null)
            {
                throw new ArgumentNullException(nameof(initializer));
            }
            var initializerReturnType = lib.MainModule.Import(initializer.ReturnType);
            // Create a new method .cctor (a static constructor) inside the Assembly
            var cctor = new MethodDefinition(".cctor", Attributes, initializerReturnType);
            var il    = cctor.Body.GetILProcessor();

            il.Append(il.Create(OpCodes.Call, initializer));
            il.Append(il.Create(OpCodes.Ret));

            var moduleClass = lib.MainModule.Types.FirstOrDefault(t => t.Name == "<Module>");

            moduleClass.Methods.Add(cctor);
        }
        /// <summary>
        /// Adds a new method to the <paramref name="typeDef">target type</paramref>.
        /// </summary>
        /// <param name="typeDef">The type that will hold the newly-created method.</param>
        /// <param name="attributes">The <see cref="Mono.Cecil.MethodAttributes"/> parameter that describes the characteristics of the method.</param>
        /// <param name="methodName">The name to be given to the new method.</param>
        /// <param name="returnType">The method return type.</param>
        /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param>
        /// <param name="genericParameterTypes">The list of generic argument types that will be used to define the method signature.</param>
        /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns>
        public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName,
                                                    Mono.Cecil.MethodAttributes attributes, System.Type returnType, System.Type[] parameterTypes, System.Type[] genericParameterTypes)
        {
            var method = new MethodDefinition(methodName, attributes, typeDef.Module.Import(typeof(object)));

            typeDef.Methods.Add(method);

            //Match the generic parameter types
            foreach (var genericParameterType in genericParameterTypes)
            {
                method.AddGenericParameter(genericParameterType);
            }

            // Match the parameter types
            method.AddParameters(parameterTypes);

            // Match the return type
            method.SetReturnType(returnType);

            return(method);
        }
        /// <summary>
        /// Adds a new method to the <paramref name="typeDef">target type</paramref>.
        /// </summary>
        /// <param name="typeDef">The type that will hold the newly-created method.</param>
        /// <param name="attributes">The <see cref="MethodAttributes"/> parameter that describes the characteristics of the method.</param>
        /// <param name="methodName">The name to be given to the new method.</param>
        /// <param name="returnType">The method return type.</param>
        /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param>
        /// <param name="genericParameterTypes">The list of generic argument types that will be used to define the method signature.</param>
        /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns>
        public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName,
                                                    MethodAttributes attributes, Type returnType, Type[] parameterTypes, Type[] genericParameterTypes)
        {
            var method = new MethodDefinition(methodName, attributes, null);

            typeDef.Methods.Add(method);

            //Match the generic parameter types
            foreach (var genericParameterType in genericParameterTypes)
            {
                method.AddGenericParameter(genericParameterType);
            }

            // Match the parameter types
            method.AddParameters(parameterTypes);

            // Match the return type
            method.SetReturnType(returnType);

            return(method);
        }
Exemple #28
0
        public static DynamicMethodBody NewMethod
            (this TypeDefinition that, string methodName, MethodAttributes methodAttributes, Type returnType, AssemblyDefinition assembly)
        {
            var typeReference = assembly.MainModule.Import(returnType);

            var method = new MethodDefinition(methodName, methodAttributes, typeReference);

            ILProcessor worker = method.Body.GetILProcessor();

            var emitter = new CecilILEmitter(
                assembly,
                worker,
                method.Body.Instructions.Add);

            var dinfo = new DynamicMethodInfo(emitter);

            method.LoadArgsTo(dinfo);

            that.Methods.Add(method);

            return(dinfo.Body);
        }
        /// <summary>
        /// Adds a default constructor to the target type.
        /// </summary>
        /// <param name="parentType">The base class that contains the default constructor that will be used for constructor chaining..</param>
        /// <param name="targetType">The type that will contain the default constructor.</param>
        /// <returns>The default constructor.</returns>
        public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType, Type parentType)
        {
            ModuleDefinition module           = targetType.Module;
            TypeReference    voidType         = module.Import(typeof(void));
            MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig
                                                | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;


            BindingFlags    flags             = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
            ConstructorInfo objectConstructor = parentType.GetConstructor(flags, null, new Type[0], null);

            // Revert to the System.Object constructor
            // if the parent type does not have a default constructor
            if (objectConstructor == null)
            {
                objectConstructor = typeof(object).GetConstructor(new Type[0]);
            }

            MethodReference baseConstructor = module.Import(objectConstructor);

            // Define the default constructor
            var ctor = new MethodDefinition(".ctor", methodAttributes, voidType)
            {
                CallingConvention = MethodCallingConvention.StdCall,
                ImplAttributes    = (MethodImplAttributes.IL | MethodImplAttributes.Managed)
            };

            CilWorker IL = ctor.Body.CilWorker;

            // Call the constructor for System.Object, and exit
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Call, baseConstructor);
            IL.Emit(OpCodes.Ret);

            targetType.Constructors.Add(ctor);

            return(ctor);
        }
Exemple #30
0
        /// <summary>
        /// Creates a module init for a C# assembly.
        /// </summary>
        /// <param name="Method">The Method to add to the module init.</param>
        private void CreateModuleInit(MethodDefinition Method)
        {
            MethodAttributes ModuleInitAttributes = MethodAttributes.Static | MethodAttributes.Assembly | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
            TypeDefinition ModuleType = Assembly.MainModule.GetType("<Module>");

            // Get or create ModuleInit Method
            MethodDefinition Cctor = ModuleType.Methods.FirstOrDefault(X => X.Name == ".cctor");

            if (Cctor == null)
            {
                Cctor = new MethodDefinition(".cctor", ModuleInitAttributes, Method.ReturnType);
                ModuleType.Methods.Add(Cctor);
            }

            Boolean IsCallAlreadyDone = Cctor.Body.Instructions.Any(X => X.OpCode == OpCodes.Call && X.Operand == Method);

            // If the Method is not called, we can add it
            if (IsCallAlreadyDone)
                return;

            ILProcessor IlProcessor = Cctor.Body.GetILProcessor();
            var RetInstruction = Cctor.Body.Instructions.FirstOrDefault(X => X.OpCode == OpCodes.Ret);
            var CallMethod = IlProcessor.Create(OpCodes.Call, Method);

            if (RetInstruction == null)
            {
                // If a ret instruction is not present, add the Method call and ret
                IlProcessor.Append(CallMethod);
                IlProcessor.Emit(OpCodes.Ret);
            }
            else
            {
                // If a ret instruction is already present, just add the Method to call before
                IlProcessor.InsertBefore(RetInstruction, CallMethod);
            }
        }
Exemple #31
0
 public static GenericFuncContainer <MethodDefinition, bool> MethodNegAttributeComparer(Mono.Cecil.MethodAttributes negAttrs)
 {
     return(new GenericFuncContainer <MethodDefinition, bool>(method => {
         return (method.Attributes & negAttrs) == 0;
     }));
 }
        /// <summary>
        /// Creates a property setter method implementation with the
        /// <paramref name="propertyType"/> as the setter parameter.
        /// </summary>
        /// <param name="propertyType">Represents the <see cref="TypeReference">parameter type</see> for the setter method.</param>
        /// <param name="attributes">The method attributes associated with the setter method.</param>
        /// <param name="backingField">The field that will store the instance for the setter method.</param>
        /// <param name="setterName">The method name of the setter method.</param>
        /// <param name="voidType">The <see cref="TypeReference"/> that represents <see cref="Void"/>.</param>
        /// <returns>A <see cref="MethodDefinition"/> that represents the setter method itself.</returns>
        private static MethodDefinition AddPropertySetter(TypeReference propertyType, MethodAttributes attributes, FieldReference backingField, string setterName, TypeReference voidType)
        {
            var setter = new MethodDefinition(setterName, attributes, voidType)
                             {
                                 IsPublic = true,
                                 ImplAttributes = (MethodImplAttributes.Managed | MethodImplAttributes.IL)
                             };

            setter.Parameters.Add(new ParameterDefinition(propertyType));

            var IL = setter.GetILGenerator();
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Stfld, backingField);
            IL.Emit(OpCodes.Ret);

            return setter;
        }
        /// <summary>
        /// Creates a property getter method implementation with the
        /// <paramref name="propertyType"/> as the return type.
        /// </summary>
        /// <param name="propertyType">Represents the <see cref="TypeReference">return type</see> for the getter method.</param>
        /// <param name="getterName">The getter method name.</param>
        /// <param name="attributes">The method attributes associated with the getter method.</param>
        /// <param name="backingField">The field that will store the instance that the getter method will retrieve.</param>
        /// <returns>A <see cref="MethodDefinition"/> representing the getter method itself.</returns>
        private static MethodDefinition AddPropertyGetter(TypeReference propertyType,
            string getterName, MethodAttributes attributes, FieldReference backingField)
        {
            var getter = new MethodDefinition(getterName, attributes, propertyType)
                             {
                                 IsPublic = true,
                                 ImplAttributes = (MethodImplAttributes.Managed | MethodImplAttributes.IL)
                             };

            var IL = getter.GetILGenerator();
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Ldfld, backingField);
            IL.Emit(OpCodes.Ret);

            return getter;
        }
        /// <summary>
        /// Adds a new method to the <paramref name="typeDef">target type</paramref>.
        /// </summary>
        /// <param name="typeDef">The type that will hold the newly-created method.</param>
        /// <param name="attributes">The <see cref="MethodAttributes"/> parameter that describes the characteristics of the method.</param>
        /// <param name="methodName">The name to be given to the new method.</param>
        /// <param name="returnType">The method return type.</param>        
        /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param>
        /// <param name="genericParameterTypes">The list of generic argument types that will be used to define the method signature.</param>
        /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns>
        public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName,
            MethodAttributes attributes, Type returnType, Type[] parameterTypes, Type[] genericParameterTypes)
        {
            var method = new MethodDefinition(methodName, attributes, null);

            typeDef.Methods.Add(method);

            //Match the generic parameter types
            foreach (var genericParameterType in genericParameterTypes)
            {
                method.AddGenericParameter(genericParameterType);
            }

            // Match the parameter types
            method.AddParameters(parameterTypes);

            // Match the return type
            method.SetReturnType(returnType);

            return method;
        }
        /// <summary>
        /// Adds a new method to the <paramref name="typeDef">target type</paramref>.
        /// </summary>
        /// <param name="typeDef">The type that will hold the newly-created method.</param>
        /// <param name="attributes">The <see cref="Mono.Cecil.MethodAttributes"/> parameter that describes the characteristics of the method.</param>
        /// <param name="methodName">The name to be given to the new method.</param>
        /// <param name="returnType">The method return type.</param>
        /// <param name="callingConvention">The calling convention of the method being created.</param>
        /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param>
        /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns>
        public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName,
            MethodAttributes attributes, MethodCallingConvention callingConvention, Type returnType, params Type[] parameterTypes)
        {
            var method = new MethodDefinition(methodName, attributes, null)
            {
                CallingConvention = callingConvention
            };

            typeDef.Methods.Add(method);

            // Match the parameter types
            method.AddParameters(parameterTypes);

            // Match the return type
            method.SetReturnType(returnType);

            return method;
        }
        private TypeDefinition CreateRepositoryType(TypeDefinition repoTypeDef,
            TypeCodeGenInfo rti,
            MethodAttributes methodAttributes,
            string repoTypeNameFormat,
            TypeAttributes typeAttributes,
            bool isImplementation,
            IEnumerable<TypeReference> interfacesToImplement = null)
        {
            var tt = (ResourceType)rti.TransformedType;

            repoTypeDef.Namespace = this.assemblyName;
            repoTypeDef.Name = string.Format(repoTypeNameFormat, rti.TransformedType.Name);
            repoTypeDef.Attributes = typeAttributes;

            if (isImplementation)
                repoTypeDef.BaseType = rti.CustomRepositoryBaseTypeReference;

            repoTypeDef.Interfaces.AddRange(interfacesToImplement ?? Enumerable.Empty<TypeReference>());
            var baseTypeGenericDef = rti.CustomRepositoryBaseTypeDefinition;
            var baseTypeGenericArgs = rti.CustomRepositoryBaseTypeReference.GenericArguments.ToArray();

            foreach (var subType in tt.MergedTypes.Concat(tt))
            {
                if (subType.PostAllowed)
                {
                    AddRepositoryFormPostMethod(methodAttributes,
                        isImplementation,
                        subType,
                        repoTypeDef,
                        baseTypeGenericDef,
                        baseTypeGenericArgs);
                }
            }
            if (tt.PrimaryId != null)
            {
                AddRepositoryGetByIdMethod(rti,
                    methodAttributes,
                    isImplementation,
                    tt,
                    repoTypeDef,
                    baseTypeGenericDef,
                    baseTypeGenericArgs,
                    "Get");
                AddRepositoryGetByIdMethod(rti,
                    methodAttributes,
                    isImplementation,
                    tt,
                    repoTypeDef,
                    baseTypeGenericDef,
                    baseTypeGenericArgs,
                    "GetLazy");
            }

            // Constructor
            if (isImplementation)
            {
                var baseCtor = baseTypeGenericDef.GetConstructors().First();
                var baseCtorRef =
                    Import(baseCtor).MakeHostInstanceGeneric(baseTypeGenericArgs);

                var ctor = new MethodDefinition(
                    ".ctor",
                    MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName
                    | MethodAttributes.Public,
                    VoidTypeRef);

                baseCtor.Parameters.Select(x => new ParameterDefinition(x.Name, x.Attributes, Import(x.ParameterType)))
                    .AddTo(ctor.Parameters);

                ctor.Body.MaxStackSize = 8;
                var ctorIlProcessor = ctor.Body.GetILProcessor();
                ctorIlProcessor.Append(Instruction.Create(OpCodes.Ldarg_0));
                foreach (var ctorParam in ctor.Parameters)
                    ctorIlProcessor.Append(Instruction.Create(OpCodes.Ldarg, ctorParam));
                ctorIlProcessor.Append(Instruction.Create(OpCodes.Call, baseCtorRef));
                ctorIlProcessor.Append(Instruction.Create(OpCodes.Ret));
                repoTypeDef.Methods.Add(ctor);
            }

            if (!this.module.Types.Contains(repoTypeDef))
                this.module.Types.Add(repoTypeDef);
            return repoTypeDef;
        }
        private void AddRepositoryGetByIdMethod(TypeCodeGenInfo rti,
            MethodAttributes methodAttributes,
            bool isImplementation,
            TransformedType tt,
            TypeDefinition repoTypeDef,
            TypeDefinition baseTypeGenericDef,
            TypeReference[] baseTypeGenericArgs,
            string methodName)
        {
            var method = new MethodDefinition(methodName, methodAttributes, rti.InterfaceType);
            var idType = tt.PrimaryId.PropertyType;
            if (!(idType is TypeSpec))
                throw new NotSupportedException("Id needs to be a shared type.");
            var idTypeRef = Import(idType.Type);
            method.Parameters.Add(new ParameterDefinition(tt.PrimaryId.LowerCaseName,
                0,
                idTypeRef));
            repoTypeDef.Methods.Add(method);

            if (isImplementation)
            {
                var baseGetMethodRef =
                    Import(Import(typeof(ClientRepository<,>)).Resolve().Methods.First(x => x.Name == methodName))
                        .MakeHostInstanceGeneric(baseTypeGenericArgs);
                var ilproc = method.Body.GetILProcessor();

                ilproc.Emit(OpCodes.Ldarg_0);
                ilproc.Emit(OpCodes.Ldarg_1);
                if (idType.Type.IsValueType)
                    ilproc.Emit(OpCodes.Box, idTypeRef);
                else
                    ilproc.Emit(OpCodes.Castclass, idTypeRef);
                ilproc.Emit(OpCodes.Callvirt, baseGetMethodRef);
                ilproc.Emit(OpCodes.Ret);
            }
        }
        private void AddRepositoryFormPostMethod(MethodAttributes methodAttributes,
            bool isImplementation,
            ResourceType subType,
            TypeDefinition repoTypeDef,
            TypeDefinition baseTypeGenericDef,
            TypeReference[] baseTypeGenericArgs)
        {
            var postReturnTypeRef = this.clientTypeInfoDict[subType.PostReturnType].InterfaceType;
            var method = new MethodDefinition("Post",
                methodAttributes,
                postReturnTypeRef);
            method.Parameters.Add(new ParameterDefinition("form", 0, this.clientTypeInfoDict[subType].PostFormType));
            repoTypeDef.Methods.Add(method);

            if (isImplementation)
            {
                var basePostMethodRef =
                    Import(
                        Import(typeof(ClientRepository<,>)).Resolve().GetMethods()
                            .Single(
                                x =>
                                    x.Name == "Post" && x.Parameters.Count == 1 &&
                                    x.Parameters[0].Name == "form")
                        ).MakeHostInstanceGeneric(baseTypeGenericArgs);

                var ilproc = method.Body.GetILProcessor();

                ilproc.Emit(OpCodes.Ldarg_0);
                ilproc.Emit(OpCodes.Ldarg_1);

                ilproc.Emit(OpCodes.Callvirt, basePostMethodRef);

                ilproc.Emit(OpCodes.Castclass, postReturnTypeRef);
                ilproc.Emit(OpCodes.Ret);
            }
        }
        public static DynamicMethodBody NewMethod
            (this TypeDefinition that, string methodName, MethodAttributes methodAttributes, Type returnType, AssemblyDefinition assembly)
        {
            var typeReference = assembly.MainModule.Import(returnType);
            
            var method = new MethodDefinition(methodName, methodAttributes, typeReference);
            
            ILProcessor worker = method.Body.GetILProcessor();

            var emitter = new CecilILEmitter(
                assembly,
                worker,
                method.Body.Instructions.Add);

            var dinfo = new DynamicMethodInfo(emitter);
            method.LoadArgsTo(dinfo);

            that.Methods.Add(method);

            return dinfo.Body;
        }