Files
ft/Client/Packages/io.github.hatayama.uloopmcp/Editor/Execution/CompiledCommandEntryPointResolver.cs

155 lines
5.3 KiB
C#

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<string, object>), typeof(CancellationToken) },
null);
if (methodWithParametersAndCancellation != null)
{
return methodWithParametersAndCancellation;
}
MethodInfo methodWithParameters = type.GetMethod(
WrappedExecuteMethodName,
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[] { typeof(Dictionary<string, object>) },
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<string, object>), typeof(CancellationToken) },
null);
if (methodWithParametersAndCancellation != null)
{
return methodWithParametersAndCancellation;
}
MethodInfo methodWithParameters = type.GetMethod(
WrappedExecuteAsyncMethodName,
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[] { typeof(Dictionary<string, object>) },
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);
}
}
}