mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-04-26 01:37:54 +08:00
1. 新增了脚本节点之间连接时,入参类型伴随来源节点的返回类型改变而改变。
2. 重新优化了Script项目脚本生成代码的缩进排版 3. 修复了Script中对于Double字面量错误的使用了Float解析的bug
This commit is contained in:
@@ -27,13 +27,15 @@ namespace Serein.Library
|
|||||||
RunState = RunState.Running;
|
RunState = RunState.Running;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _guid = global::System.Guid.NewGuid().ToString();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否记录流程调用信息
|
/// 是否记录流程调用信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsRecordInvokeInfo { get; set; } = true;
|
public bool IsRecordInvokeInfo { get; set; } = true;
|
||||||
string IFlowContext.Guid => _guid;
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标识流程的Guid
|
||||||
|
/// </summary>
|
||||||
|
public string Guid { get; private set; } = global::System.Guid.NewGuid().ToString();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 运行环境
|
/// 运行环境
|
||||||
@@ -97,7 +99,7 @@ namespace Serein.Library
|
|||||||
|
|
||||||
FlowInvokeInfo flowInvokeInfo = new FlowInvokeInfo
|
FlowInvokeInfo flowInvokeInfo = new FlowInvokeInfo
|
||||||
{
|
{
|
||||||
ContextGuid = this._guid,
|
ContextGuid = this.Guid,
|
||||||
Id = id,
|
Id = id,
|
||||||
PreviousNodeGuid = previousNode?.Guid,
|
PreviousNodeGuid = previousNode?.Guid,
|
||||||
Method = theNode.MethodDetails?.MethodName,
|
Method = theNode.MethodDetails?.MethodName,
|
||||||
@@ -258,7 +260,7 @@ namespace Serein.Library
|
|||||||
NextOrientation = ConnectionInvokeType.None;
|
NextOrientation = ConnectionInvokeType.None;
|
||||||
RunState = RunState.Running;
|
RunState = RunState.Running;
|
||||||
flowInvokeInfos.Clear();
|
flowInvokeInfos.Clear();
|
||||||
_guid = global::System.Guid.NewGuid().ToString();
|
Guid = global::System.Guid.NewGuid().ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
|
|
||||||
};
|
};
|
||||||
this.MethodDetails.ParameterDetailss = [.. pd];
|
this.MethodDetails.ParameterDetailss = [.. pd];
|
||||||
|
this.MethodDetails.ReturnType = typeof(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -103,14 +104,12 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
{
|
{
|
||||||
if(token.IsCancellationRequested) return FlowResult.Fail(this.Guid, context, "流程已通过token取消");
|
if(token.IsCancellationRequested) return FlowResult.Fail(this.Guid, context, "流程已通过token取消");
|
||||||
|
|
||||||
object? parameter = null;// context.TransmissionData(this); // 表达式节点使用上一节点数据
|
object? parameter = null;// 表达式节点使用上一节点数据
|
||||||
var pd = MethodDetails.ParameterDetailss[0];
|
var pd = MethodDetails.ParameterDetailss[0];
|
||||||
|
|
||||||
var hasNode = context.Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var argSourceNode);
|
var hasNode = context.Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var argSourceNode);
|
||||||
if (!hasNode)
|
if (!hasNode)
|
||||||
{
|
{
|
||||||
/*context.NextOrientation = ConnectionInvokeType.IsError;
|
|
||||||
return new FlowResult(this.Guid, context);*/
|
|
||||||
parameter = null;
|
parameter = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -130,14 +129,6 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
parameter = result.Value;
|
parameter = result.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 条件节点透传上一节点的数据
|
|
||||||
parameter = context.TransmissionData(this.Guid);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await GetValueExpressionAsync(context, parameter, Expression);
|
var result = await GetValueExpressionAsync(context, parameter, Expression);
|
||||||
@@ -179,17 +170,18 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
// 表达式默认包含 “.”
|
// 表达式默认包含 “.”
|
||||||
expression = $"return {expression};";
|
expression = $"return {expression};";
|
||||||
}
|
}
|
||||||
var resultType = getValueScript .ParserScript(expression, new Dictionary<string, Type>
|
var resultType = getValueScript.ParserScript(expression, new Dictionary<string, Type>
|
||||||
{
|
{
|
||||||
{ dataName, dataType},
|
{ dataName, dataType},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext(flowContext);
|
IScriptInvokeContext scriptContext = new ScriptInvokeContext(flowContext);
|
||||||
scriptContext.SetVarValue(dataName, data);
|
scriptContext.SetVarValue(dataName, data);
|
||||||
|
|
||||||
var result = await getValueScript .InterpreterAsync(scriptContext);
|
var result = await getValueScript.InterpreterAsync(scriptContext);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
public SingleScriptNode(IFlowEnvironment environment) : base(environment)
|
public SingleScriptNode(IFlowEnvironment environment) : base(environment)
|
||||||
{
|
{
|
||||||
sereinScript = new SereinScript();
|
sereinScript = new SereinScript();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SingleScriptNode()
|
static SingleScriptNode()
|
||||||
@@ -78,9 +79,9 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
IsScriptChanged = true;
|
IsScriptChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点创建时
|
/// 节点创建时
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void OnCreating()
|
public override void OnCreating()
|
||||||
{
|
{
|
||||||
var md = MethodDetails;
|
var md = MethodDetails;
|
||||||
@@ -106,6 +107,38 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新节点返回类型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newType"></param>
|
||||||
|
private void UploadNodeReturnType(Type newType)
|
||||||
|
{
|
||||||
|
MethodDetails.ReturnType = newType;
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var ct in NodeStaticConfig.ConnectionArgSourceTypes)
|
||||||
|
{
|
||||||
|
var newResultNodes = NeedResultNodes[ct].ToArray();
|
||||||
|
foreach (var node in newResultNodes)
|
||||||
|
{
|
||||||
|
if(node is SingleScriptNode scriptNode)
|
||||||
|
{
|
||||||
|
var pds = scriptNode.MethodDetails.ParameterDetailss;
|
||||||
|
foreach (var pd in pds)
|
||||||
|
{
|
||||||
|
if (pd.ArgDataSourceType == ct &&
|
||||||
|
pd.ArgDataSourceNodeGuid == this.Guid)
|
||||||
|
{
|
||||||
|
pd.DataType = newType; // 更新参数类型
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//scriptNode.ReloadScript(); // 重新加载目标脚本节点
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 保存项目时保存脚本代码、方法入参类型、返回值类型
|
/// 保存项目时保存脚本代码、方法入参类型、返回值类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -181,58 +214,77 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private object reloadLockObj = new object();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 重新加载脚本代码
|
/// 重新加载脚本代码
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ReloadScript()
|
public bool ReloadScript()
|
||||||
{
|
{
|
||||||
try
|
lock (reloadLockObj)
|
||||||
{
|
{
|
||||||
HashSet<string> varNames = new HashSet<string>();
|
if (!CheckRepeatParamter())
|
||||||
foreach (var pd in MethodDetails.ParameterDetailss)
|
return false;
|
||||||
|
var argTypes = GetParamterTypeInfo();
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (varNames.Contains(pd.Name))
|
var returnType = sereinScript.ParserScript(Script, argTypes); // 开始解析获取程序主节点
|
||||||
{
|
UploadNodeReturnType(returnType);
|
||||||
throw new Exception($"脚本节点重复的变量名称:{pd.Name} - {Guid}");
|
}
|
||||||
}
|
catch (Exception ex)
|
||||||
varNames.Add(pd.Name);
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.WARN, ex.Message);
|
||||||
|
return false; // 解析失败
|
||||||
}
|
}
|
||||||
|
|
||||||
var argTypes = MethodDetails.ParameterDetailss
|
|
||||||
.Select(pd =>
|
|
||||||
{
|
|
||||||
if (pd.ArgDataSourceType == ConnectionArgSourceType.GetPreviousNodeData)
|
|
||||||
{
|
|
||||||
var Type = pd.DataType;
|
|
||||||
return (pd.Name, Type);
|
|
||||||
}
|
|
||||||
if (Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var node) &&
|
|
||||||
node.MethodDetails?.ReturnType is not null)
|
|
||||||
{
|
|
||||||
pd.DataType = node.MethodDetails.ReturnType;
|
|
||||||
var Type = node.MethodDetails.ReturnType;
|
|
||||||
return (pd.Name, Type);
|
|
||||||
}
|
|
||||||
return default;
|
|
||||||
})
|
|
||||||
.Where(x => x != default)
|
|
||||||
.ToDictionary(x => x.Name, x => x.Type); // 准备预定义类型
|
|
||||||
|
|
||||||
|
|
||||||
var returnType = sereinScript.ParserScript(Script, argTypes); // 开始解析获取程序主节点
|
|
||||||
MethodDetails.ReturnType = returnType;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
SereinEnv.WriteLine(InfoType.WARN, ex.Message);
|
|
||||||
return false; // 解析失败
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查脚本参数是否有重复的名称
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool CheckRepeatParamter()
|
||||||
|
{
|
||||||
|
bool isSueccess = true;
|
||||||
|
HashSet<string> varNames = new HashSet<string>();
|
||||||
|
foreach (var pd in MethodDetails.ParameterDetailss)
|
||||||
|
{
|
||||||
|
if (varNames.Contains(pd.Name))
|
||||||
|
{
|
||||||
|
SereinEnv.WriteLine(InfoType.ERROR, $"脚本节点重复的变量名称:{pd.Name} - {Guid}");
|
||||||
|
|
||||||
|
isSueccess = false;
|
||||||
|
}
|
||||||
|
varNames.Add(pd.Name);
|
||||||
|
}
|
||||||
|
return isSueccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取参数类型信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private Dictionary<string, Type> GetParamterTypeInfo()
|
||||||
|
{
|
||||||
|
Dictionary<string, Type> argTypes = [];
|
||||||
|
var pds = MethodDetails.ParameterDetailss.ToArray();
|
||||||
|
foreach (var pd in pds)
|
||||||
|
{
|
||||||
|
if (pd.ArgDataSourceType == ConnectionArgSourceType.GetPreviousNodeData)
|
||||||
|
{
|
||||||
|
argTypes[pd.Name] = pd.DataType;
|
||||||
|
}
|
||||||
|
if (Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var node) &&
|
||||||
|
node.MethodDetails?.ReturnType is not null)
|
||||||
|
{
|
||||||
|
pd.DataType = node.MethodDetails.ReturnType;
|
||||||
|
var Type = node.MethodDetails.ReturnType;
|
||||||
|
argTypes[pd.Name] = Type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return argTypes;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 转换为 C# 代码,并且附带方法信息
|
/// 转换为 C# 代码,并且附带方法信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -246,39 +298,11 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
methodName = $"FlowMethod_{tmp}";
|
methodName = $"FlowMethod_{tmp}";
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet<string> varNames = new HashSet<string>();
|
if (!CheckRepeatParamter())
|
||||||
foreach (var pd in MethodDetails.ParameterDetailss)
|
throw new Exception($"脚本节点入参重复");
|
||||||
{
|
var argTypes = GetParamterTypeInfo();
|
||||||
if (varNames.Contains(pd.Name))
|
|
||||||
{
|
|
||||||
throw new Exception($"脚本节点重复的变量名称:{pd.Name} - {Guid}");
|
|
||||||
}
|
|
||||||
varNames.Add(pd.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
var argTypes = MethodDetails.ParameterDetailss
|
|
||||||
.Select(pd =>
|
|
||||||
{
|
|
||||||
if(pd.ArgDataSourceType == ConnectionArgSourceType.GetPreviousNodeData)
|
|
||||||
{
|
|
||||||
var Type = pd.DataType;
|
|
||||||
return (pd.Name, Type);
|
|
||||||
}
|
|
||||||
if (Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var node) &&
|
|
||||||
node.MethodDetails?.ReturnType is not null)
|
|
||||||
{
|
|
||||||
pd.DataType = node.MethodDetails.ReturnType;
|
|
||||||
var Type = node.MethodDetails.ReturnType;
|
|
||||||
return (pd.Name, Type);
|
|
||||||
}
|
|
||||||
return default;
|
|
||||||
})
|
|
||||||
.Where(x => x != default)
|
|
||||||
.ToDictionary(x => x.Name, x => x.Type); // 准备预定义类型
|
|
||||||
|
|
||||||
|
|
||||||
var returnType = sereinScript.ParserScript(Script, argTypes); // 开始解析获取程序主节点
|
var returnType = sereinScript.ParserScript(Script, argTypes); // 开始解析获取程序主节点
|
||||||
MethodDetails.ReturnType = returnType;
|
UploadNodeReturnType(returnType);
|
||||||
var scriptMethodInfo = sereinScript.ConvertCSharpCode(methodName, argTypes);
|
var scriptMethodInfo = sereinScript.ConvertCSharpCode(methodName, argTypes);
|
||||||
return scriptMethodInfo;
|
return scriptMethodInfo;
|
||||||
}
|
}
|
||||||
@@ -297,6 +321,13 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
public override async Task<FlowResult> ExecutingAsync(IFlowContext context, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
if (IsScriptChanged)
|
||||||
|
{
|
||||||
|
if (!ReloadScript())
|
||||||
|
{
|
||||||
|
return FlowResult.Fail(this.Guid, context, "脚本解析失败,请检查脚本代码");
|
||||||
|
}
|
||||||
|
}
|
||||||
var result = await ExecutingAsync(this, context, token);
|
var result = await ExecutingAsync(this, context, token);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -311,6 +342,14 @@ namespace Serein.NodeFlow.Model.Nodes
|
|||||||
public async Task<FlowResult> ExecutingAsync(NodeModelBase flowCallNode, IFlowContext context, CancellationToken token)
|
public async Task<FlowResult> ExecutingAsync(NodeModelBase flowCallNode, IFlowContext context, CancellationToken token)
|
||||||
{
|
{
|
||||||
if (token.IsCancellationRequested) return FlowResult.Fail(this.Guid, context, "流程已通过token取消");
|
if (token.IsCancellationRequested) return FlowResult.Fail(this.Guid, context, "流程已通过token取消");
|
||||||
|
if (IsScriptChanged)
|
||||||
|
{
|
||||||
|
if (!ReloadScript())
|
||||||
|
{
|
||||||
|
return FlowResult.Fail(this.Guid, context, "脚本解析失败,请检查脚本代码");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var @params = await flowCallNode.GetParametersAsync(context, token);
|
var @params = await flowCallNode.GetParametersAsync(context, token);
|
||||||
|
|
||||||
IScriptInvokeContext scriptContext = new ScriptInvokeContext(context);
|
IScriptInvokeContext scriptContext = new ScriptInvokeContext(context);
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ namespace Serein.NodeFlow.Model.Operations
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ToNode.ControlType is not (NodeControlType.GlobalData or NodeControlType.ExpCondition or NodeControlType.ExpOp))
|
if (ToNode.ControlType is not (NodeControlType.GlobalData or NodeControlType.ExpCondition or NodeControlType.ExpOp))
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -199,6 +200,7 @@ namespace Serein.NodeFlow.Model.Operations
|
|||||||
}
|
}
|
||||||
if (ToNode.MethodDetails.ParameterDetailss.Length > 0)
|
if (ToNode.MethodDetails.ParameterDetailss.Length > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
var fromNoeReturnType = fromNode.MethodDetails.ReturnType;
|
var fromNoeReturnType = fromNode.MethodDetails.ReturnType;
|
||||||
if (fromNoeReturnType != null
|
if (fromNoeReturnType != null
|
||||||
&& fromNoeReturnType != typeof(object)
|
&& fromNoeReturnType != typeof(object)
|
||||||
@@ -206,24 +208,33 @@ namespace Serein.NodeFlow.Model.Operations
|
|||||||
&& fromNoeReturnType != typeof(Unit))
|
&& fromNoeReturnType != typeof(Unit))
|
||||||
{
|
{
|
||||||
var toNodePds = toNode.MethodDetails.ParameterDetailss;
|
var toNodePds = toNode.MethodDetails.ParameterDetailss;
|
||||||
foreach (ParameterDetails toNodePd in toNodePds)
|
if (toNodePds.Any(pd=>pd.IsExplicitData))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(toNodePd.ArgDataSourceNodeGuid) // 入参没有设置数据来源节点
|
checkTypeState = true; // 目标节点使用了显式的入参,无需关心参数是否匹配
|
||||||
&& toNodePd.DataType.IsAssignableFrom(fromNoeReturnType)) // 返回值与目标入参相同(或可转换为目标入参)
|
|
||||||
{
|
|
||||||
|
|
||||||
toPds.Add(toNodePd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (toPds.Count == 0)
|
|
||||||
{
|
|
||||||
var any = toNodePds.Any(pd => pd.ArgDataSourceNodeGuid == fromNode.Guid); // 判断目标节点是否已有该节点的连接
|
|
||||||
checkTypeState = any;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
checkTypeState = true; // 类型检查初步通过
|
foreach (ParameterDetails toNodePd in toNodePds)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(toNodePd.ArgDataSourceNodeGuid) // 入参没有设置数据来源节点
|
||||||
|
&& toNodePd.DataType.IsAssignableFrom(fromNoeReturnType)) // 返回值与目标入参相同(或可转换为目标入参)
|
||||||
|
{
|
||||||
|
|
||||||
|
toPds.Add(toNodePd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toPds.Count == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
var any = toNodePds.Any(pd => pd.ArgDataSourceNodeGuid == fromNode.Guid); // 判断目标节点是否已有该节点的连接
|
||||||
|
checkTypeState = any;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checkTypeState = true; // 类型检查初步通过
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,23 +27,23 @@ namespace Serein.Script.Node
|
|||||||
public class NumberIntNode(int vlaue) : NumberNode<int>(vlaue)
|
public class NumberIntNode(int vlaue) : NumberNode<int>(vlaue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// int 整数型字面量
|
/// long 整数型字面量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NumberLongNode(long vlaue) : NumberNode<long>(vlaue)
|
public class NumberLongNode(long vlaue) : NumberNode<long>(vlaue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// int 整数型字面量
|
/// float 字面量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NumberFloatNode(float vlaue) : NumberNode<float>(vlaue)
|
public class NumberFloatNode(float vlaue) : NumberNode<float>(vlaue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// int 整数型字面量
|
/// double 字面量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NumberDoubleNode(double vlaue) : NumberNode<double>(vlaue)
|
public class NumberDoubleNode(double vlaue) : NumberNode<double>(vlaue)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -321,11 +321,11 @@ namespace Serein.Script
|
|||||||
async Task<object?> InterpreterFunctionCallNodeAsync(IScriptInvokeContext context, FunctionCallNode functionCallNode)
|
async Task<object?> InterpreterFunctionCallNodeAsync(IScriptInvokeContext context, FunctionCallNode functionCallNode)
|
||||||
{
|
{
|
||||||
// 获取流程上下文
|
// 获取流程上下文
|
||||||
if (context.FlowContext != null && functionCallNode.FunctionName.Equals("getFlowApi", StringComparison.OrdinalIgnoreCase))
|
if (context.FlowContext != null && functionCallNode.FunctionName.Equals("getFlowContext", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return context.FlowContext;
|
return context.FlowContext;
|
||||||
}
|
}
|
||||||
else if (functionCallNode.FunctionName.Equals("getScriptApi", StringComparison.OrdinalIgnoreCase))
|
else if (functionCallNode.FunctionName.Equals("getScriptContext", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1087,7 +1087,7 @@ namespace Serein.Script
|
|||||||
}
|
}
|
||||||
else if (_currentToken.Type == TokenType.NumberDouble)
|
else if (_currentToken.Type == TokenType.NumberDouble)
|
||||||
{
|
{
|
||||||
var value = float.Parse(_currentToken.Value);
|
var value = double.Parse(_currentToken.Value);
|
||||||
NextToken(); // 消耗 double 浮点数
|
NextToken(); // 消耗 double 浮点数
|
||||||
return new NumberDoubleNode(value).SetTokenInfo(factorToken);
|
return new NumberDoubleNode(value).SetTokenInfo(factorToken);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Serein.Script
|
|||||||
{
|
{
|
||||||
public const string ClassName = nameof(SereinScriptToCsharpScript);
|
public const string ClassName = nameof(SereinScriptToCsharpScript);
|
||||||
|
|
||||||
public SereinScriptMethodInfo sereinScriptMethodInfo ;
|
public SereinScriptMethodInfo sereinScriptMethodInfo;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 符号表
|
/// 符号表
|
||||||
@@ -51,6 +51,13 @@ namespace Serein.Script
|
|||||||
_codeBuilder.Append(code);
|
_codeBuilder.Append(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CompleteCurrentStatement()
|
||||||
|
{
|
||||||
|
_codeBuilder.Append($";{Environment.NewLine}");
|
||||||
|
|
||||||
|
}
|
||||||
|
private string Tab => new string (' ', _indentLevel* 4);
|
||||||
|
|
||||||
private void Indent() => _indentLevel++;
|
private void Indent() => _indentLevel++;
|
||||||
private void Unindent() => _indentLevel--;
|
private void Unindent() => _indentLevel--;
|
||||||
|
|
||||||
@@ -67,7 +74,7 @@ namespace Serein.Script
|
|||||||
};
|
};
|
||||||
var sb = _codeBuilder;
|
var sb = _codeBuilder;
|
||||||
var methodResultType = _symbolInfos[programNode];
|
var methodResultType = _symbolInfos[programNode];
|
||||||
if(methodResultType == typeof(void))
|
if (methodResultType == typeof(void))
|
||||||
{
|
{
|
||||||
methodResultType = typeof(object);
|
methodResultType = typeof(object);
|
||||||
}
|
}
|
||||||
@@ -85,9 +92,9 @@ namespace Serein.Script
|
|||||||
}
|
}
|
||||||
|
|
||||||
AppendLine($"public partial class {ClassName}");
|
AppendLine($"public partial class {ClassName}");
|
||||||
AppendLine( "{");
|
AppendLine("{");
|
||||||
Indent();
|
Indent();
|
||||||
if(param is null || param.Count == 0)
|
if (param is null || param.Count == 0)
|
||||||
{
|
{
|
||||||
// 生成方法签名
|
// 生成方法签名
|
||||||
AppendLine($"public static {returnContent} {mehtodName}()");
|
AppendLine($"public static {returnContent} {mehtodName}()");
|
||||||
@@ -97,15 +104,15 @@ namespace Serein.Script
|
|||||||
// 生成方法签名
|
// 生成方法签名
|
||||||
AppendLine($"public static {returnContent} {mehtodName}({GetMethodParamster(param)})");
|
AppendLine($"public static {returnContent} {mehtodName}({GetMethodParamster(param)})");
|
||||||
}
|
}
|
||||||
AppendLine( "{");
|
AppendLine("{");
|
||||||
Indent();
|
Indent();
|
||||||
// 生成变量节点
|
// 生成变量节点
|
||||||
var idfNodesTemp = _symbolInfos.Keys.Where(key => key is IdentifierNode)
|
var idfNodesTemp = _symbolInfos.Keys.Where(key => key is IdentifierNode)
|
||||||
.OfType<IdentifierNode>().ToList() ;
|
.OfType<IdentifierNode>().ToList();
|
||||||
var idfNodes = (param is null) switch
|
var idfNodes = (param is null) switch
|
||||||
{
|
{
|
||||||
true => idfNodesTemp.DistinctBy(n => n.Name).ToList(),
|
true => idfNodesTemp.DistinctBy(n => n.Name).ToList(),
|
||||||
false => idfNodesTemp.DistinctBy(n => n.Name).DistinctByCondition(n => !param.ContainsKey(n.Name) ).ToList(),
|
false => idfNodesTemp.DistinctBy(n => n.Name).DistinctByCondition(n => !param.ContainsKey(n.Name)).ToList(),
|
||||||
};
|
};
|
||||||
foreach (var idf in idfNodes)
|
foreach (var idf in idfNodes)
|
||||||
{
|
{
|
||||||
@@ -116,10 +123,13 @@ namespace Serein.Script
|
|||||||
AppendLine("");
|
AppendLine("");
|
||||||
|
|
||||||
// 递归遍历节点生成代码
|
// 递归遍历节点生成代码
|
||||||
foreach (var stmt in programNode.Statements)
|
foreach (var stmt in programNode.Statements)
|
||||||
{
|
{
|
||||||
ConvertCode(stmt);
|
ConvertCode(stmt);
|
||||||
Append(";");
|
if (stmt is not (IfNode or WhileNode))
|
||||||
|
{
|
||||||
|
CompleteCurrentStatement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_symbolInfos[programNode] == typeof(void))
|
if (_symbolInfos[programNode] == typeof(void))
|
||||||
{
|
{
|
||||||
@@ -158,7 +168,7 @@ namespace Serein.Script
|
|||||||
return string.Join(',', values);
|
return string.Join(',', values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConvertCode( ASTNode node)
|
private void ConvertCode(ASTNode node)
|
||||||
{
|
{
|
||||||
switch (node)
|
switch (node)
|
||||||
{
|
{
|
||||||
@@ -167,16 +177,16 @@ namespace Serein.Script
|
|||||||
case ReturnNode returnNode: // 程序退出节点
|
case ReturnNode returnNode: // 程序退出节点
|
||||||
void ConvertCodeOfReturnNode(ReturnNode returnNode)
|
void ConvertCodeOfReturnNode(ReturnNode returnNode)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Append(Tab);
|
||||||
if (returnNode.Value is not null)
|
if (returnNode.Value is not null)
|
||||||
{
|
{
|
||||||
Append($"return ");
|
Append($"return ");
|
||||||
ConvertCode(returnNode.Value);
|
ConvertCode(returnNode.Value);
|
||||||
Append(";");
|
|
||||||
AppendLine(string.Empty);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AppendLine("return defult;");
|
AppendLine("return defult");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConvertCodeOfReturnNode(returnNode);
|
ConvertCodeOfReturnNode(returnNode);
|
||||||
@@ -205,49 +215,30 @@ namespace Serein.Script
|
|||||||
break;
|
break;
|
||||||
case NumberDoubleNode numberDoubleNode: // double浮点数值字面量
|
case NumberDoubleNode numberDoubleNode: // double浮点数值字面量
|
||||||
Append($"{numberDoubleNode.Value}d");
|
Append($"{numberDoubleNode.Value}d");
|
||||||
break;
|
break;
|
||||||
#endregion
|
#endregion
|
||||||
case IdentifierNode identifierNode: // 变量定义
|
case IdentifierNode identifierNode: // 变量定义
|
||||||
void ConvertCodeOfIdentifierNode(IdentifierNode identifierNode)
|
void ConvertCodeOfIdentifierNode(IdentifierNode identifierNode)
|
||||||
{
|
{
|
||||||
var varName = identifierNode.Name;
|
var varName = identifierNode.Name;
|
||||||
Append(varName);
|
Append(varName);
|
||||||
/*if (_local.TryGetValue(varName, out var type))
|
|
||||||
{
|
|
||||||
// 定义过,需要使用变量
|
|
||||||
Append(varName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_symbolInfos.TryGetValue(identifierNode, out type))
|
|
||||||
{
|
|
||||||
// 不存在,定义变量
|
|
||||||
Append($"global::{type.FullName} {varName}");
|
|
||||||
_local[varName] = type;
|
|
||||||
//Append(varName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception($"加载符号表时,无法匹配 IdentifierNode 节点的类型。 name : {varName}");
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
ConvertCodeOfIdentifierNode(identifierNode);
|
ConvertCodeOfIdentifierNode(identifierNode);
|
||||||
break;
|
break;
|
||||||
case IfNode ifNode: // if语句结构
|
case IfNode ifNode: // if语句结构
|
||||||
void ConvertCodeOfIfNode(IfNode ifNOde)
|
void ConvertCodeOfIfNode(IfNode ifNOde)
|
||||||
{
|
{
|
||||||
AppendLine("");
|
|
||||||
Append($"if(");
|
Append($"{Tab}if(");
|
||||||
ConvertCode(ifNOde.Condition); // 解析条件
|
ConvertCode(ifNOde.Condition); // 解析条件
|
||||||
Append($" == true)");
|
Append($" == true){Environment.NewLine}");
|
||||||
AppendLine("{");
|
AppendLine("{");
|
||||||
Indent();
|
Indent();
|
||||||
foreach(var item in ifNOde.TrueBranch)
|
foreach (var item in ifNOde.TrueBranch)
|
||||||
{
|
{
|
||||||
ConvertCode(item);
|
ConvertCode(item);
|
||||||
AppendLine(string.Empty);
|
CompleteCurrentStatement();
|
||||||
}
|
}
|
||||||
Unindent();
|
Unindent();
|
||||||
AppendLine("}");
|
AppendLine("}");
|
||||||
AppendLine("else");
|
AppendLine("else");
|
||||||
@@ -256,7 +247,7 @@ namespace Serein.Script
|
|||||||
foreach (var item in ifNOde.FalseBranch)
|
foreach (var item in ifNOde.FalseBranch)
|
||||||
{
|
{
|
||||||
ConvertCode(item);
|
ConvertCode(item);
|
||||||
AppendLine(string.Empty);
|
CompleteCurrentStatement();
|
||||||
}
|
}
|
||||||
Unindent();
|
Unindent();
|
||||||
AppendLine("}");
|
AppendLine("}");
|
||||||
@@ -275,8 +266,7 @@ namespace Serein.Script
|
|||||||
foreach (var item in whileNode.Body)
|
foreach (var item in whileNode.Body)
|
||||||
{
|
{
|
||||||
ConvertCode(item);
|
ConvertCode(item);
|
||||||
Append(";");
|
CompleteCurrentStatement();
|
||||||
AppendLine(string.Empty);
|
|
||||||
}
|
}
|
||||||
Unindent();
|
Unindent();
|
||||||
AppendLine("}");
|
AppendLine("}");
|
||||||
@@ -286,6 +276,8 @@ namespace Serein.Script
|
|||||||
case AssignmentNode assignmentNode: // 变量赋值语句
|
case AssignmentNode assignmentNode: // 变量赋值语句
|
||||||
void ConvertCodeOfAssignmentNode(AssignmentNode assignmentNode)
|
void ConvertCodeOfAssignmentNode(AssignmentNode assignmentNode)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Append(Tab);
|
||||||
ConvertCode(assignmentNode.Target);
|
ConvertCode(assignmentNode.Target);
|
||||||
Append(" = ");
|
Append(" = ");
|
||||||
if (assignmentNode.Value is null)
|
if (assignmentNode.Value is null)
|
||||||
@@ -296,19 +288,17 @@ namespace Serein.Script
|
|||||||
{
|
{
|
||||||
ConvertCode(assignmentNode.Value);
|
ConvertCode(assignmentNode.Value);
|
||||||
}
|
}
|
||||||
Append(";");
|
|
||||||
AppendLine(string.Empty);
|
|
||||||
}
|
}
|
||||||
ConvertCodeOfAssignmentNode(assignmentNode);
|
ConvertCodeOfAssignmentNode(assignmentNode);
|
||||||
break;
|
break;
|
||||||
case BinaryOperationNode binaryOperationNode: // 二元运算操作
|
case BinaryOperationNode binaryOperationNode: // 二元运算操作
|
||||||
void ConvertCodeOfBinaryOperationNode(BinaryOperationNode binaryOperationNode)
|
void ConvertCodeOfBinaryOperationNode(BinaryOperationNode binaryOperationNode)
|
||||||
{
|
{
|
||||||
Append("(");
|
Append("(");
|
||||||
ConvertCode(binaryOperationNode.Left); // 左操作数
|
ConvertCode(binaryOperationNode.Left); // 左操作数
|
||||||
Append(binaryOperationNode.Operator); // 操作符
|
Append(binaryOperationNode.Operator); // 操作符
|
||||||
ConvertCode(binaryOperationNode.Right); // 左操作数
|
ConvertCode(binaryOperationNode.Right); // 左操作数
|
||||||
Append(")");
|
Append(")");
|
||||||
}
|
}
|
||||||
ConvertCodeOfBinaryOperationNode(binaryOperationNode);
|
ConvertCodeOfBinaryOperationNode(binaryOperationNode);
|
||||||
break;
|
break;
|
||||||
@@ -318,7 +308,6 @@ namespace Serein.Script
|
|||||||
ConvertCode(collectionAssignmentNode.Collection);
|
ConvertCode(collectionAssignmentNode.Collection);
|
||||||
Append(" = ");
|
Append(" = ");
|
||||||
ConvertCode(collectionAssignmentNode.Value);
|
ConvertCode(collectionAssignmentNode.Value);
|
||||||
Append(";");
|
|
||||||
AppendLine(string.Empty);
|
AppendLine(string.Empty);
|
||||||
}
|
}
|
||||||
ConvertCodeOfCollectionAssignmentNode(collectionAssignmentNode);
|
ConvertCodeOfCollectionAssignmentNode(collectionAssignmentNode);
|
||||||
@@ -333,6 +322,25 @@ namespace Serein.Script
|
|||||||
}
|
}
|
||||||
ConvertCodeOfCollectionIndexNode(collectionIndexNode);
|
ConvertCodeOfCollectionIndexNode(collectionIndexNode);
|
||||||
break;
|
break;
|
||||||
|
case ArrayDefintionNode arrayDefintionNode:
|
||||||
|
void ConvertCodeOfArrayDefintionNode(ArrayDefintionNode arrayDefintionNode)
|
||||||
|
{
|
||||||
|
var arrType = this._symbolInfos[arrayDefintionNode];
|
||||||
|
var tab = new string(' ', (_indentLevel + 1) * 4);
|
||||||
|
Append($"new global::{arrType.FullName}{{{Environment.NewLine}");
|
||||||
|
for (int index = 0; index < arrayDefintionNode.Elements.Count; index++)
|
||||||
|
{
|
||||||
|
ASTNode? e = arrayDefintionNode.Elements[index];
|
||||||
|
Append(tab + " ");
|
||||||
|
ConvertCode(e);
|
||||||
|
if (index < arrayDefintionNode.Elements.Count - 1)
|
||||||
|
Append($", {Environment.NewLine}");
|
||||||
|
|
||||||
|
}
|
||||||
|
Append($"{Environment.NewLine}{tab}}}");
|
||||||
|
}
|
||||||
|
ConvertCodeOfArrayDefintionNode(arrayDefintionNode);
|
||||||
|
break;
|
||||||
case ClassTypeDefinitionNode classTypeDefinitionNode: // 类型定义
|
case ClassTypeDefinitionNode classTypeDefinitionNode: // 类型定义
|
||||||
void ConvertCodeOfClassTypeDefinitionNode(ClassTypeDefinitionNode classTypeDefinitionNode)
|
void ConvertCodeOfClassTypeDefinitionNode(ClassTypeDefinitionNode classTypeDefinitionNode)
|
||||||
{
|
{
|
||||||
@@ -409,7 +417,7 @@ namespace Serein.Script
|
|||||||
ConvertCode(memberAccessNode.Object);
|
ConvertCode(memberAccessNode.Object);
|
||||||
Append($".{memberAccessNode.MemberName}");
|
Append($".{memberAccessNode.MemberName}");
|
||||||
}
|
}
|
||||||
ConvertCodeOfMemberAccessNode(memberAccessNode);
|
ConvertCodeOfMemberAccessNode(memberAccessNode);
|
||||||
break;
|
break;
|
||||||
case MemberAssignmentNode memberAssignmentNode: // 对象成员赋值
|
case MemberAssignmentNode memberAssignmentNode: // 对象成员赋值
|
||||||
void ConvertCodeOfMemberAssignmentNode(MemberAssignmentNode memberAssignmentNode)
|
void ConvertCodeOfMemberAssignmentNode(MemberAssignmentNode memberAssignmentNode)
|
||||||
@@ -417,10 +425,8 @@ namespace Serein.Script
|
|||||||
ConvertCode(memberAssignmentNode.Object);
|
ConvertCode(memberAssignmentNode.Object);
|
||||||
Append($".{memberAssignmentNode.MemberName} = ");
|
Append($".{memberAssignmentNode.MemberName} = ");
|
||||||
ConvertCode(memberAssignmentNode.Value);
|
ConvertCode(memberAssignmentNode.Value);
|
||||||
Append($";");
|
|
||||||
AppendLine(string.Empty);
|
|
||||||
}
|
}
|
||||||
ConvertCodeOfMemberAssignmentNode(memberAssignmentNode);
|
ConvertCodeOfMemberAssignmentNode(memberAssignmentNode);
|
||||||
break;
|
break;
|
||||||
case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用
|
case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用
|
||||||
void ConvertCodeOfMemberFunctionCallNode(MemberFunctionCallNode memberFunctionCallNode)
|
void ConvertCodeOfMemberFunctionCallNode(MemberFunctionCallNode memberFunctionCallNode)
|
||||||
@@ -450,7 +456,7 @@ namespace Serein.Script
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ConvertCodeOfMemberFunctionCallNode(memberFunctionCallNode);
|
ConvertCodeOfMemberFunctionCallNode(memberFunctionCallNode);
|
||||||
break;
|
break;
|
||||||
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
||||||
void ConvertCodeOfFunctionCallNode(FunctionCallNode functionCallNode)
|
void ConvertCodeOfFunctionCallNode(FunctionCallNode functionCallNode)
|
||||||
@@ -462,13 +468,13 @@ namespace Serein.Script
|
|||||||
}
|
}
|
||||||
var funcName = functionCallNode.FunctionName switch
|
var funcName = functionCallNode.FunctionName switch
|
||||||
{
|
{
|
||||||
"int" => "@int" ,
|
"int" => "@int",
|
||||||
"bool" => "@bool" ,
|
"bool" => "@bool",
|
||||||
"double" => "@double" ,
|
"double" => "@double",
|
||||||
"long" => "@long" ,
|
"long" => "@long",
|
||||||
"decimal" => "@decimal" ,
|
"decimal" => "@decimal",
|
||||||
"float" => "@float" ,
|
"float" => "@float",
|
||||||
"byte" => "@byte" ,
|
"byte" => "@byte",
|
||||||
|
|
||||||
_ => functionCallNode.FunctionName,
|
_ => functionCallNode.FunctionName,
|
||||||
};
|
};
|
||||||
@@ -495,6 +501,9 @@ namespace Serein.Script
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Serein.Library;
|
using Serein.Library;
|
||||||
|
using Serein.Library.Api;
|
||||||
using Serein.Library.Utils;
|
using Serein.Library.Utils;
|
||||||
using Serein.Script.Node;
|
using Serein.Script.Node;
|
||||||
using Serein.Script.Node.FlowControl;
|
using Serein.Script.Node.FlowControl;
|
||||||
@@ -105,10 +106,20 @@ namespace Serein.Script
|
|||||||
case ReturnNode returnNode: // 程序退出节点
|
case ReturnNode returnNode: // 程序退出节点
|
||||||
Type AnalysisReturnNode(ReturnNode returnNode)
|
Type AnalysisReturnNode(ReturnNode returnNode)
|
||||||
{
|
{
|
||||||
var resultType = Analysis(returnNode.Value);
|
if(returnNode.Value is null)
|
||||||
NodeSymbolInfos[returnNode.Value] = resultType;
|
{
|
||||||
NodeSymbolInfos[returnNode] = resultType;
|
var resultType = typeof(void);
|
||||||
return resultType;
|
NodeSymbolInfos[returnNode] = resultType;
|
||||||
|
return resultType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var resultType = Analysis(returnNode.Value);
|
||||||
|
NodeSymbolInfos[returnNode.Value] = resultType;
|
||||||
|
NodeSymbolInfos[returnNode] = resultType;
|
||||||
|
return resultType;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return AnalysisReturnNode(returnNode);
|
return AnalysisReturnNode(returnNode);
|
||||||
case NullNode nullNode: // null
|
case NullNode nullNode: // null
|
||||||
@@ -406,9 +417,25 @@ namespace Serein.Script
|
|||||||
{
|
{
|
||||||
var objectType = Analysis(memberFunctionCallNode.Object);
|
var objectType = Analysis(memberFunctionCallNode.Object);
|
||||||
var types = memberFunctionCallNode.Arguments.Select(arg => Analysis(arg)).ToArray();
|
var types = memberFunctionCallNode.Arguments.Select(arg => Analysis(arg)).ToArray();
|
||||||
|
|
||||||
|
|
||||||
var methodInfo = objectType.GetMethod(memberFunctionCallNode.FunctionName, types);
|
var methodInfo = objectType.GetMethod(memberFunctionCallNode.FunctionName, types);
|
||||||
if (methodInfo is null)
|
if (methodInfo is null)
|
||||||
throw new Exception($"类型 {objectType} 没有方法 {memberFunctionCallNode.FunctionName}");
|
{
|
||||||
|
var t = objectType.GetMethods().Where(m => m.Name.Equals(memberFunctionCallNode.FunctionName)).ToArray();
|
||||||
|
if(t.Length > 0)
|
||||||
|
{
|
||||||
|
var content = string.Join($";{Environment.NewLine}", t.Select(m => m.ToString()));
|
||||||
|
throw new Exception($"类型 {objectType} 没有指定的重载方法 " +
|
||||||
|
$"{memberFunctionCallNode.FunctionName}({string.Join(",", types.Select(t => t.Name))})," +
|
||||||
|
$"但存在其它重载方法:{content}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception($"类型 {objectType} 没有方法 {memberFunctionCallNode.FunctionName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < memberFunctionCallNode.Arguments.Count; index++)
|
for (int index = 0; index < memberFunctionCallNode.Arguments.Count; index++)
|
||||||
{
|
{
|
||||||
ASTNode argNode = memberFunctionCallNode.Arguments[index];
|
ASTNode argNode = memberFunctionCallNode.Arguments[index];
|
||||||
@@ -428,7 +455,17 @@ namespace Serein.Script
|
|||||||
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
||||||
Type AnalysisFunctionCallNode(FunctionCallNode functionCallNode)
|
Type AnalysisFunctionCallNode(FunctionCallNode functionCallNode)
|
||||||
{
|
{
|
||||||
if(!SereinScript.FunctionInfos.TryGetValue(functionCallNode.FunctionName, out var methodInfo))
|
// 获取流程上下文
|
||||||
|
if (functionCallNode.FunctionName.Equals("getFlowContext", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return typeof(IFlowContext);
|
||||||
|
}
|
||||||
|
else if (functionCallNode.FunctionName.Equals("getScriptContext", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return typeof(IScriptInvokeContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SereinScript.FunctionInfos.TryGetValue(functionCallNode.FunctionName, out var methodInfo))
|
||||||
{
|
{
|
||||||
throw new Exception($"脚本没有挂载方法 {functionCallNode.FunctionName}");
|
throw new Exception($"脚本没有挂载方法 {functionCallNode.FunctionName}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1281,7 +1281,7 @@ namespace Serein.Workbench.Views
|
|||||||
private ContextMenu ConfiguerSelectionRectangle()
|
private ContextMenu ConfiguerSelectionRectangle()
|
||||||
{
|
{
|
||||||
var contextMenu = new ContextMenu();
|
var contextMenu = new ContextMenu();
|
||||||
contextMenu.Items.Add(WpfFuncTool.CreateMenuItem("删除", (s, e) =>
|
/*contextMenu.Items.Add(WpfFuncTool.CreateMenuItem("删除", (s, e) =>
|
||||||
{
|
{
|
||||||
if (selectNodeControls.Count > 0)
|
if (selectNodeControls.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -1296,7 +1296,7 @@ namespace Serein.Workbench.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SelectionRectangle.Visibility = Visibility.Collapsed;
|
SelectionRectangle.Visibility = Visibility.Collapsed;
|
||||||
}));
|
}));*/
|
||||||
return contextMenu;
|
return contextMenu;
|
||||||
// nodeControl.ContextMenu = contextMenu;
|
// nodeControl.ContextMenu = contextMenu;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user