Example #1
0
        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));
        }