| File: System\Reflection\TypeLoading\Types\RoFunctionPointerType.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.Collections.Immutable; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection.Metadata; using System.Reflection.TypeLoading.Ecma; using System.Text; using StructLayoutAttribute = System.Runtime.InteropServices.StructLayoutAttribute; namespace System.Reflection.TypeLoading { /// <summary> /// All RoTypes that return true for IsFunctionPointer. /// </summary> internal sealed class RoFunctionPointerType : RoType { private readonly EcmaModule _module; private readonly SignatureCallingConvention _callKind; private readonly bool _isUnmanaged; internal readonly Type _returnType; internal readonly Type[] _parameterTypes; private string? _toString; private string GetToString() => _toString ??= ComputeToString(); internal RoFunctionPointerType(EcmaModule module, MethodSignature<RoType> signature) { Debug.Assert(module != null); _module = module; _returnType = signature.ReturnType; ImmutableArray<RoType> sigParameterTypes = signature.ParameterTypes; _parameterTypes = new RoType[sigParameterTypes.Length]; for (int i = 0; i < sigParameterTypes.Length; i++) { _parameterTypes[i] = sigParameterTypes[i]; } _callKind = GetCallingConvention(signature, out _isUnmanaged); } public sealed override bool IsFunctionPointer => true; public sealed override bool IsUnmanagedFunctionPointer => _isUnmanaged; public sealed override Type GetFunctionPointerReturnType() => _returnType.UnderlyingSystemType; public sealed override Type[] GetFunctionPointerParameterTypes() => _parameterTypes.CloneArrayToUnmodifiedTypes(); protected sealed override string? ComputeFullName() => null; protected sealed override string ComputeName() => string.Empty; internal static SignatureCallingConvention GetCallingConvention(MethodSignature<RoType> signature, out bool isUnmanaged) { SignatureCallingConvention callKind = signature.Header.CallingConvention; isUnmanaged = false; switch (callKind) { case SignatureCallingConvention.CDecl: case SignatureCallingConvention.StdCall: case SignatureCallingConvention.ThisCall: case SignatureCallingConvention.FastCall: case SignatureCallingConvention.Unmanaged: isUnmanaged = true; break; } return callKind; } internal SignatureCallingConvention CallKind => _callKind; private string ComputeToString() { Type t = _returnType; StringBuilder sb = new(t.ToString()); sb.Append('('); AppendParameters(sb); sb.Append(')'); return sb.ToString(); void AppendParameters(StringBuilder sb) { for (int i = 0; i < _parameterTypes.Length; i++) { if (i != 0) { sb.Append(", "); } sb.Append(_parameterTypes[i].ToString()); } } } protected sealed override string? ComputeNamespace() => null; public sealed override string ToString() => GetToString(); public sealed override string? AssemblyQualifiedName => null; internal sealed override RoModule GetRoModule() => _module; public sealed override int GetHashCode() { return ToString().GetHashCode(); } public sealed override bool Equals([NotNullWhen(true)] Type? type) => Equals((object?)type); public sealed override bool Equals([NotNullWhen(true)] object? obj) { // Treat as an unmodified type; do not not include the modified type values including // calling conventions and custom modifiers. if (obj is not RoFunctionPointerType other) return false; if (GetFunctionPointerReturnType() != other.GetFunctionPointerReturnType()) return false; if (IsUnmanagedFunctionPointer != other.IsUnmanagedFunctionPointer) return false; Type[] args = GetFunctionPointerParameterTypes(); Type[] otherArgs = other.GetFunctionPointerParameterTypes(); if (!args.Length.Equals(otherArgs.Length)) return false; for (int i = 0; i < args.Length; i++) { if (args[i] != otherArgs[i]) return false; } return true; } public sealed override bool IsTypeDefinition => false; public sealed override bool IsGenericTypeDefinition => false; 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 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 { get { if (_returnType.ContainsGenericParameters) return true; foreach (Type parameterType in _parameterTypes) { if (parameterType.ContainsGenericParameters) return true; } return false; } } protected sealed override TypeCode GetTypeCodeImpl() => TypeCode.Object; public sealed override int GetArrayRank() => throw new ArgumentException(SR.Argument_HasToBeArrayClass); public sealed override MethodBase DeclaringMethod => throw new InvalidOperationException(SR.Arg_NotGenericParameter); protected sealed override RoType? ComputeDeclaringType() => null; public sealed override IEnumerable<CustomAttributeData> CustomAttributes => Array.Empty<CustomAttributeData>(); internal sealed override bool IsCustomAttributeDefined(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name) => false; internal sealed override CustomAttributeData? TryFindCustomAttribute(ReadOnlySpan<byte> ns, ReadOnlySpan<byte> name) => null; public sealed override int MetadataToken => 0x02000000; // nil TypeDef token internal sealed override RoType? GetRoElementType() => null; public sealed override Type GetGenericTypeDefinition() => throw new InvalidOperationException(SR.InvalidOperation_NotGenericType); internal sealed override RoType[] GetGenericTypeParametersNoCopy() => Array.Empty<RoType>(); internal sealed override RoType[] GetGenericTypeArgumentsNoCopy() => Array.Empty<RoType>(); protected internal sealed override RoType[] GetGenericArgumentsNoCopy() => Array.Empty<RoType>(); [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) => throw new InvalidOperationException(SR.Format(SR.Arg_NotGenericTypeDefinition, this)); 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 Guid GUID => Guid.Empty; public sealed override StructLayoutAttribute? StructLayoutAttribute => null; protected internal sealed override RoType ComputeEnumUnderlyingType() => throw new ArgumentException(SR.Arg_MustBeEnum); // Low level support for the BindingFlag-driven enumerator apis. internal sealed override IEnumerable<EventInfo> GetEventsCore(NameFilter? filter, Type reflectedType) => Array.Empty<EventInfo>(); internal sealed override IEnumerable<FieldInfo> GetFieldsCore(NameFilter? filter, Type reflectedType) => Array.Empty<FieldInfo>(); internal sealed override IEnumerable<PropertyInfo> GetPropertiesCore(NameFilter? filter, Type reflectedType) => Array.Empty<PropertyInfo>(); internal sealed override IEnumerable<RoType> GetNestedTypesCore(NameFilter? filter) => Array.Empty<RoType>(); protected sealed override TypeAttributes ComputeAttributeFlags() => TypeAttributes.Public; internal sealed override RoType? ComputeBaseTypeWithoutDesktopQuirk() => null; internal sealed override IEnumerable<RoType> ComputeDirectlyImplementedInterfaces() => Array.Empty<RoType>(); internal sealed override IEnumerable<ConstructorInfo> GetConstructorsCore(NameFilter? filter) => Array.Empty<ConstructorInfo>(); internal sealed override IEnumerable<MethodInfo> GetMethodsCore(NameFilter? filter, Type reflectedType) => Array.Empty<MethodInfo>(); } }