mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-20 00:06:45 +08:00
暂时实现了简陋的脚本AST分析解释,后面再绑定到控件上
This commit is contained in:
@@ -14,6 +14,20 @@ namespace Serein.Library.Utils
|
||||
/// </summary>
|
||||
public class EmitHelper
|
||||
{
|
||||
|
||||
public class EmitMethodInfo
|
||||
{
|
||||
public Type DeclaringType { get; set; }
|
||||
/// <summary>
|
||||
/// 是异步方法
|
||||
/// </summary>
|
||||
public bool IsTask { get; set; }
|
||||
/// <summary>
|
||||
/// 是静态的
|
||||
/// </summary>
|
||||
public bool IsStatic { get; set; }
|
||||
}
|
||||
|
||||
public enum EmitMethodType
|
||||
{
|
||||
/// <summary>
|
||||
@@ -28,6 +42,15 @@ namespace Serein.Library.Utils
|
||||
/// 有返回值的异步方法
|
||||
/// </summary>
|
||||
HasResultTask,
|
||||
|
||||
/// <summary>
|
||||
/// 普通的方法。如果方法返回void时,将会返回null。
|
||||
/// </summary>
|
||||
StaticFunc,
|
||||
/// <summary>
|
||||
/// 无返回值的异步方法
|
||||
/// </summary>
|
||||
StaticTask,
|
||||
}
|
||||
|
||||
public static bool IsGenericTask(Type returnType, out Type taskResult)
|
||||
@@ -60,17 +83,19 @@ namespace Serein.Library.Utils
|
||||
/// <param name="methodInfo"></param>
|
||||
/// <param name="delegate"></param>
|
||||
/// <returns></returns>
|
||||
public static EmitMethodType CreateDynamicMethod(MethodInfo methodInfo,out Delegate @delegate)
|
||||
public static EmitMethodInfo CreateDynamicMethod(MethodInfo methodInfo,out Delegate @delegate)
|
||||
{
|
||||
EmitMethodInfo emitMethodInfo = new EmitMethodInfo();
|
||||
bool IsTask = IsGenericTask(methodInfo.ReturnType, out var taskGenericsType);
|
||||
bool IsTaskGenerics = taskGenericsType != null;
|
||||
DynamicMethod dynamicMethod;
|
||||
|
||||
|
||||
Type returnType;
|
||||
if (!IsTask)
|
||||
{
|
||||
// 普通方法
|
||||
returnType = typeof(object);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -96,10 +121,19 @@ namespace Serein.Library.Utils
|
||||
|
||||
var il = dynamicMethod.GetILGenerator();
|
||||
|
||||
// 加载实例 (this)
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Castclass, methodInfo.DeclaringType); // 将 ISocketControlBase 转换为目标类类型
|
||||
// 判断是否为静态方法
|
||||
bool isStatic = methodInfo.IsStatic;
|
||||
|
||||
if (isStatic)
|
||||
{
|
||||
// 如果是静态方法,直接跳过实例(不加载Ldarg_0)
|
||||
}
|
||||
else
|
||||
{
|
||||
// 加载实例 (this) 对于非静态方法
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Castclass, methodInfo.DeclaringType); // 将 ISocketControlBase 转换为目标类类型
|
||||
}
|
||||
// 加载方法参数
|
||||
var methodParams = methodInfo.GetParameters();
|
||||
for (int i = 0; i < methodParams.Length; i++)
|
||||
@@ -122,11 +156,17 @@ namespace Serein.Library.Utils
|
||||
il.Emit(OpCodes.Castclass, paramType);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 调用方法
|
||||
il.Emit(OpCodes.Callvirt, methodInfo);
|
||||
// 调用方法:静态方法使用 Call,实例方法使用 Callvirt
|
||||
if (isStatic)
|
||||
{
|
||||
il.Emit(OpCodes.Call, methodInfo); // 对于静态方法,使用 Call
|
||||
}
|
||||
else
|
||||
{
|
||||
il.Emit(OpCodes.Callvirt, methodInfo); // 对于实例方法,使用 Callvirt
|
||||
}
|
||||
|
||||
//// 处理返回值,如果没有返回值,则返回null
|
||||
if (methodInfo.ReturnType == typeof(void))
|
||||
@@ -139,27 +179,28 @@ namespace Serein.Library.Utils
|
||||
}
|
||||
// 处理返回值,如果没有返回值,则返回null
|
||||
il.Emit(OpCodes.Ret); // 返回
|
||||
EmitMethodType emitMethodType;
|
||||
if (IsTask)
|
||||
{
|
||||
if (IsTaskGenerics)
|
||||
{
|
||||
emitMethodType = EmitMethodType.HasResultTask;
|
||||
@delegate = dynamicMethod.CreateDelegate(typeof(Func<object, object[], Task<object>>));
|
||||
}
|
||||
else
|
||||
{
|
||||
emitMethodType = EmitMethodType.Task;
|
||||
@delegate = dynamicMethod.CreateDelegate(typeof(Func<object, object[], Task>));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emitMethodType = EmitMethodType.Func;
|
||||
@delegate = dynamicMethod.CreateDelegate(typeof(Func<object, object[], object>));
|
||||
|
||||
}
|
||||
return emitMethodType;
|
||||
return new EmitMethodInfo
|
||||
{
|
||||
DeclaringType = methodInfo.DeclaringType,
|
||||
IsTask = IsTask,
|
||||
IsStatic = isStatic
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user