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)); }
private void InitializeTypeDef(Cts.MetadataType entity, TypeDefinition record) { Debug.Assert(entity.IsTypeDefinition); Cts.MetadataType containingType = (Cts.MetadataType)entity.ContainingType; if (containingType != null) { var enclosingType = (TypeDefinition)HandleType(containingType); record.EnclosingType = enclosingType; enclosingType.NestedTypes.Add(record); var namespaceDefinition = HandleNamespaceDefinition(containingType.Module, entity.ContainingType.Namespace); record.NamespaceDefinition = namespaceDefinition; } else { var namespaceDefinition = HandleNamespaceDefinition(entity.Module, entity.Namespace); record.NamespaceDefinition = namespaceDefinition; namespaceDefinition.TypeDefinitions.Add(record); } record.Name = HandleString(entity.Name); Cts.ClassLayoutMetadata layoutMetadata = entity.GetClassLayout(); record.Size = checked ((uint)layoutMetadata.Size); record.PackingSize = checked ((ushort)layoutMetadata.PackingSize); record.Flags = GetTypeAttributes(entity); if (entity.HasBaseType) { record.BaseType = HandleType(entity.BaseType); } record.Interfaces.Capacity = entity.ExplicitlyImplementedInterfaces.Length; foreach (var interfaceType in entity.ExplicitlyImplementedInterfaces) { if (IsBlocked(interfaceType)) { continue; } record.Interfaces.Add(HandleType(interfaceType)); } if (entity.HasInstantiation) { record.GenericParameters.Capacity = entity.Instantiation.Length; foreach (var p in entity.Instantiation) { record.GenericParameters.Add(HandleGenericParameter((Cts.GenericParameterDesc)p)); } } foreach (var field in entity.GetFields()) { if (_policy.GeneratesMetadata(field)) { record.Fields.Add(HandleFieldDefinition(field)); } } foreach (var method in entity.GetMethods()) { if (_policy.GeneratesMetadata(method)) { record.Methods.Add(HandleMethodDefinition(method)); } } var ecmaEntity = entity as Cts.Ecma.EcmaType; if (ecmaEntity != null) { Ecma.TypeDefinition ecmaRecord = ecmaEntity.MetadataReader.GetTypeDefinition(ecmaEntity.Handle); foreach (var e in ecmaRecord.GetEvents()) { Event evt = HandleEvent(ecmaEntity.EcmaModule, e); if (evt != null) { record.Events.Add(evt); } } foreach (var property in ecmaRecord.GetProperties()) { Property prop = HandleProperty(ecmaEntity.EcmaModule, property); if (prop != null) { record.Properties.Add(prop); } } Ecma.CustomAttributeHandleCollection customAttributes = ecmaRecord.GetCustomAttributes(); if (customAttributes.Count > 0) { record.CustomAttributes = HandleCustomAttributes(ecmaEntity.EcmaModule, customAttributes); } foreach (var miHandle in ecmaRecord.GetMethodImplementations()) { Ecma.MetadataReader reader = ecmaEntity.EcmaModule.MetadataReader; Ecma.MethodImplementation miDef = reader.GetMethodImplementation(miHandle); Cts.MethodDesc methodBody = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodBody); if (_policy.IsBlocked(methodBody)) { continue; } Cts.MethodDesc methodDecl = (Cts.MethodDesc)ecmaEntity.EcmaModule.GetObject(miDef.MethodDeclaration); if (_policy.IsBlocked(methodDecl.GetTypicalMethodDefinition())) { continue; } MethodImpl methodImplRecord = new MethodImpl { MethodBody = HandleQualifiedMethod(methodBody), MethodDeclaration = HandleQualifiedMethod(methodDecl) }; record.MethodImpls.Add(methodImplRecord); } } }