| File: System\Reflection\Runtime\MethodInfos\CustomMethodMapper.cs | Web Access |
| Project: src\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.csproj (System.Private.CoreLib) |
// 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 Internal.Reflection.Core.Execution; namespace System.Reflection.Runtime.MethodInfos { internal static partial class CustomMethodMapper { // // Certain types and methods are edge-cases that require special handling. // public static MethodBaseInvoker GetCustomMethodInvokerIfNeeded(this MethodBase methodBase) { Type declaringType = methodBase.DeclaringType!; bool isNullable = declaringType.IsConstructedGenericType && declaringType.GetGenericTypeDefinition() == typeof(Nullable<>); Dictionary<MethodBase, CustomMethodInvokerAction> map; if (isNullable) map = NullableActions.Map; else if (declaringType == typeof(string)) map = StringActions.Map; else return null; if (!map.TryGetValue(methodBase.MetadataDefinitionMethod, out CustomMethodInvokerAction? action)) return null; ReadOnlySpan<ParameterInfo> parameterInfos = methodBase.GetParametersAsSpan(); Type[] parameterTypes = new Type[parameterInfos.Length]; for (int i = 0; i < parameterInfos.Length; i++) { parameterTypes[i] = parameterInfos[i].ParameterType; } InvokerOptions options = (methodBase.IsStatic || methodBase is ConstructorInfo || isNullable) ? InvokerOptions.AllowNullThis : InvokerOptions.None; return new CustomMethodInvoker(declaringType, parameterTypes, options, action); } private static void AddConstructor(this Dictionary<MethodBase, CustomMethodInvokerAction> map, Type declaringType, Type[] parameterTypes, CustomMethodInvokerAction action) { map.AddMethod(declaringType, ConstructorInfo.ConstructorName, parameterTypes, action); } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", Justification = "GetConstructor/GetMethod being null is handled and expected.")] private static void AddMethod(this Dictionary<MethodBase, CustomMethodInvokerAction> map, Type declaringType, string name, Type[] parameterTypes, CustomMethodInvokerAction action) { const BindingFlags bf = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.ExactBinding; MethodBase? methodBase; if (name == ConstructorInfo.ConstructorName) { methodBase = declaringType.GetConstructor(bf, null, parameterTypes, null); } else { methodBase = declaringType.GetMethod(name, 0, bf, parameterTypes); } if (methodBase == null) return; // If we got here, this specific member was not included in the metadata. Debug.Assert(methodBase == methodBase.MetadataDefinitionMethod); map.Add(methodBase, action); } } }