public TypeConverter(ConverterInfo info, TypeInfo type, TypeDesc desc, ParamDesc paramDesc, bool convertingNewEnumMember, ConversionType conversionType) { m_info = info; m_typeInfo = type; m_typeDesc = desc; m_paramDesc = paramDesc; m_conversionType = conversionType; m_attribute = null; m_conversionLoss = false; m_convertedType = null; m_nativeIndirections = 0; m_convertingNewEnumMember = convertingNewEnumMember; ResetUnmanagedType(); // Do the conversion _Convert(); }
/// <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); }