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); }
/// <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()); }