Ejemplo n.º 1
0
        /// <summary>
        /// If the type is aliased, return the ultimated non-aliased type if the type is user-defined, otherwise, return
        /// the aliased type directly. So the result could still be aliased to a built-in type.
        /// If the type is not aliased, just return the type directly
        /// </summary>
        public static void ResolveAlias(TypeInfo type, TypeDesc typeDesc, out TypeInfo realType, out TypeAttr realAttr)
        {
            if (type == null) throw new ArgumentNullException(nameof(type));
            if (typeDesc == null) throw new ArgumentNullException(nameof(typeDesc));
            if ((VarEnum)typeDesc.vt != VarEnum.VT_USERDEFINED)
            {
                // Already resolved
                realType = type;
                realAttr = type.GetTypeAttr();
                return;
            }
            else
            {
                TypeInfo refType = type.GetRefTypeInfo(typeDesc.hreftype);
                TypeAttr refAttr = refType.GetTypeAttr();

                // If the userdefined typeinfo is not itself an alias, then it is what the alias aliases.
                // Also, if the userdefined typeinfo is an alias to a builtin type, then the builtin
                // type is what the alias aliases.
                if (refAttr.typekind != TypeLibTypes.Interop.TYPEKIND.TKIND_ALIAS || (VarEnum)refAttr.tdescAlias.vt != VarEnum.VT_USERDEFINED)
                {
                    // Resolved
                    realType = refType;
                    realAttr = refAttr;
                }
                else
                {
                    // Continue resolving the type
                    ResolveAlias(refType, refAttr.tdescAlias, out realType, out realAttr);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This function is used to workaround around the fact that the TypeInfo might return IUnknown/IDispatch methods (in the case of dual interfaces)
        /// So we should always call this function to get the first index for different TypeInfo and never save the id
        /// </summary>
        public static int GetIndexOfFirstMethod(TypeInfo type, TypeAttr attr)
        {
            if (type == null) throw new ArgumentNullException(nameof(type));
            if (attr == null) throw new ArgumentNullException(nameof(attr));
            if (attr.typekind != TypeLibTypes.Interop.TYPEKIND.TKIND_DISPATCH) return 0;

            int nIndex = 0;
            if (attr.cFuncs >= 3)
            {
                // Check for IUnknown first
                using (FuncDesc func = type.GetFuncDesc(0))
                {
                    if (func.memid == 0x60000000 &&
                       func.elemdescFunc.tdesc.vt == (int)VarEnum.VT_VOID &&
                       func.cParams == 2 &&
                       func.GetElemDesc(0).tdesc.vt == (int)VarEnum.VT_PTR &&
                       func.GetElemDesc(1).tdesc.vt == (int)VarEnum.VT_PTR &&
                       "QueryInterface" == type.GetDocumentation(func.memid))
                    {
                        nIndex = 3;
                    }
                }

                if (attr.cFuncs >= 7)
                {
                    using (FuncDesc func = type.GetFuncDesc(3))
                    {
                        // Check IDispatch
                        if (func.memid == 0x60010000 &&
                            func.elemdescFunc.tdesc.vt == (int)VarEnum.VT_VOID &&
                            func.cParams == 1 &&
                            func.GetElemDesc(0).tdesc.vt == (int)VarEnum.VT_PTR &&
                            "GetTypeInfoCount" == type.GetDocumentation(func.memid))
                        {
                            nIndex = 7;
                        }
                    }
                }
            }
            return nIndex;
        }
Ejemplo n.º 3
0
        private void CreateField(TypeInfo type, TypeAttr attr, VarDesc var, ref bool isConversionLoss)
        {
            TypeDesc fieldTypeDesc = var.elemdescVar.tdesc;
            TypeConverter typeConverter = new TypeConverter(m_info, type, fieldTypeDesc, ConversionType.Field);
            Type fieldType = typeConverter.ConvertedType;
            string fieldName = type.GetDocumentation(var.memid);
            FieldBuilder field = m_typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Public);
            typeConverter.ApplyAttributes(field);

            isConversionLoss |= typeConverter.IsConversionLoss;

            //
            // Emit ComConversionLossAttribute for fields if necessary
            //
            if (typeConverter.IsConversionLoss)
            {
                field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss());

                //
                // Emit Wrn_UnconvertableField warning
                //
                m_info.ReportEvent(
                    WarningCode.Wrn_UnconvertableField,
                    Resource.FormatString("Wrn_UnconvertableField", m_typeBuilder.FullName, fieldName));
            }

            //
            // Emit TypeLibVarAttribute if necessary
            //
            if (var.wVarFlags != 0)
            {
                field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibVar((TypeLibVarFlags)var.wVarFlags));
            }
        }
Ejemplo n.º 4
0
        private void CreateField(TypeInfo type, TypeAttr attr, VarDesc var, ref bool isConversionLoss)
        {
            if (IsObjectType(type, var.elemdescVar.tdesc))
            {
                isConversionLoss = true;
            }
            else
            {

                TypeConverter typeConverter = new TypeConverter(m_info, type, var.elemdescVar.tdesc, ConversionType.Field);
                Type fieldType = typeConverter.ConvertedType;

                // TlbImp2 will only skip reference types, instead of skipping every field
                // Also, TlbImp1 will skip ValueType *, which doesn't make any sense. TlbImp2 will keep ValueType * as IntPtr

                string fieldName = type.GetDocumentation(var.memid);
                // Generates the [FieldOffset(0)] layout declarations that approximate unions in managed code
                FieldBuilder field = m_typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Public);
                field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForFieldOffset(0));
                typeConverter.ApplyAttributes(field);

                isConversionLoss |= typeConverter.IsConversionLoss;

                //
                // Emit ComConversionLossAttribute for fields if necessary
                //
                if (typeConverter.IsConversionLoss)
                {
                    field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss());

                    //
                    // Emit Wrn_UnconvertableField warning
                    //
                    m_info.ReportEvent(
                        WarningCode.Wrn_UnconvertableField,
                        Resource.FormatString("Wrn_UnconvertableField", m_typeBuilder.FullName, fieldName));
                }
            }
        }
Ejemplo n.º 5
0
 public InterfaceInfo(ConverterInfo info, TypeBuilder typeBuilder, bool supportsDispatch, TypeInfo type, TypeAttr attr, bool bCoClass)
 {
     Init(info, typeBuilder, supportsDispatch, type, attr, bCoClass, false, null);
 }
Ejemplo n.º 6
0
 public InterfaceInfo(ConverterInfo info, TypeBuilder typeBuilder, bool supportsDispatch, TypeInfo type, TypeAttr attr, bool bCoClass, bool bSource, TypeInfo implementingInterface)
 {
     Init(info, typeBuilder, supportsDispatch, type, attr, bCoClass, bSource, implementingInterface);
 }
Ejemplo n.º 7
0
        private void Init(ConverterInfo info, TypeBuilder typeBuilder, bool emitDispId, TypeInfo type, TypeAttr attr, bool bCoClass, bool bSource, TypeInfo implementingInterface)
        {
            m_typeStack = new Stack<TypeInfo>();

            m_attrStack = new Stack<TypeAttr>();
            PushType(type, attr);

            m_info = info;
            m_typeBuilder = typeBuilder;
            m_emitDispId = emitDispId;
            m_bCoClass = bCoClass;
            m_propertyInfo = new PropertyInfo(this);
            m_bSource = bSource;
            IsConversionLoss = false;
            IsDefaultInterface = false;
            m_currentSlot = 0;
            m_currentImplementingInterface = implementingInterface;
        }
Ejemplo n.º 8
0
 public void PushType(TypeInfo type, TypeAttr attr)
 {
     m_typeStack.Push(type);
     m_attrStack.Push(attr);
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Is this interface explicitly derives from IEnumerable (from mscorlib.tlb)?
        /// </summary>
        /// <param name="lookupPartner">Whether we look at the partner interface</param>
        public static bool ExplicitlyImplementsIEnumerable(TypeInfo typeInfo, TypeAttr typeAttr, bool lookupPartner)
        {
            // Look through each of the implemented/inherited interfaces
            for (int i = 0; i < typeAttr.cImplTypes; ++i)
            {
                TypeInfo interfaceTypeInfo = typeInfo.GetRefType(i);

                using (TypeAttr interfaceTypeAttr = interfaceTypeInfo.GetTypeAttr())
                {
                    if ((typeInfo.GetImplTypeFlags(i) & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) == 0)
                    {
                        if (interfaceTypeAttr.Guid == WellKnownGuids.IID_IEnumerable)
                            return true;
                        if (ExplicitlyImplementsIEnumerable(interfaceTypeInfo, interfaceTypeAttr))
                            return true;
                    }
                }
            }

            if (lookupPartner)
            {
                TypeInfo partnerTypeInfo = typeInfo.GetRefTypeNoComThrow();
                if (partnerTypeInfo != null)
                {
                    using (TypeAttr partnerTypeAttr = partnerTypeInfo.GetTypeAttr())
                    {
                        if (partnerTypeAttr.Guid == WellKnownGuids.IID_IEnumerable)
                            return true;

                        if (ExplicitlyImplementsIEnumerable(partnerTypeInfo, partnerTypeAttr, false))
                            return true;
                    }
                }
            }

            return false;
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Is this interface explicitly derives from IEnumerable (from mscorlib.tlb)?
 /// </summary>
 public static bool ExplicitlyImplementsIEnumerable(TypeInfo typeInfo, TypeAttr typeAttr)
 {
     return ExplicitlyImplementsIEnumerable(typeInfo, typeAttr, true);
 }
Ejemplo n.º 11
0
 public static bool InterfaceSupportsDispatch(TypeInfo typeInfo, TypeAttr attr)
 {
     return attr.IsDual || attr.typekind == TypeLibTypes.Interop.TYPEKIND.TKIND_DISPATCH;
 }