| File: System\Reflection\TypeLoading\Types\RoModifiedType.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.Reflection.TypeLoading; using StructLayoutAttribute = System.Runtime.InteropServices.StructLayoutAttribute; namespace System.Reflection { /// <summary> /// Base type for modified types obtained through FieldInfo.GetModifiedFieldInfo(), PropertyInfo.GetModifiedPropertyInfo() /// and ParameterInfo.GetModifiedParameterInfo(). /// </summary> internal abstract class RoModifiedType : RoType { private List<Type>? _requiredModifiersBuilder; private List<Type>? _optionalModifiersBuilder; private Type[]? _requiredModifiers; private Type[]? _optionalModifiers; private readonly RoType _unmodifiedType; protected RoModifiedType(RoType unmodifiedType) { _unmodifiedType = unmodifiedType; } public static RoModifiedType Create(RoType unmodifiedType) { RoModifiedType modifiedType; if (unmodifiedType is RoModifiedType mod) { // A nested type, such as a function pointer in 'delegate*<void>[]' array, may already be modified. modifiedType = mod; } else if (unmodifiedType.IsFunctionPointer) { modifiedType = new RoModifiedFunctionPointerType((RoFunctionPointerType)unmodifiedType); } else if (unmodifiedType.IsGenericType) { modifiedType = new RoModifiedGenericType((RoConstructedGenericType)unmodifiedType); } else if (unmodifiedType.HasElementType) { modifiedType = new RoModifiedHasElementType(unmodifiedType); } else { modifiedType = new RoModifiedStandaloneType(unmodifiedType); } return modifiedType; } public void AddRequiredModifier(Type type) { Debug.Assert(_requiredModifiers == null); _requiredModifiersBuilder ??= new List<Type>(); _requiredModifiersBuilder.Add(type); } public void AddOptionalModifier(Type type) { Debug.Assert(_optionalModifiers == null); _optionalModifiersBuilder ??= new List<Type>(); _optionalModifiersBuilder.Add(type); } // Below are the multitude of Type overloads. We throw NSE for members that would return an unmodified Type // directly or indirectly. We do this in case we want to support returning modified types instead. public override Type[] GetRequiredCustomModifiers() { if (_requiredModifiers == null) { if (_requiredModifiersBuilder == null) { _requiredModifiers = EmptyTypes; } else { _requiredModifiers = _requiredModifiersBuilder.ToArray(); _requiredModifiersBuilder = null; } } return Helpers.CloneArray<Type>(_requiredModifiers); } public override Type[] GetOptionalCustomModifiers() { if (_optionalModifiers == null) { if (_optionalModifiersBuilder == null) { _optionalModifiers = EmptyTypes; } else { _optionalModifiers = _optionalModifiersBuilder.ToArray(); _optionalModifiersBuilder = null; } } return Helpers.CloneArray<Type>(_optionalModifiers); } public override Type UnderlyingSystemType => _unmodifiedType; // Modified types do not support Equals. That would need to include custom modifiers and any parameterized types recursively. // UnderlyingSystemType.Equals() should should be used if basic equality is necessary. public override bool Equals([NotNullWhen(true)] object? obj) => throw new NotSupportedException(SR.NotSupported_ModifiedType); public override bool Equals(Type? other) => throw new NotSupportedException(SR.NotSupported_ModifiedType); public override int GetHashCode() => throw new NotSupportedException(SR.NotSupported_ModifiedType); public override string ToString() => _unmodifiedType.ToString(); public sealed override bool IsEnum => _unmodifiedType.IsEnum; protected sealed override bool IsPrimitiveImpl() => _unmodifiedType.IsPrimitive; protected sealed override bool IsValueTypeImpl() => _unmodifiedType.IsValueType; public override bool IsTypeDefinition => _unmodifiedType.IsTypeDefinition; public override bool IsGenericTypeDefinition => _unmodifiedType.IsGenericTypeDefinition; protected override bool HasElementTypeImpl() => _unmodifiedType.Call_HasElementTypeImpl(); protected override bool IsArrayImpl() => _unmodifiedType.Call_IsArrayImpl(); public override bool IsSZArray => _unmodifiedType.IsSZArray; public override bool IsVariableBoundArray => _unmodifiedType.IsVariableBoundArray; protected override bool IsByRefImpl() => _unmodifiedType.Call_IsByRefImpl(); protected override bool IsPointerImpl() => _unmodifiedType.Call_IsPointerImpl(); public override bool IsFunctionPointer => _unmodifiedType.IsFunctionPointer; public override bool IsUnmanagedFunctionPointer => _unmodifiedType.IsUnmanagedFunctionPointer; public override bool IsConstructedGenericType => _unmodifiedType.IsConstructedGenericType; public override bool IsGenericParameter => _unmodifiedType.IsGenericParameter; public override bool IsGenericTypeParameter => _unmodifiedType.IsGenericTypeParameter; public override bool IsGenericMethodParameter => _unmodifiedType.IsGenericMethodParameter; public override bool ContainsGenericParameters => _unmodifiedType.ContainsGenericParameters; internal override RoModule GetRoModule() => _unmodifiedType.GetRoModule(); public override int GetArrayRank() => _unmodifiedType.GetArrayRank(); protected override string ComputeName() => _unmodifiedType.Call_ComputeName(); protected override string? ComputeNamespace() => _unmodifiedType.Call_ComputeNamespace(); protected override string? ComputeFullName() => _unmodifiedType.Call_ComputeFullName(); protected override TypeAttributes ComputeAttributeFlags() => _unmodifiedType.Call_ComputeAttributeFlags(); protected override TypeCode GetTypeCodeImpl() => _unmodifiedType.Call_GetTypeCodeImpl(); public override MethodBase? DeclaringMethod => throw new NotSupportedException(SR.NotSupported_ModifiedType); protected override RoType? ComputeDeclaringType() => throw new NotSupportedException(SR.NotSupported_ModifiedType); public override IEnumerable<TypeInfo> DeclaredNestedTypes { #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicNestedTypes)] #endif get { throw new NotSupportedException(SR.NotSupported_ModifiedType); } } public override IEnumerable<CustomAttributeData> CustomAttributes => _unmodifiedType.CustomAttributes; internal override bool IsCustomAttributeDefined(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name) => _unmodifiedType.IsCustomAttributeDefined(ns, name); internal override CustomAttributeData? TryFindCustomAttribute(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name) => _unmodifiedType.TryFindCustomAttribute(ns, name); public override int MetadataToken => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override RoType? GetRoElementType() => null; public override Type GetGenericTypeDefinition() => throw new NotSupportedException(SR.NotSupported_ModifiedType); #if NET11_0_OR_GREATER public override Type? GetNullableUnderlyingType() => _unmodifiedType.GetNullableUnderlyingType() is not null ? GetGenericArguments()[0] : null; #endif // Generic parameters are supported. internal override RoType[] GetGenericTypeParametersNoCopy() => _unmodifiedType.GetGenericTypeParametersNoCopy(); internal override RoType[] GetGenericTypeArgumentsNoCopy() => _unmodifiedType.GetGenericTypeArgumentsNoCopy(); protected internal override RoType[] GetGenericArgumentsNoCopy() => _unmodifiedType.GetGenericArgumentsNoCopy(); [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 override Type MakeGenericType(params Type[] typeArguments) => throw new NotSupportedException(SR.NotSupported_ModifiedType); public override Type GetFunctionPointerReturnType() => throw new InvalidOperationException(SR.InvalidOperation_NotFunctionPointer); public override Type[] GetFunctionPointerParameterTypes() => throw new InvalidOperationException(SR.InvalidOperation_NotFunctionPointer); public override GenericParameterAttributes GenericParameterAttributes => _unmodifiedType.GenericParameterAttributes; public override int GenericParameterPosition => _unmodifiedType.GenericParameterPosition; public override Type[] GetGenericParameterConstraints() => throw new NotSupportedException(SR.NotSupported_ModifiedType); public override Guid GUID => _unmodifiedType.GUID; public override StructLayoutAttribute? StructLayoutAttribute => _unmodifiedType.StructLayoutAttribute; protected internal override RoType ComputeEnumUnderlyingType() => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override RoType? ComputeBaseTypeWithoutDesktopQuirk() => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override IEnumerable<RoType> ComputeDirectlyImplementedInterfaces() => throw new NotSupportedException(SR.NotSupported_ModifiedType); // Low level support for the BindingFlag-driven enumerator apis. internal override IEnumerable<ConstructorInfo> GetConstructorsCore(NameFilter? filter) => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override IEnumerable<MethodInfo> GetMethodsCore(NameFilter? filter, Type reflectedType) => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override IEnumerable<EventInfo> GetEventsCore(NameFilter? filter, Type reflectedType) => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override IEnumerable<FieldInfo> GetFieldsCore(NameFilter? filter, Type reflectedType) => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override IEnumerable<PropertyInfo> GetPropertiesCore(NameFilter? filter, Type reflectedType) => throw new NotSupportedException(SR.NotSupported_ModifiedType); internal override IEnumerable<RoType> GetNestedTypesCore(NameFilter? filter) => throw new NotSupportedException(SR.NotSupported_ModifiedType); } }