Beispiel #1
0
        internal List <TypeRef> GetExtendindTypes(TypeDef type, CodedIndex ciForThisType)
        {
            List <TypeRef>    inheritingTypes = new List <TypeRef>();
            List <CodedIndex> ourIndexes      = new List <CodedIndex>(); // our coded index in typedef and any that appear in the type spec metadata Signatures

            ourIndexes.Add(ciForThisType);

            // All types in this assembly that extend another use the TypeDef.Extends data in the metadata
            // table.
            if (type.IsGeneric)
            {
                MetadataRow[] typeSpecs = _metadataStream.Tables[MetadataTables.TypeSpec];
                for (int i = 0; i < typeSpecs.Length; i++)
                {
                    TypeSpecMetadataTableRow row = typeSpecs[i] as TypeSpecMetadataTableRow;
                    if (row != null)
                    {
                        // We need to find all of the TypeSpec references that point back to us, remember
                        // that as a generic type people can inherit from us in different ways - Type<int> or Type<string>
                        // for example. Each one of these will be a different type spec.
                        TypeSpec       spec  = _metadataMap.GetDefinition(MetadataTables.TypeSpec, row) as TypeSpec;
                        SignatureToken token = spec.Signiture.TypeToken.Tokens[0];

                        // First check if it is a GenericInstance as per the signiture spec in ECMA 23.2.14
                        if (token.TokenType == SignatureTokens.ElementType && ((ElementTypeSignatureToken)token).ElementType == ElementTypes.GenericInstance)
                        {
                            ElementTypeSignatureToken typeToken = spec.Signiture.TypeToken.Tokens[1] as ElementTypeSignatureToken;

                            TypeRef typeRef = typeToken.ResolveToken(Assembly);
                            if (typeRef == type)
                            {
                                ourIndexes.Add(new CodedIndex(MetadataTables.TypeSpec, (uint)i + 1));
                            }
                        }
                    }
                }
            }

            MetadataRow[] typeDefs = _metadataStream.Tables[MetadataTables.TypeDef];
            for (int i = 0; i < typeDefs.Length; i++)
            {
                for (int j = 0; j < ourIndexes.Count; j++)
                {
                    TypeDefMetadataTableRow row = (TypeDefMetadataTableRow)typeDefs[i];
                    CodedIndex ourCi            = ourIndexes[j];

                    if (row.Extends == ourCi)
                    {
                        inheritingTypes.Add(
                            (TypeDef)_metadataMap.GetDefinition(MetadataTables.TypeDef, _metadataStream.Tables[MetadataTables.TypeDef][i])
                            );
                        continue; // a type can only be extending once so if we find ourselves we are done
                    }
                }
            }

            return(inheritingTypes);
        }