Skip to content

Commit ed785a8

Browse files
🔧 Fix(Workflow): Test M(PluginCallWithTarget 跨设备调用)功能修复
1 parent 6c9ff71 commit ed785a8

4 files changed

Lines changed: 49 additions & 15 deletions

File tree

KitX Clients/KitX Core/KitX.Core.BluePrint.Test/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using KitX.Core.DI;
77
using KitX.Core.Contract.Workflow;
88
using KitX.Core.Workflow.Blueprint;
9-
using KitX.Core.Workflow.Blueprint.CFG;
9+
using KitX.Core.Workflow.CFG;
1010
using KitX.Core.Workflow.BlockScripting;
1111

1212
namespace KitX.Core.BluePrint.Test;

KitX Clients/KitX Core/KitX.Core/Workflow/BlockScripting/CFG2CSGenerator.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,11 +734,27 @@ internal static SwitchSectionSyntax GenerateFormattedBlockCase(
734734
var callExpr = BuildPluginCallWithTargetExpression(stmt, pubVarTypes);
735735
if (stmt.PubVarTarget != null)
736736
{
737+
// G.PluginCallWithTarget returns object? — wrap in ConvertTo<T> when
738+
// assigning to a typed PubVar, mirroring the Assignment/Expression case.
737739
var typeName = pubVarTypes.GetValueOrDefault(stmt.PubVarTarget, "object");
740+
ExpressionSyntax initExpr = typeName != "object"
741+
? BuildConvertToInvocation(typeName, callExpr)
742+
: callExpr;
738743
caseStatements.Add(LocalDeclarationStatement(
739744
VariableDeclaration(ParseTypeName(typeName))
740745
.AddVariables(VariableDeclarator(Identifier(stmt.PubVarTarget))
741-
.WithInitializer(EqualsValueClause(callExpr)))));
746+
.WithInitializer(EqualsValueClause(initExpr)))));
747+
748+
// Sync PubVar to globals so debugger sees the value
749+
caseStatements.Add(ExpressionStatement(
750+
InvocationExpression(
751+
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
752+
IdentifierName("G"), IdentifierName("Set")),
753+
ArgumentList(SeparatedList(new[]
754+
{
755+
Argument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(stmt.PubVarTarget))),
756+
Argument(IdentifierName(stmt.PubVarTarget))
757+
})))));
742758
}
743759
else
744760
{

KitX Clients/KitX Core/KitX.Core/Workflow/Pipeline/CFG2BPConverter.cs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ private void ProcessBlock(CFGBlock block, PipelineContext context)
112112
private BlueprintNode? ProcessStatement(CFGStatement stmt, string blockName,
113113
PipelineContext context, ref BlueprintNode? prevNode, ref string? prevStmtId)
114114
{
115+
// PluginCallWithTarget must become an explicit CallNode carrying TargetDevice.
116+
// Route it before the registry dispatch — otherwise the registry creates a
117+
// BuiltinFunctionNode that ConfigureNode (which expects a CallNode) cannot convert,
118+
// leaving TargetDevice unset and producing no CallNode for the test to find.
119+
if (stmt.FunctionName == "PluginCallWithTarget")
120+
return ProcessCallOrAssignment(stmt, context, ref prevNode, ref prevStmtId);
121+
115122
// Registry path: handle all registered builtin functions
116123
if (_functionRegistry != null && !string.IsNullOrEmpty(stmt.FunctionName))
117124
{
@@ -203,7 +210,28 @@ private bool IsRegistryFlowControlTerminator(CFGStatement stmt)
203210

204211
// --- Create new node ---
205212
BlueprintNode mainNode;
206-
if (_functionRegistry != null && _functionRegistry.Get(stmt.FunctionName!) is { } funcDef)
213+
if (stmt.FunctionName == "PluginCallWithTarget")
214+
{
215+
// PluginCallWithTarget must be an explicit CallNode carrying TargetDevice.
216+
// Handle BEFORE the builtin registry dispatch — otherwise the registry shadows
217+
// it (PluginCallWithTarget is a registered builtin) and TargetDevice is never set.
218+
var callNode = (CallNode)_registry.Create(BlueprintNodeType.Call);
219+
var args = stmt.Arguments;
220+
// G.PluginCallWithTarget("plugin", "method", "device", ...)
221+
// Arguments[0]=pluginName, [1]=methodName, [2]=targetDevice
222+
callNode.PluginName = args?.Count > 0 ? StripQuotes(args[0]) : "";
223+
callNode.FunctionName = args?.Count > 1 ? StripQuotes(args[1]) : "";
224+
callNode.TargetDevice = args?.Count > 2 ? StripQuotes(args[2]) : null;
225+
// Preserve extra arguments (beyond plugin/method/device) for BS round-trip,
226+
// mirroring PluginCallWithTargetFunction.ConfigureNode.
227+
if (args != null && args.Count > 3)
228+
callNode.ExtraArguments = args.Skip(3).ToList();
229+
mainNode = callNode;
230+
231+
// Add parameter pins based on argument count
232+
AddParamPins(mainNode, stmt.FunctionName!, stmt.Arguments?.Count ?? 0);
233+
}
234+
else if (_functionRegistry != null && _functionRegistry.Get(stmt.FunctionName!) is { } funcDef)
207235
{
208236
mainNode = _registry.CreateBuiltinFunctionNode(stmt.FunctionName!);
209237
mainNode = funcDef.ConfigureNode(mainNode, stmt);
@@ -222,17 +250,7 @@ private bool IsRegistryFlowControlTerminator(CFGStatement stmt)
222250
var callNode = (CallNode)_registry.Create(BlueprintNodeType.Call);
223251

224252
// Parse plugin name from full dotted method name (e.g. "TestPlugin.WPF.Core.HelloKitX")
225-
// PluginCallWithTarget has G.PluginCallWithTarget as FullFunctionName, handle it first
226-
if (stmt.FunctionName == "PluginCallWithTarget")
227-
{
228-
// G.PluginCallWithTarget("plugin", "method", "device", ...)
229-
// Arguments[0]=pluginName, [1]=methodName, [2]=targetDevice
230-
var args = stmt.Arguments;
231-
callNode.PluginName = args?.Count > 0 ? StripQuotes(args[0]) : "";
232-
callNode.FunctionName = args?.Count > 1 ? StripQuotes(args[1]) : "";
233-
callNode.TargetDevice = args?.Count > 2 ? StripQuotes(args[2]) : null;
234-
}
235-
else if (!string.IsNullOrEmpty(stmt.FullFunctionName) && stmt.FullFunctionName.Contains('.'))
253+
if (!string.IsNullOrEmpty(stmt.FullFunctionName) && stmt.FullFunctionName.Contains('.'))
236254
{
237255
var lastDot = stmt.FullFunctionName.LastIndexOf('.');
238256
callNode.PluginName = stmt.FullFunctionName.Substring(0, lastDot);

0 commit comments

Comments
 (0)