예제 #1
0
        public static void VerifyConstructor(ConstructorBuilder constructor, TypeBuilder type, MethodAttributes attributes, Type[] parameterTypes)
        {
            string expectedName = (attributes & MethodAttributes.Static) != 0 ? ConstructorInfo.TypeConstructorName : ConstructorInfo.ConstructorName;

            Assert.Equal(expectedName, constructor.Name);
            Assert.Equal(attributes | MethodAttributes.SpecialName, constructor.Attributes);
            Assert.Equal(CallingConventions.Standard, constructor.CallingConvention);
            Assert.Equal(type.AsType(), constructor.DeclaringType);
            Assert.Equal(type.Module, constructor.Module);
            Assert.Equal(MethodImplAttributes.IL, constructor.MethodImplementationFlags);

            Assert.Throws <NotSupportedException>(() => constructor.Invoke(null));
            Assert.Throws <NotSupportedException>(() => constructor.Invoke(null, null));

            Type createdType = type.CreateTypeInfo().AsType();

            Assert.Equal(type.AsType().GetConstructors(AllFlags), createdType.GetConstructors(AllFlags));
            Assert.Equal(type.AsType().GetConstructor(parameterTypes), createdType.GetConstructor(parameterTypes));

            ConstructorInfo createdConstructor = createdType.GetConstructors(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                                 .Single(ctor => ctor.IsStatic == constructor.IsStatic);

            CallingConventions expectedCallingConvention = CallingConventions.Standard;

            if ((attributes & MethodAttributes.Static) == 0)
            {
                expectedCallingConvention |= CallingConventions.HasThis;
            }
            MethodAttributes expectedAttributes = attributes | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;

            expectedAttributes &= ~MethodAttributes.RequireSecObject;

            Assert.Equal(expectedName, constructor.Name);
            Assert.Equal(expectedAttributes, createdConstructor.Attributes);
            Assert.Equal(expectedCallingConvention, createdConstructor.CallingConvention);
            Assert.Equal(createdType, createdConstructor.DeclaringType);
            Assert.Equal(MethodImplAttributes.IL, constructor.MethodImplementationFlags);
        }
예제 #2
0
        void GenerateEquals(TypeBuilder tb, FieldInfo[] fields)
        {
            MethodBuilder mb = tb.DefineMethod("Equals",
                                               MethodAttributes.Public | MethodAttributes.ReuseSlot |
                                               MethodAttributes.Virtual | MethodAttributes.HideBySig,
                                               typeof(bool), new Type[] { typeof(object) });
            ILGenerator  gen   = mb.GetILGenerator();
            LocalBuilder other = gen.DeclareLocal(tb.AsType());
            Label        next  = gen.DefineLabel();

            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Isinst, tb.AsType());
            gen.Emit(OpCodes.Stloc, other);
            gen.Emit(OpCodes.Ldloc, other);
            gen.Emit(OpCodes.Brtrue_S, next);
            gen.Emit(OpCodes.Ldc_I4_0);
            gen.Emit(OpCodes.Ret);
            gen.MarkLabel(next);
            foreach (FieldInfo field in fields)
            {
                Type ft = field.FieldType;
                Type ct = typeof(EqualityComparer <>).MakeGenericType(ft);
                next = gen.DefineLabel();
                gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);
                gen.Emit(OpCodes.Ldarg_0);
                gen.Emit(OpCodes.Ldfld, field);
                gen.Emit(OpCodes.Ldloc, other);
                gen.Emit(OpCodes.Ldfld, field);
                gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", new Type[] { ft, ft }), null);
                gen.Emit(OpCodes.Brtrue_S, next);
                gen.Emit(OpCodes.Ldc_I4_0);
                gen.Emit(OpCodes.Ret);
                gen.MarkLabel(next);
            }
            gen.Emit(OpCodes.Ldc_I4_1);
            gen.Emit(OpCodes.Ret);
        }
예제 #3
0
        private static void VerifyMethod(TypeBuilder type, MethodBuilder method, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
        {
            CallingConventions expectedCallingConvention = callingConvention;

            if ((attributes & MethodAttributes.Static) == 0)
            {
                expectedCallingConvention |= CallingConventions.HasThis;
            }

            Assert.Equal(type.AsType(), method.DeclaringType);
            Assert.Equal(name, method.Name);
            Assert.Equal(attributes, method.Attributes);
            Assert.Equal(expectedCallingConvention, method.CallingConvention);
            Assert.Equal(returnType ?? typeof(void), method.ReturnType);
        }
        public void TestDeclaringTypeWithDifferentOverload()
        {
            AssemblyName an = new AssemblyName();

            an.Name = "DynamicRandomAssembly";
            AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);

            ModuleBuilder mb = TestLibrary.Utilities.GetModuleBuilder(ab, "Module1");
            TypeBuilder   tb = mb.DefineType("DynamicRandomClass", TypeAttributes.Public);

            Type[] parameterTypes = { typeof(int), typeof(double) };

            ConstructorBuilder cb =
                tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, parameterTypes);

            Assert.Equal(tb.AsType(), cb.DeclaringType);
        }
예제 #5
0
파일: Emit.cs 프로젝트: arlm/Sigil-vNext
        /// <summary>
        /// Creates a new Emit, suitable for building a constructor on the given TypeBuilder.
        ///
        /// The DelegateType and TypeBuilder must agree on parameter types and parameter counts.
        ///
        /// If you intend to use unveriable code, you must set allowUnverifiableCode to true.
        ///
        /// If doVerify is false (default is true) Sigil will *not* throw an exception on invalid IL.  This is faster, but the benefits
        /// of Sigil are reduced to "a nicer ILGenerator interface".
        ///
        /// If strictBranchValidation is true (default is false) Sigil will enforce "Backward branch constraints" which are *technically* required
        /// for valid CIL, but in practice often ignored.  The most common case to set this option is if you are generating types to write to disk.
        /// </summary>
        public static Emit BuildConstructor(Type[] parameterTypes, TypeBuilder type, MethodAttributes attributes, CallingConventions callingConvention = CallingConventions.HasThis, bool allowUnverifiableCode = false, bool doVerify = true, bool strictBranchVerification = false)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            Emit <NonGenericPlaceholderDelegate> .CheckAttributesAndConventions(attributes, callingConvention);

            if (!HasFlag(callingConvention, CallingConventions.HasThis))
            {
                throw new ArgumentException("Constructors always have a this reference");
            }

            ValidateReturnAndParameterTypes(type
#if NETSTANDARD
                                            .AsType()
#endif
                                            , parameterTypes);

            var passedParameters = parameterTypes;

            // Constructors always have a `this`
            var pList = new List <Type>(parameterTypes);
            pList.Insert(0, TypeHelpers.AsType(type));

            parameterTypes = pList.ToArray();

            var innerEmit = Emit <NonGenericPlaceholderDelegate> .MakeNonGenericEmit(callingConvention, typeof(void), parameterTypes, allowUnverifiableCode, doVerify, strictBranchVerification);

            innerEmit.ConstructorDefinedInType = TypeHelpers.AsType(type);

            var ret = new Emit(innerEmit, NonGenericEmitType.Constructor);
            ret.ReturnType        = TypeHelpers.AsType(type);
            ret.ParameterTypes    = passedParameters;
            ret.Attributes        = attributes;
            ret.CallingConvention = callingConvention;
            ret.TypeBuilder       = type;

            return(ret);
        }
        public void TestThrowsExceptionForTypeNotGeneric()
        {
            AssemblyName myAsmName =
                new AssemblyName("TypeBuilderGetMethodTest");
            AssemblyBuilder myAssembly = AssemblyBuilder.DefineDynamicAssembly(
                myAsmName, AssemblyBuilderAccess.Run);
            ModuleBuilder myModule = TestLibrary.Utilities.GetModuleBuilder(myAssembly, "Module1");

            TypeBuilder myType = myModule.DefineType("Sample",
                                                     TypeAttributes.Class | TypeAttributes.Public);

            ConstructorBuilder ctor = myType.DefineDefaultConstructor(
                MethodAttributes.PrivateScope | MethodAttributes.Public |
                MethodAttributes.HideBySig | MethodAttributes.SpecialName |
                MethodAttributes.RTSpecialName);

            Assert.Throws <ArgumentException>(() =>
            {
                ConstructorInfo ci = TypeBuilder.GetConstructor(myType.AsType(), ctor);
            });
        }
예제 #7
0
        public void TestDeclaringType()
        {
            AssemblyName    myAsmName  = new AssemblyName("GenericEmitExample1");
            AssemblyBuilder myAssembly = AssemblyBuilder.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
            ModuleBuilder   myModule   = TestLibrary.Utilities.GetModuleBuilder(myAssembly, myAsmName.Name);

            Type baseType = typeof(ExampleBase);

            TypeBuilder myType = myModule.DefineType("Sample", TypeAttributes.Public);

            string[] typeParamNames = { "TFirst" };
            GenericTypeParameterBuilder[] typeParams = myType.DefineGenericParameters(typeParamNames);

            GenericTypeParameterBuilder TFirst = typeParams[0];

            Type expectedValue = myType.AsType();
            Type actualValue;

            actualValue = TFirst.DeclaringType;

            Assert.Equal(expectedValue, actualValue);
        }
예제 #8
0
        public static IEnumerable <object[]> DeclaringType_TestData()
        {
            yield return(new object[] { s_type1, typeof(object), FieldAttributes.Public });

            yield return(new object[] { s_type1, typeof(int), FieldAttributes.Public });

            yield return(new object[] { s_type1, typeof(string), FieldAttributes.Public });

            yield return(new object[] { s_type1, typeof(FieldBuilderDeclaringType), FieldAttributes.Public });

            yield return(new object[] { s_type1, s_type1.AsType(), FieldAttributes.Public });

            yield return(new object[] { s_type2, typeof(object), FieldAttributes.Public });

            yield return(new object[] { s_type2, typeof(int), FieldAttributes.Public });

            yield return(new object[] { s_type2, typeof(string), FieldAttributes.Public });

            yield return(new object[] { s_type2, typeof(FieldBuilderDeclaringType), FieldAttributes.Public });

            yield return(new object[] { s_type2, s_type2.AsType(), FieldAttributes.Public });
        }
예제 #9
0
        public void DefineConstructor(MethodAttributes methodAttributes, Type[] parameterTypes, CallingConventions callingConvention, BindingFlags bindingFlags)
        {
            TypeBuilder type = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public);

            FieldBuilder fieldBuilderA = type.DefineField("TestField", typeof(int), FieldAttributes.Private);
            FieldBuilder fieldBuilderB = type.DefineField("TestField", typeof(int), FieldAttributes.Private);

            ConstructorBuilder ctorBuilder = type.DefineConstructor(methodAttributes, callingConvention, parameterTypes);

            Assert.Equal(type.Module, ctorBuilder.Module);
            Assert.Equal(type.AsType(), ctorBuilder.DeclaringType);
            Assert.Throws <NotSupportedException>(() => ctorBuilder.Invoke(null));
            Assert.Throws <NotSupportedException>(() => ctorBuilder.Invoke(null, null));

            ILGenerator ctorIlGenerator = ctorBuilder.GetILGenerator();

            if (parameterTypes.Length != 0)
            {
                //Calling base class constructor
                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Call, typeof(object).GetConstructor(new Type[0]));

                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Ldarg_1);
                ctorIlGenerator.Emit(OpCodes.Stfld, fieldBuilderA);

                ctorIlGenerator.Emit(OpCodes.Ldarg_0);
                ctorIlGenerator.Emit(OpCodes.Ldarg_2);
                ctorIlGenerator.Emit(OpCodes.Stfld, fieldBuilderB);
            }

            ctorIlGenerator.Emit(OpCodes.Ret);

            Type createdType = type.CreateTypeInfo().AsType();

            Assert.NotNull(createdType.GetConstructors(bindingFlags).FirstOrDefault());
        }
예제 #10
0
 public void DeclaringType(TypeBuilder type, Type fieldType, FieldAttributes attributes)
 {
     FieldBuilder field = type.DefineField(fieldType.ToString(), fieldType, attributes);
     Assert.Equal(type.AsType(), field.DeclaringType);
 }
예제 #11
0
        private static void VerifyMethod(TypeBuilder type, MethodBuilder method, string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
        {
            CallingConventions expectedCallingConvention = callingConvention;
            if ((attributes & MethodAttributes.Static) == 0)
            {
                expectedCallingConvention |= CallingConventions.HasThis;
            }

            Assert.Equal(type.AsType(), method.DeclaringType);
            Assert.Equal(name, method.Name);
            Assert.Equal(attributes, method.Attributes);
            Assert.Equal(expectedCallingConvention, method.CallingConvention);
            Assert.Equal(returnType, method.ReturnType);
        }