< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 127
Coverable lines: 127
Total lines: 297
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 29
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%110%
GetLayout()0%440%
GetDeclaringType()100%110%
GetGenericParameters()100%110%
GetMethods()100%110%
GetFields()100%110%
GetProperties()100%110%
GetEvents()100%110%
GetNestedTypes()100%110%
GetMethodImplementations()100%110%
GetInterfaceImplementations()100%110%
GetCustomAttributes()100%110%
GetDeclarativeSecurityAttributes()100%110%
GetProjectedFlags()0%11110%
GetProjectedName()0%440%
GetProjectedNamespace()100%110%
GetProjectedNamespaceString()100%110%
GetProjectedBaseType()100%110%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeSystem/TypeDefinition.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Immutable;
 5using System.Reflection.Metadata.Ecma335;
 6
 7namespace System.Reflection.Metadata
 8{
 9    public readonly struct TypeDefinition
 10    {
 11        private readonly MetadataReader _reader;
 12
 13        // Workaround: JIT doesn't generate good code for nested structures, so use RowId.
 14        private readonly uint _treatmentAndRowId;
 15
 16        internal TypeDefinition(MetadataReader reader, uint treatmentAndRowId)
 017        {
 018            _reader = reader;
 019            _treatmentAndRowId = treatmentAndRowId;
 020        }
 21
 22        private int RowId
 23        {
 024            get { return (int)(_treatmentAndRowId & TokenTypeIds.RIDMask); }
 25        }
 26
 27        private TypeDefTreatment Treatment
 28        {
 029            get { return (TypeDefTreatment)(_treatmentAndRowId >> TokenTypeIds.RowIdBitCount); }
 30        }
 31
 32        private TypeDefinitionHandle Handle
 33        {
 034            get { return TypeDefinitionHandle.FromRowId(RowId); }
 35        }
 36
 37        public TypeAttributes Attributes
 38        {
 39            get
 040            {
 041                if (Treatment == 0)
 042                {
 043                    return _reader.TypeDefTable.GetFlags(Handle);
 44                }
 45
 046                return GetProjectedFlags();
 047            }
 48        }
 49
 50        /// <summary>
 51        /// Indicates whether this is a nested type.
 52        /// </summary>
 053        public bool IsNested => Attributes.IsNested();
 54
 55        /// <summary>
 56        /// Name of the type.
 57        /// </summary>
 58        public StringHandle Name
 59        {
 60            get
 061            {
 062                if (Treatment == 0)
 063                {
 064                    return _reader.TypeDefTable.GetName(Handle);
 65                }
 66
 067                return GetProjectedName();
 068            }
 69        }
 70
 71        /// <summary>
 72        /// Full name of the namespace where the type is defined, or nil if the type is nested or defined in a root name
 73        /// </summary>
 74        public StringHandle Namespace
 75        {
 76            get
 077            {
 078                if (Treatment == 0)
 079                {
 080                    return _reader.TypeDefTable.GetNamespace(Handle);
 81                }
 82
 083                return GetProjectedNamespaceString();
 084            }
 85        }
 86
 87        /// <summary>
 88        /// The definition handle of the namespace where the type is defined, or nil if the type is nested or defined in
 89        /// </summary>
 90        public NamespaceDefinitionHandle NamespaceDefinition
 91        {
 92            get
 093            {
 094                if (Treatment == 0)
 095                {
 096                    return _reader.TypeDefTable.GetNamespaceDefinition(Handle);
 97                }
 98
 099                return GetProjectedNamespace();
 0100            }
 101        }
 102
 103        /// <summary>
 104        /// The base type of the type definition: either
 105        /// <see cref="TypeSpecificationHandle"/>, <see cref="TypeReferenceHandle"/> or <see cref="TypeDefinitionHandle"
 106        /// </summary>
 107        public EntityHandle BaseType
 108        {
 109            get
 0110            {
 0111                if (Treatment == 0)
 0112                {
 0113                    return _reader.TypeDefTable.GetExtends(Handle);
 114                }
 115
 0116                return GetProjectedBaseType();
 0117            }
 118        }
 119
 120        public TypeLayout GetLayout()
 0121        {
 0122            int classLayoutRowId = _reader.ClassLayoutTable.FindRow(Handle);
 0123            if (classLayoutRowId == 0)
 0124            {
 125                // NOTE: We don't need a bool/TryGetLayout because zero also means use default:
 126                //
 127                // Spec:
 128                //  ClassSize of zero does not mean the class has zero size. It means that no .size directive was specif
 129                //  at definition time, in which case, the actual size is calculated from the field types, taking accoun
 130                //  packing size (default or specified) and natural alignment on the target, runtime platform.
 131                //
 132                // PackingSize shall be one of {0, 1, 2, 4, 8, 16, 32, 64, 128}. (0 means use
 133                // the default pack size for the platform on which the application is
 134                // running.)
 135
 0136                return default(TypeLayout);
 137            }
 138
 0139            uint size = _reader.ClassLayoutTable.GetClassSize(classLayoutRowId);
 140
 141            // The spec doesn't limit the size to 31bit. It only limits the size to 1MB if Parent is a value type.
 142            // It however doesn't make much sense to define classes with >2GB size. So in order to keep the API
 143            // clean of unsigned ints we impose the limit.
 0144            if (unchecked((int)size) != size)
 0145            {
 0146                throw new BadImageFormatException(SR.InvalidTypeSize);
 147            }
 148
 0149            int packingSize = _reader.ClassLayoutTable.GetPackingSize(classLayoutRowId);
 0150            return new TypeLayout((int)size, packingSize);
 0151        }
 152
 153        /// <summary>
 154        /// Returns the enclosing type of a specified nested type or nil handle if the type is not nested.
 155        /// </summary>
 156        public TypeDefinitionHandle GetDeclaringType()
 0157        {
 0158            return _reader.NestedClassTable.FindEnclosingType(Handle);
 0159        }
 160
 161        public GenericParameterHandleCollection GetGenericParameters()
 0162        {
 0163            return _reader.GenericParamTable.FindGenericParametersForType(Handle);
 0164        }
 165
 166        public MethodDefinitionHandleCollection GetMethods()
 0167        {
 0168            return new MethodDefinitionHandleCollection(_reader, Handle);
 0169        }
 170
 171        public FieldDefinitionHandleCollection GetFields()
 0172        {
 0173            return new FieldDefinitionHandleCollection(_reader, Handle);
 0174        }
 175
 176        public PropertyDefinitionHandleCollection GetProperties()
 0177        {
 0178            return new PropertyDefinitionHandleCollection(_reader, Handle);
 0179        }
 180
 181        public EventDefinitionHandleCollection GetEvents()
 0182        {
 0183            return new EventDefinitionHandleCollection(_reader, Handle);
 0184        }
 185
 186        /// <summary>
 187        /// Returns an array of types nested in the specified type.
 188        /// </summary>
 189        public ImmutableArray<TypeDefinitionHandle> GetNestedTypes()
 0190        {
 0191            return _reader.GetNestedTypes(Handle);
 0192        }
 193
 194        public MethodImplementationHandleCollection GetMethodImplementations()
 0195        {
 0196            return new MethodImplementationHandleCollection(_reader, Handle);
 0197        }
 198
 199        public InterfaceImplementationHandleCollection GetInterfaceImplementations()
 0200        {
 0201            return new InterfaceImplementationHandleCollection(_reader, Handle);
 0202        }
 203
 204        public CustomAttributeHandleCollection GetCustomAttributes()
 0205        {
 0206            return new CustomAttributeHandleCollection(_reader, Handle);
 0207        }
 208
 209        public DeclarativeSecurityAttributeHandleCollection GetDeclarativeSecurityAttributes()
 0210        {
 0211            return new DeclarativeSecurityAttributeHandleCollection(_reader, Handle);
 0212        }
 213
 214        #region Projections
 215
 216        private TypeAttributes GetProjectedFlags()
 0217        {
 0218            var flags = _reader.TypeDefTable.GetFlags(Handle);
 0219            var treatment = Treatment;
 220
 0221            switch (treatment & TypeDefTreatment.KindMask)
 222            {
 223                case TypeDefTreatment.NormalNonAttribute:
 0224                    flags |= TypeAttributes.WindowsRuntime | TypeAttributes.Import;
 0225                    break;
 226
 227                case TypeDefTreatment.NormalAttribute:
 0228                    flags |= TypeAttributes.WindowsRuntime | TypeAttributes.Sealed;
 0229                    break;
 230
 231                case TypeDefTreatment.UnmangleWinRTName:
 0232                    flags = flags & ~TypeAttributes.SpecialName | TypeAttributes.Public;
 0233                    break;
 234
 235                case TypeDefTreatment.PrefixWinRTName:
 0236                    flags = flags & ~TypeAttributes.Public | TypeAttributes.Import;
 0237                    break;
 238
 239                case TypeDefTreatment.RedirectedToClrType:
 0240                    flags = flags & ~TypeAttributes.Public | TypeAttributes.Import;
 0241                    break;
 242
 243                case TypeDefTreatment.RedirectedToClrAttribute:
 0244                    flags &= ~TypeAttributes.Public;
 0245                    break;
 246            }
 247
 0248            if ((treatment & TypeDefTreatment.MarkAbstractFlag) != 0)
 0249            {
 0250                flags |= TypeAttributes.Abstract;
 0251            }
 252
 0253            if ((treatment & TypeDefTreatment.MarkInternalFlag) != 0)
 0254            {
 0255                flags &= ~TypeAttributes.Public;
 0256            }
 257
 0258            return flags;
 0259        }
 260
 261        private StringHandle GetProjectedName()
 0262        {
 0263            var name = _reader.TypeDefTable.GetName(Handle);
 264
 0265            return (Treatment & TypeDefTreatment.KindMask) switch
 0266            {
 0267                TypeDefTreatment.UnmangleWinRTName => name.SuffixRaw(MetadataReader.ClrPrefix.Length),
 0268                TypeDefTreatment.PrefixWinRTName => name.WithWinRTPrefix(),
 0269                _ => name,
 0270            };
 0271        }
 272
 273        private NamespaceDefinitionHandle GetProjectedNamespace()
 0274        {
 275            // NOTE: NamespaceDefinitionHandle currently relies on never having virtual values. If this ever gets projec
 276            //       to a virtual namespace name, then that assumption will need to be removed.
 277
 278            // no change:
 0279            return _reader.TypeDefTable.GetNamespaceDefinition(Handle);
 0280        }
 281
 282        private StringHandle GetProjectedNamespaceString()
 0283        {
 284            // no change:
 0285            return _reader.TypeDefTable.GetNamespace(Handle);
 0286        }
 287
 288        private EntityHandle GetProjectedBaseType()
 0289        {
 290            // no change:
 0291            return _reader.TypeDefTable.GetExtends(Handle);
 0292        }
 293
 294        #endregion
 295    }
 296}
 297