using System; using System.Collections.Generic; using System.Reflection; using System.Threading; using Assembly = System.Reflection.Assembly; namespace io.github.hatayama.uLoopMCP { internal sealed class CompiledCommandEntryPointResolver { private const string WrappedExecuteMethodName = "Execute"; private const string WrappedExecuteAsyncMethodName = "ExecuteAsync"; public (Type targetType, MethodInfo executeMethod) TryFindExecuteMethod(Assembly assembly) { Type wrappedType = assembly.GetType( $"{DynamicCodeConstants.DEFAULT_NAMESPACE}.{DynamicCodeConstants.DEFAULT_CLASS_NAME}", false); if (wrappedType != null) { MethodInfo directMethod = FindPreferredExecuteMethod(wrappedType); if (directMethod != null) { return (wrappedType, directMethod); } } Type[] types = assembly.GetTypes(); foreach (Type type in types) { MethodInfo method = FindPreferredExecuteMethod(type); if (method != null) { return (type, method); } } return (null, null); } private static MethodInfo FindPreferredExecuteMethod(Type type) { MethodInfo methodWithParametersAndCancellation = type.GetMethod( WrappedExecuteMethodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(Dictionary), typeof(CancellationToken) }, null); if (methodWithParametersAndCancellation != null) { return methodWithParametersAndCancellation; } MethodInfo methodWithParameters = type.GetMethod( WrappedExecuteMethodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(Dictionary) }, null); if (methodWithParameters != null) { return methodWithParameters; } MethodInfo methodWithCancellation = type.GetMethod( WrappedExecuteMethodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(CancellationToken) }, null); if (methodWithCancellation != null) { return methodWithCancellation; } return type.GetMethod( WrappedExecuteMethodName, BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); } public (Type targetType, MethodInfo executeAsyncMethod) TryFindExecuteAsyncMethod(Assembly assembly) { Type wrappedType = assembly.GetType( $"{DynamicCodeConstants.DEFAULT_NAMESPACE}.{DynamicCodeConstants.DEFAULT_CLASS_NAME}", false); if (wrappedType != null) { MethodInfo directMethod = FindPreferredExecuteAsyncMethod(wrappedType); if (directMethod != null) { return (wrappedType, directMethod); } } Type[] types = assembly.GetTypes(); foreach (Type type in types) { MethodInfo method = FindPreferredExecuteAsyncMethod(type); if (method != null) { return (type, method); } } return (null, null); } private static MethodInfo FindPreferredExecuteAsyncMethod(Type type) { MethodInfo methodWithParametersAndCancellation = type.GetMethod( WrappedExecuteAsyncMethodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(Dictionary), typeof(CancellationToken) }, null); if (methodWithParametersAndCancellation != null) { return methodWithParametersAndCancellation; } MethodInfo methodWithParameters = type.GetMethod( WrappedExecuteAsyncMethodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(Dictionary) }, null); if (methodWithParameters != null) { return methodWithParameters; } MethodInfo methodWithCancellation = type.GetMethod( WrappedExecuteAsyncMethodName, BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(CancellationToken) }, null); if (methodWithCancellation != null) { return methodWithCancellation; } return type.GetMethod( WrappedExecuteAsyncMethodName, BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); } } }