internal uint CalculateTypeDefTreatmentAndRowId(TypeDefinitionHandle handle) { Debug.Assert(_metadataKind != MetadataKind.Ecma335); TypeDefTreatment treatment; TypeAttributes flags = TypeDefTable.GetFlags(handle); Handle 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 producted 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)); }
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)); }