예제 #1
0
        protected override void OnDefineType()
        {
            TypeInfo typeInfo = RefNonAliasedTypeInfo;

            m_typeBuilder = ConvCommon.DefineTypeHelper(
                m_info,
                RefTypeInfo,
                RefNonAliasedTypeInfo,
                TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.ExplicitLayout,
                typeof(ValueType),
                ConvType.Union
                );

            // Handle [TypeLibType(...)] if evaluate to non-0
            using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr())
            {
                if (refTypeAttr.wTypeFlags != 0)
                {
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags));
                }
            }

            m_info.AddToSymbolTable(RefTypeInfo, ConvType.Union, this);
            m_info.RegisterType(m_typeBuilder, this);
        }
예제 #2
0
        protected override void OnDefineType()
        {
            TypeInfo typeInfo = RefNonAliasedTypeInfo;

            // Creates the enum type
            m_typeBuilder = ConvCommon.DefineTypeHelper(
                m_info,
                RefTypeInfo,
                RefNonAliasedTypeInfo,
                TypeAttributes.Public | TypeAttributes.Sealed,
                typeof(Enum),
                ConvType.Enum
                );

            // The field must be created here so that TypeBuilder can calculate a hash...
            // Need to create a special field to hold the enum data
            FieldBuilder field = m_typeBuilder.DefineField(
                "value__",
                typeof(Int32),
                FieldAttributes.Public | FieldAttributes.SpecialName);

            // Handle [TypeLibType(...)] if evaluate to non-0
            using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr())
            {
                if (refTypeAttr.wTypeFlags != 0)
                {
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags));
                }
            }

            m_info.AddToSymbolTable(RefTypeInfo, ConvType.Enum, this);
            m_info.RegisterType(m_typeBuilder, this);
        }
예제 #3
0
        protected override void OnDefineType()
        {
            TypeInfo typeInfo = RefNonAliasedTypeInfo;

            using (TypeAttr typeAttr = typeInfo.GetTypeAttr())
            {
                string name = m_info.GetUniqueManagedName(RefTypeInfo, ConvType.Module);

                // Create the managed type for the module
                // It should be abstract & sealed, which is the same as a static class in C#
                // Also, reflection will create a default constructor for you if the class has no constructor,
                // except if the class is interface, valuetype, enum, or a static class, so this works pretty well
                // except that this is slightly different than tlbimpv1, as tlbimpv1 the class is not sealed
                m_typeBuilder = m_info.ModuleBuilder.DefineType(name,
                                                                TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed,
                                                                typeof(Object));

                // Handle [Guid(...)] custom attribute
                ConvCommon.DefineGuid(RefTypeInfo, RefNonAliasedTypeInfo, m_typeBuilder);

                // Handle [TypeLibType(...)] if evaluate to non-0
                using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr())
                {
                    if (refTypeAttr.wTypeFlags != 0)
                    {
                        m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags));
                    }
                }
            }

            // Add to symbol table automatically
            m_info.AddToSymbolTable(RefTypeInfo, ConvType.Module, this);

            // Register type
            m_info.RegisterType(m_typeBuilder, this);
        }
예제 #4
0
        protected override void OnDefineType()
        {
            TypeInfo typeInfo = RefNonAliasedTypeInfo;

            using (TypeAttr attr = typeInfo.GetTypeAttr())
            {
                string name = m_info.GetUniqueManagedName(RefTypeInfo, ConvType.CoClass);

                //
                // Collect information for a list of interfaces & event interface types
                //
                List <Type> intfList                 = new List <Type>(); // interface list
                List <Type> eventIntfList            = new List <Type>(); // event interface list
                TypeInfo    defaultInterfaceTypeInfo = null;

                int nCount = attr.cImplTypes;

                string sourceInterfaceNames  = String.Empty;
                bool   hasDefaultInterface   = false;
                bool   implementsIEnumerable = ConvCommon.ExplicitlyImplementsIEnumerable(typeInfo, attr);

                for (int n = 0; n < nCount; ++n)
                {
                    IMPLTYPEFLAGS flags     = typeInfo.GetImplTypeFlags(n);
                    bool          isDefault = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0;
                    bool          isSource  = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0;

                    TypeInfo typeImpl = typeInfo.GetRefType(n);

                    using (TypeAttr attrImpl = typeImpl.GetTypeAttr())
                    {
                        // Skip IUnknown & IDispatch
                        if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown)
                        {
                            continue;
                        }

                        // Skip non-dispatch interfaces that doesn't derive from IUnknown
                        if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl))
                        {
                            continue;
                        }

                        IConvInterface convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, typeImpl);

                        // For source interfaces, try create the event interface
                        // Could be already created if it is the default source interface
                        if (isSource)
                        {
                            convInterface.DefineEventInterface();
                        }

                        // Use the RealManagedType (avoid getting the class interface)
                        Type typeRef = convInterface.RealManagedType;

                        // Append the source interface name to the list for the ComSourceInterfacesAttribute
                        if (isSource)
                        {
                            string interfaceName;
                            if (convInterface.ConvScope == ConvScope.External)
                            {
                                interfaceName = typeRef.AssemblyQualifiedName + "\0";
                            }
                            else
                            {
                                interfaceName = typeRef.FullName + "\0";
                            }

                            // Insert default source interface to the beginning
                            if (isDefault)
                            {
                                sourceInterfaceNames = interfaceName + sourceInterfaceNames;
                            }
                            else
                            {
                                sourceInterfaceNames = sourceInterfaceNames + interfaceName;
                            }
                        }

                        if (isDefault)
                        {
                            // Add the real interface first
                            if (isSource)
                            {
                                // For source interface, use the event interface instead
                                // Insert to the beginning
                                eventIntfList.Insert(0, convInterface.EventInterface.ManagedType);
                            }
                            else
                            {
                                m_defaultInterface = convInterface;

                                // Insert to the beginning
                                intfList.Insert(0, typeRef);
                                hasDefaultInterface      = true;
                                defaultInterfaceTypeInfo = typeImpl;
                            }
                        }
                        else
                        {
                            if (isSource)
                            {
                                // For source interface, add the event interface instead
                                eventIntfList.Add(convInterface.EventInterface.ManagedType);
                            }
                            else
                            {
                                if (m_defaultInterface == null)
                                {
                                    m_defaultInterface       = convInterface;
                                    defaultInterfaceTypeInfo = typeImpl;
                                }

                                intfList.Add(typeRef);
                            }
                        }
                    }
                }

                //
                // Get class interface
                //
                m_classInterface = m_info.GetTypeRef(ConvType.ClassInterface, RefTypeInfo) as IConvClassInterface;
                if (m_classInterface == null)
                {
                    throw new TlbImpInvalidTypeConversionException(RefTypeInfo);
                }

                //
                // Build implemented type list in a specific order
                //
                List <Type> implTypeList = new List <Type>();
                if (hasDefaultInterface)
                {
                    implTypeList.Add(intfList[0]);
                    intfList.RemoveAt(0);

                    implTypeList.Add(m_classInterface.ManagedType);
                }
                else
                {
                    implTypeList.Add(m_classInterface.ManagedType);
                    if (intfList.Count > 0)
                    {
                        implTypeList.Add(intfList[0]);
                        intfList.RemoveAt(0);
                    }
                }

                if (eventIntfList.Count > 0)
                {
                    implTypeList.Add(eventIntfList[0]);
                    eventIntfList.RemoveAt(0);
                }

                implTypeList.AddRange(intfList);
                implTypeList.AddRange(eventIntfList);

                // Check to see if the default interface has a member with a DISPID of DISPID_NEWENUM.
                if (defaultInterfaceTypeInfo != null)
                {
                    if (!implementsIEnumerable && ConvCommon.HasNewEnumMember(m_info, defaultInterfaceTypeInfo))
                    {
                        implTypeList.Add(typeof(System.Collections.IEnumerable));
                    }
                }

                // Check to see if the IEnumerable Custom Value exists on the CoClass if doesn't inherit from IEnumerable yet
                if (!implTypeList.Contains(typeof(System.Collections.IEnumerable)))
                {
                    if (ConvCommon.HasForceIEnumerableCustomAttribute(typeInfo))
                    {
                        implTypeList.Add(typeof(System.Collections.IEnumerable));
                    }
                }

                // Define the type
                m_typeBuilder = m_info.ModuleBuilder.DefineType(name,
                                                                TypeAttributes.Public | TypeAttributes.Import,
                                                                typeof(Object),
                                                                implTypeList.ToArray());

                // Handle [Guid(...)] custom attribute
                ConvCommon.DefineGuid(RefTypeInfo, RefNonAliasedTypeInfo, m_typeBuilder);

                // Handle [ClassInterface(ClassInterfaceType.None)]
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForClassInterface(ClassInterfaceType.None));

                // Handle [TypeLibType(...)] if evaluate to non-0
                using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr())
                {
                    if (refTypeAttr.wTypeFlags != 0)
                    {
                        m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags));
                    }
                }

                // Handle [ComSourceInterfacesAttribute]
                if (sourceInterfaceNames != String.Empty)
                {
                    sourceInterfaceNames += "\0";
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComSourceInterfaces(sourceInterfaceNames));
                }

                // Add to symbol table automatically
                m_info.AddToSymbolTable(RefTypeInfo, ConvType.CoClass, this);

                // Register type
                m_info.RegisterType(m_typeBuilder, this);
            }
        }
예제 #5
0
        /// <summary>
        /// Create the event interface
        /// </summary>
        public override void OnCreate()
        {
            if (m_type != null)
            {
                return;
            }

            string name = m_convInterface.ManagedName;

            m_convInterface.Create();

            using (TypeAttr attr = m_convInterface.RefTypeInfo.GetTypeAttr())
            {
                //
                // Emit attributes
                //

                //
                // Emit [ComEventInterfaceAttribute(...)]
                //
                ConstructorInfo ctorComEventInterface = typeof(ComEventInterfaceAttribute).GetConstructor(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                    null,
                    new Type[] { typeof(Type), typeof(Type) },
                    null);

                //
                // Build the blob manually before creating the event interface / provider types.
                // We only need to give the name of the types, in order to simplify creation logic and avoid dependency
                //
                CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder();

                string eventInterfaceFullyQualifiedName = name;
                if (m_convInterface.ConvScope == ConvScope.External)
                {
                    eventInterfaceFullyQualifiedName = m_convInterface.ManagedType.AssemblyQualifiedName;
                }

                blobBuilder.AddFixedArg(eventInterfaceFullyQualifiedName);                      // source interface

                // Handle event provider name generation collision scenario
                m_eventProviderName = m_info.GetUniqueManagedName(
                    m_info.GetRecommendedManagedName(m_convInterface.RefTypeInfo, ConvType.Interface, true) + "_EventProvider");

                blobBuilder.AddFixedArg(m_eventProviderName);   // corresponding event provider
                m_typeBuilder.SetCustomAttribute(ctorComEventInterface, blobBuilder.GetBlob());

                //
                // Emit ComVisibleAttribute(false)
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComVisible(false));

                //
                // Emit TypeLibTypeAttribute for TYPEFLAG_FHIDDEN
                //
                m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType(TypeLibTypeFlags.FHidden));

                bool isConversionLoss = false;

                //
                // Verify if the type has any properties
                //
                Type interfaceType = m_convInterface.RealManagedType;
                if (interfaceType.GetProperties().Length > 0)
                {
                    // Emit a warning and we'll skip the properties
                    m_info.ReportEvent(
                        WarningCode.Wrn_NoPropsInEvents,
                        Resource.FormatString("Wrn_NoPropsInEvents", RefTypeInfo.GetDocumentation()));

                    isConversionLoss = true;
                }

                //
                // Create event interface
                //

                InterfaceInfo eventInterfaceInfo = new InterfaceInfo(m_info, m_typeBuilder, false, m_convInterface.RefTypeInfo, attr, false, true);

                ConvCommon.CreateEventInterfaceCommon(eventInterfaceInfo);
                isConversionLoss |= eventInterfaceInfo.IsConversionLoss;

                //
                // Emit ComConversionLossAttribute if necessary
                //
                if (eventInterfaceInfo.IsConversionLoss)
                {
                    m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss());
                }
            }

            m_type = m_typeBuilder.CreateType();
        }