예제 #1
0
        // Get the immediate interfaces on this type.
        public TypeInfo[] GetInterfaces()
        {
            List <TypeInfo> interfaces = new List <TypeInfo>();

            if (HasReflectionType)
            {
                foreach (Type interfaceType in _reflectionType.GetInterfaces())
                {
                    interfaces.Add(new TypeInfo(interfaceType));
                }
            }
            else if (HasTypeRef)
            {
                TypeInfo defInfo = TypeRefToTypeDef(_mdToken, true);
                return(defInfo.GetInterfaces());
            }
            else
            {
                System.Diagnostics.Contracts.Contract.Assert(_mdToken.Table == MDTables.Tables.TypeDef);

                PEFileReader peFile  = _assembly.PEFileReader;
                MDTables     mdScope = peFile.MetaData;

                // Walk through all rows of the interface implementation table,
                // looking for this _mdToken.
                uint numRows = mdScope.RowsInTable(MDTables.Tables.InterfaceImpl);
                for (uint i = 0; i < numRows; i++)
                {
                    try
                    {
                        mdScope.SeekToRowOfTable(MDTables.Tables.InterfaceImpl, i);
                        uint typeDefRow = mdScope.ReadRowIndex(MDTables.Tables.TypeDef);
                        if (typeDefRow == _mdToken.Index)
                        {
                            MetadataToken interfaceToken = mdScope.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef);
                            interfaces.Add(TypeInfoFromTypeDefOrRef(interfaceToken));
                        }
                    }
                    catch (GenericsNotImplementedException)  // ignore interfaces such as IComparable<int> that aren't relevant to the addin model
                    {}
                }
            }
            return(interfaces.ToArray());
        }
예제 #2
0
        // Does a given typedef in the specified PE file implement the specified interface?
        private bool ImplementsHelper(PEFileReader peFile, MetadataToken typeDefToken, TypeInfo ifaceType)
        {
            System.Diagnostics.Contracts.Contract.Requires(typeDefToken.Table == MDTables.Tables.TypeDef);

            MDTables mdScope = peFile.MetaData;

            // Walk through all rules of the interface implementation table,
            // looking for this typeDefToken.  If we find it, check to see if
            // that row says this type implements the specified interface.
            // If not, continue walking the interface impl table.
            uint numRows = mdScope.RowsInTable(MDTables.Tables.InterfaceImpl);

            for (uint i = 0; i < numRows; i++)
            {
                mdScope.SeekToRowOfTable(MDTables.Tables.InterfaceImpl, i);
                uint typeDefRow = mdScope.ReadRowIndex(MDTables.Tables.TypeDef);
                if (typeDefRow == typeDefToken.Index)
                {
                    // if we implement it, return true.  Else continue.
                    MetadataToken interfaceToken = mdScope.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef);
                    if (ifaceType.HasName)
                    {
                        mdScope.SeekToMDToken(interfaceToken);
                        // Interface for IContract should be a typeref.
                        switch (interfaceToken.Table)
                        {
                        case MDTables.Tables.TypeRef:
                        {
                            MetadataToken resolutionScope = mdScope.ReadMetadataToken(MDTables.Encodings.ResolutionScope);
                            String        ifaceName       = mdScope.ReadString();
                            if (!String.Equals(ifaceName, ifaceType._typeName))
                            {
                                continue;
                            }
                            String ifaceNameSpace = mdScope.ReadString();
                            if (!String.Equals(ifaceNameSpace, ifaceType._nameSpace))
                            {
                                continue;
                            }
                            if (MiniAssembly.Equals(ifaceType.Assembly, peFile, resolutionScope))
                            {
                                return(true);
                            }
                            break;
                        }

                        case MDTables.Tables.TypeDef:
                        {
                            // This type implements an interface defined in the same assembly.
                            // This isn't really interesting for the add-in model, based on what
                            // we've currently designed and our limited use of this class.
                            mdScope.B.ReadUInt32();          // TypeAttributes
                            String ifaceName = mdScope.ReadString();
                            if (!String.Equals(ifaceName, ifaceType._typeName))
                            {
                                continue;
                            }
                            String ifaceNameSpace = mdScope.ReadString();
                            if (!String.Equals(ifaceNameSpace, ifaceType._nameSpace))
                            {
                                continue;
                            }
                            if (this._assembly.Equals(ifaceType._assembly))
                            {
                                return(true);
                            }
                            break;
                        }

                        case MDTables.Tables.TypeSpec:
                            // Since we're only looking for IContract, which is non-generic,
                            // we should ignore this row and move on.
                            System.Diagnostics.Contracts.Contract.Assert(false, "Checking whether a type implements a TypeSpec is NYI (generic interface?)");
                            break;

                        default:
                            System.Diagnostics.Contracts.Contract.Assert(false, "Support for this interface type is NYI");
                            throw new NotImplementedException(String.Format(CultureInfo.CurrentCulture, Res.UnsupportedInterfaceType, interfaceToken.Table));
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }
            return(false);
        }
예제 #3
0
        public MiniConstructorInfo[] GetConstructors(bool includePrivate)
        {
            System.Diagnostics.Contracts.Contract.Assert(HasToken /* || HasReflectionType*/, "GetConstructors needs a token (or you should uncomment the support for Reflection types)");

            List <MiniConstructorInfo> ctors = new List <MiniConstructorInfo>();

            /*
             * if (HasReflectionType) {
             *  System.Reflection.BindingFlags visibility = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public;
             *  if (includePrivate)
             *      visibility |= System.Reflection.BindingFlags.NonPublic;
             *  foreach (System.Reflection.ConstructorInfo ctor in _reflectionType.GetConstructors(visibility))
             *      ctors.Add(new MiniConstructorInfo(ctor));
             *  return ctors.ToArray();
             * }
             */

            System.Diagnostics.Contracts.Contract.Assert(_mdToken.Table == MDTables.Tables.TypeDef);

            PEFileReader peFile = _assembly.PEFileReader;

            peFile.InitMetaData();
            MDTables MetaData = peFile.MetaData;

            MetaData.SeekToMDToken(_mdToken);
            System.Reflection.TypeAttributes flags = (System.Reflection.TypeAttributes)peFile.B.ReadUInt32();
            System.Reflection.TypeAttributes vis   = System.Reflection.TypeAttributes.VisibilityMask & flags;
            bool isPublic = (vis == System.Reflection.TypeAttributes.Public); // don't support NestedPublic

            if (!includePrivate && !isPublic)
            {
                return(new MiniConstructorInfo[0]);
            }
            MetaData.ReadStringIndex();                                                                   // typename
            MetaData.ReadStringIndex();                                                                   // namespace

            MetadataToken baseClass        = MetaData.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef); // Base class
            uint          firstMemberIndex = MetaData.ReadRowIndex(MDTables.Tables.FieldDef);             // Field list
            uint          firstMethodIndex = MetaData.ReadRowIndex(MDTables.Tables.MethodDef);            // Method list
            uint          lastMethodIndex;

            // If this is the last entry in the TypeDef table, then all the rest of the methods in the MethodDef
            // table belong to this type.  Otherwise, look for the methods belonging to the next type.
            if (_mdToken.Index == MetaData.RowsInTable(MDTables.Tables.TypeDef))
            {
                lastMethodIndex = MetaData.RowsInTable(MDTables.Tables.MethodDef);
            }
            else
            {
                MetaData.SeekToRowOfTable(MDTables.Tables.TypeDef, _mdToken.Index);            // Seek to next type (not off by 1!)
                peFile.B.ReadUInt32();                                                         // Flags
                MetaData.ReadStringIndex();                                                    // type name
                MetaData.ReadStringIndex();                                                    // namespace
                MetaData.ReadMetadataToken(MDTables.Encodings.TypeDefOrRef);                   // Next type's base class
                MetaData.ReadRowIndex(MDTables.Tables.FieldDef);                               // field list;
                uint firstMethodOfNextType = MetaData.ReadRowIndex(MDTables.Tables.MethodDef); // method list
                lastMethodIndex = firstMethodOfNextType - 1;
            }

            // Now walk through list of methods, looking for ones w/ the name ".ctor".
            for (uint i = firstMethodIndex; i <= lastMethodIndex; i++)
            {
                MetadataToken method = new MetadataToken(MDTables.Tables.MethodDef, i);
                MetaData.SeekToMDToken(method);
                UInt32 rva       = peFile.B.ReadUInt32();
                UInt16 implFlags = peFile.B.ReadUInt16();                                                             // MethodImplAttributes
                System.Reflection.MethodAttributes attrs = (System.Reflection.MethodAttributes)peFile.B.ReadUInt16(); // Flags - MethodAttributes
                // Visibility check
                if (!includePrivate && (attrs & System.Reflection.MethodAttributes.Public) == 0)
                {
                    continue;
                }
                String methodName = MetaData.ReadString();  // Name
                // @
                if (!String.Equals(methodName, ".ctor"))
                {
                    continue;
                }

                byte[] sig = MetaData.ReadBlob();
                try
                {
                    MiniParameterInfo[] parameters = ParseSig(sig);
                    ctors.Add(new MiniConstructorInfo(parameters));
                }
                catch (GenericsNotImplementedException)
                {
                    // may be caused by a Generic contract.  The user will be warned elsewhere that generic contracts are not supported.

                    /*
                     * if (Warnings != null) {
                     *  lock (Warnings) {
                     *      Warnings.Add(String.Format(CultureInfo.CurrentCulture, Res.UnparsibleConstructorSignature, this.Name, e.GetType().Name, e.Message));
                     *  }
                     * }
                     */
                }
            } // for each .ctor
            return(ctors.ToArray());
        }