| File: System\Reflection\TypeLoading\Types\RoDefinitionType.cs | Web Access |
| Project: src\runtime\src\libraries\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj (System.Reflection.MetadataLoadContext) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace System.Reflection.TypeLoading { /// <summary> /// Base type for all RoTypes that return true for IsTypeDefinition. /// </summary> internal abstract partial class RoDefinitionType : RoInstantiationProviderType { protected RoDefinitionType() : base() { } public sealed override bool IsTypeDefinition => true; protected sealed override bool HasElementTypeImpl() => false; protected sealed override bool IsArrayImpl() => false; public sealed override bool IsSZArray => false; public sealed override bool IsVariableBoundArray => false; protected sealed override bool IsByRefImpl() => false; protected sealed override bool IsPointerImpl() => false; public sealed override bool IsFunctionPointer => false; public sealed override bool IsUnmanagedFunctionPointer => false; public sealed override bool IsConstructedGenericType => false; public sealed override bool IsGenericParameter => false; public sealed override bool IsGenericTypeParameter => false; public sealed override bool IsGenericMethodParameter => false; public sealed override bool ContainsGenericParameters => IsGenericTypeDefinition; protected sealed override string? ComputeFullName() { Debug.Assert(!IsConstructedGenericType); Debug.Assert(!IsGenericParameter); Debug.Assert(!HasElementType); string name = Name; Type? declaringType = DeclaringType; if (declaringType != null) { string? declaringTypeFullName = declaringType.FullName; return declaringTypeFullName + "+" + name; } string? ns = Namespace; if (ns == null) return name; return ns + "." + name; } public sealed override string ToString() => Loader.GetDisposedString() ?? FullName!; internal abstract int GetGenericParameterCount(); internal abstract override RoType[] GetGenericTypeParametersNoCopy(); public sealed override IEnumerable<CustomAttributeData> CustomAttributes { get { foreach (CustomAttributeData cad in GetTrueCustomAttributes()) { yield return cad; } if (0 != (Attributes & TypeAttributes.Import)) { ConstructorInfo? ci = Loader.TryGetComImportCtor(); if (ci != null) yield return new RoPseudoCustomAttributeData(ci); } } } protected abstract IEnumerable<CustomAttributeData> GetTrueCustomAttributes(); public sealed override Type GetGenericTypeDefinition() => IsGenericTypeDefinition ? this : throw new InvalidOperationException(SR.InvalidOperation_NotGenericType); internal sealed override RoType? ComputeBaseTypeWithoutDesktopQuirk() => SpecializeBaseType(Instantiation); internal abstract RoType? SpecializeBaseType(RoType[] instantiation); internal sealed override IEnumerable<RoType> ComputeDirectlyImplementedInterfaces() => SpecializeInterfaces(Instantiation); internal abstract IEnumerable<RoType> SpecializeInterfaces(RoType[] instantiation); [RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] public sealed override Type MakeGenericType(params Type[] typeArguments) { ArgumentNullException.ThrowIfNull(typeArguments); if (!IsGenericTypeDefinition) throw new InvalidOperationException(SR.Format(SR.Arg_NotGenericTypeDefinition, this)); int count = typeArguments.Length; if (count != GetGenericParameterCount()) throw new ArgumentException(SR.Argument_GenericArgsCount, nameof(typeArguments)); bool foundSigType = false; RoType[] runtimeTypeArguments = new RoType[count]; for (int i = 0; i < count; i++) { Type typeArgument = typeArguments[i]; if (typeArgument == null) throw new ArgumentNullException(); if (typeArgument.IsSignatureType) { foundSigType = true; } else { if (!(typeArgument is RoType roTypeArgument && roTypeArgument.Loader == Loader)) throw new ArgumentException(SR.Format(SR.MakeGenericType_NotLoadedByMetadataLoadContext, typeArgument)); runtimeTypeArguments[i] = roTypeArgument; } } if (foundSigType) return Type.MakeGenericSignatureType(this, typeArguments); // We are intentionally not validating constraints as constraint validation is an execution-time issue that does not block our // library and should not block a metadata inspection tool. return this.GetUniqueConstructedGenericType(runtimeTypeArguments); } public sealed override Guid GUID { get { CustomAttributeData? cad = TryFindCustomAttribute(Utf8Constants.SystemRuntimeInteropServices, Utf8Constants.GuidAttribute); if (cad == null) return default; IList<CustomAttributeTypedArgument> ctas = cad.ConstructorArguments; if (ctas.Count != 1) return default; CustomAttributeTypedArgument cta = ctas[0]; if (cta.ArgumentType != Loader.TryGetCoreType(CoreType.String)) return default; if (!(cta.Value is string guidString)) return default; return new Guid(guidString); } } private const TypeAttributes TypeAttributesExtendedLayout = (TypeAttributes)0x00000018; // TypeAttributes.ExtendedLayout private const LayoutKind LayoutKindExtended = (LayoutKind)1; public sealed override StructLayoutAttribute? StructLayoutAttribute { get { // Note: CoreClr checks HasElementType and IsGenericParameter in addition to IsInterface but those properties cannot be true here as this // RoType subclass is solely for TypeDef types.) if (IsInterface) return null; TypeAttributes attributes = Attributes; LayoutKind layoutKind = (attributes & TypeAttributes.LayoutMask) switch { TypeAttributes.ExplicitLayout => LayoutKind.Explicit, TypeAttributes.AutoLayout => LayoutKind.Auto, TypeAttributes.SequentialLayout => LayoutKind.Sequential, TypeAttributesExtendedLayout => LayoutKindExtended, _ => LayoutKind.Auto, }; CharSet charSet = (attributes & TypeAttributes.StringFormatMask) switch { TypeAttributes.AnsiClass => CharSet.Ansi, TypeAttributes.AutoClass => CharSet.Auto, TypeAttributes.UnicodeClass => CharSet.Unicode, _ => CharSet.None, }; GetPackSizeAndSize(out int pack, out int size); return new StructLayoutAttribute(layoutKind) { CharSet = charSet, Pack = pack, Size = size, }; } } protected abstract void GetPackSizeAndSize(out int packSize, out int size); protected sealed override TypeCode GetTypeCodeImpl() { Type t = IsEnum ? GetEnumUnderlyingType() : this; CoreTypes ct = Loader.GetAllFoundCoreTypes(); if (t == ct[CoreType.Boolean]) return TypeCode.Boolean; if (t == ct[CoreType.Char]) return TypeCode.Char; if (t == ct[CoreType.SByte]) return TypeCode.SByte; if (t == ct[CoreType.Byte]) return TypeCode.Byte; if (t == ct[CoreType.Int16]) return TypeCode.Int16; if (t == ct[CoreType.UInt16]) return TypeCode.UInt16; if (t == ct[CoreType.Int32]) return TypeCode.Int32; if (t == ct[CoreType.UInt32]) return TypeCode.UInt32; if (t == ct[CoreType.Int64]) return TypeCode.Int64; if (t == ct[CoreType.UInt64]) return TypeCode.UInt64; if (t == ct[CoreType.Single]) return TypeCode.Single; if (t == ct[CoreType.Double]) return TypeCode.Double; if (t == ct[CoreType.String]) return TypeCode.String; if (t == ct[CoreType.DateTime]) return TypeCode.DateTime; if (t == ct[CoreType.Decimal]) return TypeCode.Decimal; if (t == ct[CoreType.DBNull]) return TypeCode.DBNull; return TypeCode.Object; } internal sealed override RoType? GetRoElementType() => null; public sealed override int GetArrayRank() => throw new ArgumentException(SR.Argument_HasToBeArrayClass); internal sealed override RoType[] GetGenericTypeArgumentsNoCopy() => Array.Empty<RoType>(); protected internal sealed override RoType[] GetGenericArgumentsNoCopy() => GetGenericTypeParametersNoCopy(); public sealed override GenericParameterAttributes GenericParameterAttributes => throw new InvalidOperationException(SR.Arg_NotGenericParameter); public sealed override int GenericParameterPosition => throw new InvalidOperationException(SR.Arg_NotGenericParameter); public sealed override Type[] GetGenericParameterConstraints() => throw new InvalidOperationException(SR.Arg_NotGenericParameter); public sealed override MethodBase DeclaringMethod => throw new InvalidOperationException(SR.Arg_NotGenericParameter); public sealed override Type GetFunctionPointerReturnType() => throw new InvalidOperationException(SR.InvalidOperation_NotFunctionPointer); public sealed override Type[] GetFunctionPointerParameterTypes() => throw new InvalidOperationException(SR.InvalidOperation_NotFunctionPointer); internal sealed override IEnumerable<ConstructorInfo> GetConstructorsCore(NameFilter? filter) => SpecializeConstructors(filter, this); internal sealed override IEnumerable<MethodInfo> GetMethodsCore(NameFilter? filter, Type reflectedType) => SpecializeMethods(filter, reflectedType, this); internal sealed override IEnumerable<EventInfo> GetEventsCore(NameFilter? filter, Type reflectedType) => SpecializeEvents(filter, reflectedType, this); internal sealed override IEnumerable<FieldInfo> GetFieldsCore(NameFilter? filter, Type reflectedType) => SpecializeFields(filter, reflectedType, this); internal sealed override IEnumerable<PropertyInfo> GetPropertiesCore(NameFilter? filter, Type reflectedType) => SpecializeProperties(filter, reflectedType, this); // Like CoreGetDeclared but allows specifying an alternate declaringType (which must be a generic instantiation of the true declaring type) internal abstract IEnumerable<ConstructorInfo> SpecializeConstructors(NameFilter? filter, RoInstantiationProviderType declaringType); internal abstract IEnumerable<MethodInfo> SpecializeMethods(NameFilter? filter, Type reflectedType, RoInstantiationProviderType declaringType); internal abstract IEnumerable<EventInfo> SpecializeEvents(NameFilter? filter, Type reflectedType, RoInstantiationProviderType declaringType); internal abstract IEnumerable<FieldInfo> SpecializeFields(NameFilter? filter, Type reflectedType, RoInstantiationProviderType declaringType); internal abstract IEnumerable<PropertyInfo> SpecializeProperties(NameFilter? filter, Type reflectedType, RoInstantiationProviderType declaringType); // Helpers for the typeref-resolution/name lookup logic. internal abstract bool IsTypeNameEqual(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name); internal abstract RoDefinitionType? GetNestedTypeCore(ReadOnlySpan<byte> utf8Name); internal sealed override RoType[] Instantiation => GetGenericTypeParametersNoCopy(); } }