internal static IEnumerable <DerivedTypesEntryNode> FindDerivedTypes(AssemblyList list, ITypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken) { var definitionMetadata = type.ParentModule.PEFile.Metadata; var metadataToken = (SRM.TypeDefinitionHandle)type.MetadataToken; foreach (var module in assemblies) { var metadata = module.Metadata; var assembly = (MetadataModule)module.GetTypeSystemOrNull().MainModule; foreach (var h in metadata.TypeDefinitions) { cancellationToken.ThrowIfCancellationRequested(); var td = metadata.GetTypeDefinition(h); foreach (var iface in td.GetInterfaceImplementations()) { var ifaceImpl = metadata.GetInterfaceImplementation(iface); if (!ifaceImpl.Interface.IsNil && IsSameType(metadata, ifaceImpl.Interface, definitionMetadata, metadataToken)) { yield return(new DerivedTypesEntryNode(list, assembly.GetDefinition(h))); } } SRM.EntityHandle baseType = td.GetBaseTypeOrNil(); if (!baseType.IsNil && IsSameType(metadata, baseType, definitionMetadata, metadataToken)) { yield return(new DerivedTypesEntryNode(list, assembly.GetDefinition(h))); } } } yield break; }
public virtual CodeMappingInfo GetCodeMappingInfo(PEFile module, SRM.EntityHandle member) { var parts = new Dictionary <SRM.MethodDefinitionHandle, SRM.MethodDefinitionHandle[]>(); var locations = new Dictionary <SRM.EntityHandle, SRM.MethodDefinitionHandle>(); var declaringType = member.GetDeclaringType(module.Metadata); if (declaringType.IsNil && member.Kind == SRM.HandleKind.TypeDefinition) { declaringType = (SRM.TypeDefinitionHandle)member; } return(new CodeMappingInfo(module, declaringType)); }
bool?IsReferenceType(SRM.MetadataReader reader, SRM.EntityHandle handle, byte rawTypeKind) { switch (reader.ResolveSignatureTypeKind(handle, rawTypeKind)) { case SRM.SignatureTypeKind.ValueType: return(false); case SRM.SignatureTypeKind.Class: return(true); default: return(null); } }
static bool IsSameType(SRM.MetadataReader referenceMetadata, SRM.EntityHandle typeRef, SRM.MetadataReader definitionMetadata, SRM.TypeDefinitionHandle typeDef) { // FullName contains only namespace, name and type parameter count, therefore this should suffice. return(typeRef.GetFullTypeName(referenceMetadata) == typeDef.GetFullTypeName(definitionMetadata)); }
private uint CalculateMethodDefTreatmentAndRowId(MethodDefinitionHandle methodDef) { MethodDefTreatment treatment = MethodDefTreatment.Implementation; TypeDefinitionHandle parentTypeDef = GetDeclaringType(methodDef); TypeAttributes parentFlags = TypeDefTable.GetFlags(parentTypeDef); if ((parentFlags & TypeAttributes.WindowsRuntime) != 0) { if (IsClrImplementationType(parentTypeDef)) { treatment = MethodDefTreatment.Implementation; } else if (parentFlags.IsNested()) { treatment = MethodDefTreatment.Implementation; } else if ((parentFlags & TypeAttributes.Interface) != 0) { treatment = MethodDefTreatment.InterfaceMethod; } else if (_metadataKind == MetadataKind.ManagedWindowsMetadata && (parentFlags & TypeAttributes.Public) == 0) { treatment = MethodDefTreatment.Implementation; } else { treatment = MethodDefTreatment.Other; var parentBaseType = TypeDefTable.GetExtends(parentTypeDef); if (parentBaseType.Kind == HandleKind.TypeReference) { switch (GetSpecialTypeRefTreatment((TypeReferenceHandle)parentBaseType)) { case TypeRefTreatment.SystemAttribute: treatment = MethodDefTreatment.AttributeMethod; break; case TypeRefTreatment.SystemDelegate: treatment = MethodDefTreatment.DelegateMethod | MethodDefTreatment.MarkPublicFlag; break; } } } } if (treatment == MethodDefTreatment.Other) { // we want to hide the method if it implements // only redirected interfaces // We also want to check if the methodImpl is IClosable.Close, // so we can change the name bool seenRedirectedInterfaces = false; bool seenNonRedirectedInterfaces = false; bool isIClosableClose = false; foreach (var methodImplHandle in new MethodImplementationHandleCollection(this, parentTypeDef)) { MethodImplementation methodImpl = GetMethodImplementation(methodImplHandle); if (methodImpl.MethodBody == methodDef) { EntityHandle declaration = methodImpl.MethodDeclaration; // See if this MethodImpl implements a redirected interface // In WinMD, MethodImpl will always use MemberRef and TypeRefs to refer to redirected interfaces, // even if they are in the same module. if (declaration.Kind == HandleKind.MemberReference && ImplementsRedirectedInterface((MemberReferenceHandle)declaration, out isIClosableClose)) { seenRedirectedInterfaces = true; if (isIClosableClose) { // This method implements IClosable.Close // Let's rename to IDisposable later // Once we know this implements IClosable.Close, we are done // looking break; } } else { // Now we know this implements a non-redirected interface // But we need to keep looking, just in case we got a methodimpl that // implements the IClosable.Close method and needs to be renamed seenNonRedirectedInterfaces = true; } } } if (isIClosableClose) { treatment = MethodDefTreatment.DisposeMethod; } else if (seenRedirectedInterfaces && !seenNonRedirectedInterfaces) { // Only hide if all the interfaces implemented are redirected treatment = MethodDefTreatment.HiddenInterfaceImplementation; } } // If treatment is other, then this is a non-managed WinRT runtime class definition // Find out about various bits that we apply via attributes and name parsing if (treatment == MethodDefTreatment.Other) { treatment |= GetMethodTreatmentFromCustomAttributes(methodDef); } return(TreatmentAndRowId((byte)treatment, methodDef.RowId)); }
internal uint CalculateTypeDefTreatmentAndRowId(TypeDefinitionHandle handle) { Debug.Assert(_metadataKind != MetadataKind.Ecma335); TypeDefTreatment treatment; TypeAttributes flags = TypeDefTable.GetFlags(handle); EntityHandle extends = TypeDefTable.GetExtends(handle); if ((flags & TypeAttributes.WindowsRuntime) != 0) { if (_metadataKind == MetadataKind.WindowsMetadata) { treatment = GetWellKnownTypeDefinitionTreatment(handle); if (treatment != TypeDefTreatment.None) { return(TreatmentAndRowId((byte)treatment, handle.RowId)); } // Is this an attribute? if (extends.Kind == HandleKind.TypeReference && IsSystemAttribute((TypeReferenceHandle)extends)) { treatment = TypeDefTreatment.NormalAttribute; } else { treatment = TypeDefTreatment.NormalNonAttribute; } } else if (_metadataKind == MetadataKind.ManagedWindowsMetadata && NeedsWinRTPrefix(flags, extends)) { // WinMDExp emits two versions of RuntimeClasses and Enums: // // public class Foo {} // the WinRT reference class // internal class <CLR>Foo {} // the implementation class that we want WinRT consumers to ignore // // The adapter's job is to undo WinMDExp's transformations. I.e. turn the above into: // // internal class <WinRT>Foo {} // the WinRT reference class that we want CLR consumers to ignore // public class Foo {} // the implementation class // // We only add the <WinRT> prefix here since the WinRT view is the only view that is marked WindowsRuntime // De-mangling the CLR name is done below. // tomat: The CLR adapter implements a back-compat quirk: Enums exported with an older WinMDExp have only one version // not marked with tdSpecialName. These enums should *not* be mangled and flipped to private. // We don't implement this flag since the WinMDs produced by the older WinMDExp are not used in the wild. treatment = TypeDefTreatment.PrefixWinRTName; } else { treatment = TypeDefTreatment.None; } // Scan through Custom Attributes on type, looking for interesting bits. We only // need to do this for RuntimeClasses if ((treatment == TypeDefTreatment.PrefixWinRTName || treatment == TypeDefTreatment.NormalNonAttribute)) { if ((flags & TypeAttributes.Interface) == 0 && HasAttribute(handle, "Windows.UI.Xaml", "TreatAsAbstractComposableClassAttribute")) { treatment |= TypeDefTreatment.MarkAbstractFlag; } } } else if (_metadataKind == MetadataKind.ManagedWindowsMetadata && IsClrImplementationType(handle)) { // <CLR> implementation classes are not marked WindowsRuntime, but still need to be modified // by the adapter. treatment = TypeDefTreatment.UnmangleWinRTName; } else { treatment = TypeDefTreatment.None; } return(TreatmentAndRowId((byte)treatment, handle.RowId)); }