Esempio n. 1
0
        private static TypeDefinition CreatePrototypeType(TypeDefinition type)
        {
            TypeDefinition result = new TypeDefinition(null, "PrototypeClass",
                TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.BeforeFieldInit | TypeAttributes.SequentialLayout,
                type.Module.Import(typeof(ValueType)));

            result.ImportGenericParams(type);
            type.NestedTypes.Add(result);
            result.DeclaringType = type;
            return result;
        }
Esempio n. 2
0
        private static TypeDefinition CreateDeligateType(MethodDefinition method)
        {
            string deligateName = "Callback_" + ComposeFullMethodName(method);
            var parentType = method.DeclaringType.NestedTypes.Single(m => m.Name == "PrototypeClass");

            TypeReference multicastDeligateType = parentType.Module.Import(typeof(MulticastDelegate));
            TypeReference voidType = parentType.Module.Import(typeof(void));
            TypeReference objectType = parentType.Module.Import(typeof(object));
            TypeReference intPtrType = parentType.Module.Import(typeof(IntPtr));

            TypeDefinition result = new TypeDefinition(null, deligateName,
                TypeAttributes.Sealed | TypeAttributes.NestedPublic | TypeAttributes.RTSpecialName, multicastDeligateType);

            result.ImportGenericParams(parentType);
            if (method.HasGenericParameters)
                result.ImportGenericParams(method);

            //create constructor
            var constructor = new MethodDefinition(".ctor",
                                                   MethodAttributes.Public | MethodAttributes.CompilerControlled |
                                                   MethodAttributes.RTSpecialName | MethodAttributes.SpecialName |
                                                   MethodAttributes.HideBySig, voidType);
            constructor.Parameters.Add(new ParameterDefinition("object", ParameterAttributes.None, objectType));
            constructor.Parameters.Add(new ParameterDefinition("method", ParameterAttributes.None, intPtrType));
            constructor.IsRuntime = true;
            result.Methods.Add(constructor);

            //not a good solution, but it don't work any other way
            var ret = method.ReturnType;
            if (method.ReturnType.IsGenericParameter && method.GenericParameters.SingleOrDefault(m=>m.Name==method.ReturnType.Name)!=null)
                ret = result.GenericParameters.SingleOrDefault(m => m.Name == method.ReturnType.Name);

            //create Invoke
            var invoke = new MethodDefinition("Invoke",
                                              MethodAttributes.Public | MethodAttributes.HideBySig |
                                              MethodAttributes.NewSlot | MethodAttributes.Virtual, ret);

            invoke.IsRuntime = true;
            if (!method.IsStatic)
            {
                invoke.Parameters.Add(new ParameterDefinition("self", ParameterAttributes.None, method.DeclaringType.Instance()));
            }

            foreach (var param in method.Parameters)
            {
                //thanks to cecil - it can't resolve param type properly.
                //TODO: prettify/eliminate that hack
                var type = result.GenericParameters.FirstOrDefault(m => m.Name == param.ParameterType.Name.Replace("&",""));

                if(type==null)
                    invoke.Parameters.Add(new ParameterDefinition(param.Name, param.Attributes, param.ParameterType));
                else
                    invoke.Parameters.Add(new ParameterDefinition(param.Name, param.Attributes, type));
            }

            result.Methods.Add(invoke);

            //the rest of the process
            result.DeclaringType = parentType;
            parentType.NestedTypes.Add(result);
            return result;
        }