public void AddOtherMethod_NullMethodBuilder_ThrowsArgumentNullExceptio()
        {
            TypeBuilder     type     = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public);
            PropertyBuilder property = type.DefineProperty("TestProperty", PropertyAttributes.None, typeof(int), new Type[0]);

            AssertExtensions.Throws <ArgumentNullException>("mdBuilder", () => property.AddOtherMethod(null));
        }
        public void GetValue_ThrowsNotSupportedException()
        {
            TypeBuilder     type     = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public);
            PropertyBuilder property = type.DefineProperty("TestProperty", PropertyAttributes.None, typeof(int), null);
            MethodBuilder   method   = type.DefineMethod("TestMethod", MethodAttributes.Public, CallingConventions.HasThis, typeof(int), null);

            ILGenerator methodILGenerator = method.GetILGenerator();

            methodILGenerator.Emit(OpCodes.Ldarg_0);
            methodILGenerator.Emit(OpCodes.Ret);
            property.AddOtherMethod(method);

            type.CreateType();
            Assert.Throws <NotSupportedException>(() => property.GetValue(null, null));
        }
        public void AddOtherMethod_TypeAlreadyCreated_ThrowsInvalidOperationException()
        {
            Type[] paramTypes = new Type[] { typeof(int) };

            TypeBuilder     type              = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public);
            PropertyBuilder property          = type.DefineProperty("TestProperty", PropertyAttributes.None, typeof(int), new Type[0]);
            MethodBuilder   method            = type.DefineMethod("TestMethod", MethodAttributes.Public, CallingConventions.HasThis, typeof(int), paramTypes);
            ILGenerator     methodILGenerator = method.GetILGenerator();

            methodILGenerator.Emit(OpCodes.Ldarg_0);
            methodILGenerator.Emit(OpCodes.Ldarg_1);
            methodILGenerator.Emit(OpCodes.Ret);

            type.CreateTypeInfo().AsType();
            Assert.Throws <InvalidOperationException>(() => property.AddOtherMethod(method));
        }
        public void AddOtherMethod(MethodAttributes attributes, CallingConventions callingConventions, BindingFlags bindingFlags)
        {
            Type[] paramTypes = new Type[] { typeof(int) };

            TypeBuilder     type     = Helpers.DynamicType(TypeAttributes.Class | TypeAttributes.Public);
            PropertyBuilder property = type.DefineProperty("TestProperty", PropertyAttributes.None, typeof(int), new Type[0]);
            MethodBuilder   method   = type.DefineMethod("TestMethod", attributes, callingConventions, typeof(int), paramTypes);

            ILGenerator methodILGenerator = method.GetILGenerator();

            methodILGenerator.Emit(OpCodes.Ldarg_0);
            methodILGenerator.Emit(OpCodes.Ldarg_1);
            methodILGenerator.Emit(OpCodes.Ret);

            property.AddOtherMethod(method);
            Type         createdType     = type.CreateTypeInfo().AsType();
            PropertyInfo createdProperty = createdType.GetProperty("TestProperty", bindingFlags);

            MethodInfo[] actualMethods = createdProperty.GetAccessors(true);
            Assert.Equal(1, actualMethods.Length);
            Assert.Equal(method.Name, actualMethods[0].Name);
        }
Exemple #5
0
        /// <summary>
        /// Generate properties for Functions
        /// </summary>
        public void GenerateProperty(InterfaceInfo info, TypeBuilder typebuilder)
        {
            // Generate property using unique name
            string uniqueName = info.GenerateUniqueMemberName(
                m_propertyInfo.RecommendedName,
                null,
                MemberTypes.Property);

            //
            // Convert the signature
            //
            Type[] paramTypes = null;
            Type   retType    = null;

            if (m_propertyInfo.Kind == PropertyKind.VarProperty)
            {
                // Converting variable to property. There are no parameters at all
                TypeConverter typeConverter = m_propertyInfo.GetPropertyTypeConverter(info.ConverterInfo, info.RefTypeInfo);
                info.IsConversionLoss |= typeConverter.IsConversionLoss;
                retType = typeConverter.ConvertedType;
            }
            else
            {
                // If /preservesig is specified, do not generate property, and only
                // the getter and setter functions are enough.
                // Property requires that the property getter must return the real property value, and the first parameter of
                // the setter must be the property value. While, the /preservesig switch will change the prototype of the setters and
                // getters, which is different from what the compiler expected.
                // So we do not support the Property if the /preservesig is specified.
                if (info.ConverterInfo.Settings.m_isPreserveSig &&
                    (m_propertyInfo.BestFuncDesc != null && !m_propertyInfo.BestFuncDesc.IsDispatch))
                {
                    if (TlbImpCode.TlbImpCode.s_Options.m_bVerboseMode)
                    {
                        FormattedOutput.Output.WriteInfo(Resource.FormatString("Msg_PropertyIsOmitted",
                                                                               m_propertyInfo.RecommendedName,
                                                                               m_propertyInfo.RefTypeInfo.GetDocumentation()),
                                                         MessageCode.Msg_PropertyIsOmitted);
                    }
                    return;
                }

                // Converting propget/propput/propputref functions to property.
                TypeConverter typeConverter = m_propertyInfo.GetPropertyTypeConverter(info.ConverterInfo, info.RefTypeInfo);
                retType = typeConverter.ConvertedType;
                info.IsConversionLoss |= typeConverter.IsConversionLoss;

                FuncDesc bestFuncDesc = m_propertyInfo.BestFuncDesc;

                // if we have a [vararg]
                int varArg, firstOptArg, lastOptArg;

                if (bestFuncDesc.cParamsOpt == -1)
                {
                    ConvCommon.CheckForOptionalArguments(info.ConverterInfo, bestFuncDesc, out varArg, out firstOptArg, out lastOptArg);
                }
                else
                {
                    varArg = -1;
                }

                List <Type> paramTypeList = new List <Type>();

                // Find the index part of the property's signature
                bool skipLastRetVal = (bestFuncDesc.IsPropertyPut || bestFuncDesc.IsPropertyPutRef);
                for (int i = 0; i < bestFuncDesc.cParams; ++i)
                {
                    ElemDesc  elemDesc  = bestFuncDesc.GetElemDesc(i);
                    ParamDesc paramDesc = elemDesc.paramdesc;

                    // Skip LCID/RetVal
                    if (paramDesc.IsLCID || paramDesc.IsRetval)
                    {
                        continue;
                    }

                    // Skip the "new value" parameter for putters
                    if (skipLastRetVal)
                    {
                        skipLastRetVal = false;
                        continue;
                    }

                    ConversionType conversionType;
                    if (i == varArg)
                    {
                        conversionType = ConversionType.VarArgParameter;
                    }
                    else
                    {
                        conversionType = ConversionType.Parameter;
                    }

                    TypeConverter paramTypeConverter = new TypeConverter(info.ConverterInfo, info.RefTypeInfo, elemDesc.tdesc, conversionType);
                    info.IsConversionLoss |= paramTypeConverter.IsConversionLoss;
                    paramTypeList.Add(paramTypeConverter.ConvertedType);
                }

                paramTypes = paramTypeList.ToArray();
            }

            // Define the property
            PropertyBuilder propertyBuilder = typebuilder.DefineProperty(uniqueName, PropertyAttributes.HasDefault, retType, paramTypes);

            if (info.IsCoClass && !info.IsDefaultInterface)
            {
                // Skip non-default interfaces / implemented interfaces (when we are creating coclass)
            }
            else
            {
                // Emit dispatch id attribute
                propertyBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForDispId(m_propertyInfo.DispId));
            }

            // We don't need to emit MarshalAs for properties because the get/set functions should already have them
            // Emitting MarshalAs for property will hang up CLR!!
            if (m_methodGet != null)
            {
                propertyBuilder.SetGetMethod(m_methodGet);
            }

            // Has both propPut & propPutRef?
            if (m_methodPut != null && m_methodPutRef != null)
            {
                propertyBuilder.SetSetMethod(m_methodPutRef);
                propertyBuilder.AddOtherMethod(m_methodPut);
            }
            else
            {
                if (m_methodPut != null)
                {
                    propertyBuilder.SetSetMethod(m_methodPut);
                }
                else if (m_methodPutRef != null)
                {
                    propertyBuilder.SetSetMethod(m_methodPutRef);
                }
            }

            //
            // Handle DefaultMemberAttribute
            //
            if (m_propertyInfo.DispId == WellKnownDispId.DISPID_VALUE)
            {
                // DIFF: TlbImpv1 use the type library name while we use the unique name
                info.ConverterInfo.SetDefaultMember(info.TypeBuilder, uniqueName);
            }

            // Handle alias information
            ConvCommon.HandleAlias(info.ConverterInfo, info.RefTypeInfo, m_propertyInfo.PropertyTypeDesc, propertyBuilder);
        }
    // Create the callee transient dynamic assembly.
    private static Type CreateCallee(AppDomain myAppDomain, AssemblyBuilderAccess access)
    {
        // Create a simple name for the callee assembly.
        AssemblyName myAssemblyName = new AssemblyName();

        myAssemblyName.Name = "EmittedAssembly";
        // Create the callee dynamic assembly.
        AssemblyBuilder myAssemblyBuilder =
            myAppDomain.DefineDynamicAssembly(myAssemblyName, access);
        // Create a dynamic module named "EmittedModule" in the callee assembly.
        ModuleBuilder myModule;

        if (access == AssemblyBuilderAccess.Run)
        {
            myModule = myAssemblyBuilder.DefineDynamicModule("EmittedModule");
        }
        else
        {
            myModule = myAssemblyBuilder.DefineDynamicModule("EmittedModule", "EmittedModule.mod");
        }
// <Snippet2>
        // Define a public class named "HelloWorld" in the assembly.
        TypeBuilder helloWorldTypeBuilder = myModule.DefineType("HelloWorld", TypeAttributes.Public);
        // Define a private String field named "m_greeting" in "HelloWorld" class.
        FieldBuilder greetingFieldBuilder = helloWorldTypeBuilder.DefineField("m_greeting",
                                                                              typeof(String), FieldAttributes.Private);

        // Create constructor args and define constructor.
        Type[]             constructorArgs = { typeof(String) };
        ConstructorBuilder constructor     = helloWorldTypeBuilder.DefineConstructor(
            MethodAttributes.Public, CallingConventions.Standard, constructorArgs);

        // Generate IL code for the method. The constructor stores its argument in the private field.
        ILGenerator constructorIL = constructor.GetILGenerator();

        constructorIL.Emit(OpCodes.Ldarg_0);
        constructorIL.Emit(OpCodes.Ldarg_1);
        constructorIL.Emit(OpCodes.Stfld, greetingFieldBuilder);
        constructorIL.Emit(OpCodes.Ret);
// <Snippet1>
        // Define property Greeting.
        PropertyBuilder greetingPropertyBuilder = helloWorldTypeBuilder.DefineProperty(
            "Greeting", PropertyAttributes.None, typeof(string), null);

        // Define the 'get_Greeting' method.
        MethodBuilder getGreetingMethod = helloWorldTypeBuilder.DefineMethod("get_Greeting",
                                                                             MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName,
                                                                             typeof(String), null);
        // Generate IL code for 'get_Greeting' method.
        ILGenerator methodIL = getGreetingMethod.GetILGenerator();

        methodIL.Emit(OpCodes.Ldarg_0);
        methodIL.Emit(OpCodes.Ldfld, greetingFieldBuilder);
        methodIL.Emit(OpCodes.Ret);
        greetingPropertyBuilder.SetGetMethod(getGreetingMethod);
// </Snippet1>

        // Define the set_Greeting method.
        Type[]        methodArgs        = { typeof(string) };
        MethodBuilder setGreetingMethod = helloWorldTypeBuilder.DefineMethod("set_Greeting",
                                                                             MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName,
                                                                             typeof(void), methodArgs);

        // Generate IL code for set_Greeting method.
        methodIL = setGreetingMethod.GetILGenerator();
        methodIL.Emit(OpCodes.Ldarg_0);
        methodIL.Emit(OpCodes.Ldarg_1);
        methodIL.Emit(OpCodes.Stfld, greetingFieldBuilder);
        methodIL.Emit(OpCodes.Ret);
        greetingPropertyBuilder.SetSetMethod(setGreetingMethod);
// </Snippet2>
// <Snippet3>
        // Define the reset_Greeting method.
        MethodBuilder otherGreetingMethod = helloWorldTypeBuilder.DefineMethod("reset_Greeting",
                                                                               MethodAttributes.Public | MethodAttributes.HideBySig,
                                                                               typeof(void), null);

        // Generate IL code for reset_Greeting method.
        methodIL = otherGreetingMethod.GetILGenerator();
        methodIL.Emit(OpCodes.Ldarg_0);
        methodIL.Emit(OpCodes.Ldstr, "Default String.");
        methodIL.Emit(OpCodes.Stfld, greetingFieldBuilder);
        methodIL.Emit(OpCodes.Ret);
        greetingPropertyBuilder.AddOtherMethod(otherGreetingMethod);
// </Snippet3>
        // Create the class HelloWorld.
        return(helloWorldTypeBuilder.CreateType());
    }