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); }
private void LoadCustomAttributeMetadata() { if (!_stream.Tables.ContainsKey(MetadataTables.CustomAttribute)) { return; } MetadataRow[] customAttributes = _stream.Tables[MetadataTables.CustomAttribute]; for (int i = 0; i < customAttributes.Length; i++) { CustomAttributeMetadataTableRow customAttributeRow = customAttributes[i] as CustomAttributeMetadataTableRow; ReflectedMember attributeTo = _map.GetDefinition(customAttributeRow.Parent.Table, _stream.GetEntryFor(customAttributeRow.Parent) ); MemberRef ofType = _map.GetDefinition(customAttributeRow.Type.Table, _stream.GetEntryFor(customAttributeRow.Type) ) as MemberRef; if (attributeTo != null) { CustomAttribute attribute = new CustomAttribute(ofType); attributeTo.Attributes.Add(attribute); } } }
/// <include file='code-documentation\reflection.xml' path='docs/assemblydef/member[@name="resolvemetadatatoken"]/*'/> public ReflectedMember ResolveMetadataToken(uint metadataToken) { MetadataToDefinitionMap map = _peCoffFile.Map; MetadataStream metadataStream = _peCoffFile.GetMetadataDirectory().GetMetadataStream(); // Get the details in the token ILMetadataToken token = (ILMetadataToken)(metadataToken & 0xff000000); uint index = metadataToken & 0x00ffffff; ReflectedMember returnItem = null; // switch (token) { // Method related tokens case ILMetadataToken.MethodDef: returnItem = map.GetDefinition(MetadataTables.MethodDef, metadataStream.GetEntryFor(MetadataTables.MethodDef, index)); break; case ILMetadataToken.MemberRef: returnItem = map.GetDefinition(MetadataTables.MemberRef, metadataStream.GetEntryFor(MetadataTables.MemberRef, index)); break; case ILMetadataToken.MethodSpec: returnItem = map.GetDefinition(MetadataTables.MethodSpec, metadataStream.GetEntryFor(MetadataTables.MethodSpec, index)); break; // Type related tokens case ILMetadataToken.TypeDef: returnItem = map.GetDefinition(MetadataTables.TypeDef, metadataStream.GetEntryFor(MetadataTables.TypeDef, index)); break; case ILMetadataToken.TypeRef: returnItem = map.GetDefinition(MetadataTables.TypeRef, metadataStream.GetEntryFor(MetadataTables.TypeRef, index)); break; case ILMetadataToken.TypeSpec: returnItem = map.GetDefinition(MetadataTables.TypeSpec, metadataStream.GetEntryFor(MetadataTables.TypeSpec, index)); break; case ILMetadataToken.FieldDef: returnItem = map.GetDefinition(MetadataTables.Field, metadataStream.GetEntryFor(MetadataTables.Field, index)); break; } return(returnItem); }
private void LoadProperties() { // Check if we have a property map and then find the property map for the current type // if it exists. if (!_metadataStream.Tables.ContainsKey(MetadataTables.PropertyMap)) { return; } // TODO: The metadata tables are in order, we should use a sorted search algorithm to // find elements we need. int startPropertyList = -1; int endPropertyList = -1; PropertyMapMetadataTableRow searchFor = new PropertyMapMetadataTableRow(); searchFor.Parent = _indexInMetadataTable; int mapIndex = Array.BinarySearch(_metadataStream.Tables[MetadataTables.PropertyMap], searchFor, new PropertyMapComparer() ); if (mapIndex >= 0) { startPropertyList = ((PropertyMapMetadataTableRow)_metadataStream.Tables[MetadataTables.PropertyMap][mapIndex]).PropertyList; if (mapIndex < _metadataStream.Tables[MetadataTables.PropertyMap].Length - 1) { endPropertyList = ((PropertyMapMetadataTableRow)_metadataStream.Tables[MetadataTables.PropertyMap][mapIndex + 1]).PropertyList - 1; } else { endPropertyList = _metadataStream.Tables[MetadataTables.Property].Length; } } // If we have properties we need to load them, instantiate a PropertyDef and relate // it to its getter and setter. if (startPropertyList != -1) { MetadataRow[] table = _metadataStream.Tables[MetadataTables.Property]; MetadataRow[] methodSemantics = _metadataStream.Tables[MetadataTables.MethodSemantics]; // Now load all the methods between our index and the endOfMethodIndex for (int i = startPropertyList; i <= endPropertyList; i++) { PropertyMetadataTableRow propertyRow = table[i - 1] as PropertyMetadataTableRow; PropertyDef property = new PropertyDef( _references.Assembly, _references.Assembly.StringStream.GetString(propertyRow.NameIndex.Value), _builtType); // Get the related getter and setter methods for (int j = 0; j < methodSemantics.Length; j++) { MethodSemanticsMetadataTableRow semantics = methodSemantics[j] as MethodSemanticsMetadataTableRow; CodedIndex index = semantics.Association; if (index.Table == MetadataTables.Property && index.Index == i) { if (semantics.Semantics == MethodSemanticsAttributes.Setter) { property.Setter = _map.GetDefinition( MetadataTables.MethodDef, _metadataStream.GetEntryFor(MetadataTables.MethodDef, semantics.Method) ) as MethodDef; } else if (semantics.Semantics == MethodSemanticsAttributes.Getter) { property.Getter = _map.GetDefinition( MetadataTables.MethodDef, _metadataStream.GetEntryFor(MetadataTables.MethodDef, semantics.Method) ) as MethodDef; } } } _map.Add(MetadataTables.Property, propertyRow, property); _builtType.Properties.Add(property); } } }