From f122bc19890d058b5369c24d498959f72b392c11 Mon Sep 17 00:00:00 2001 From: snakex64 <39806655+snakex64@users.noreply.github.com> Date: Fri, 15 Nov 2024 19:45:59 -0500 Subject: [PATCH 1/4] Add local variable declaration and set Fixes #14 --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/VisualNodeDev/NodeDev/issues/14?shareId=XXXX-XXXX-XXXX-XXXX). --- src/NodeDev.Core/Nodes/DeclareVariableNode.cs | 32 +++++++++++++++ .../Nodes/SetVariableValueNode.cs | 22 ++++++++++ src/NodeDev.Tests/GraphExecutorTests.cs | 40 ++++++++++++++++++- 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/NodeDev.Core/Nodes/DeclareVariableNode.cs create mode 100644 src/NodeDev.Core/Nodes/SetVariableValueNode.cs diff --git a/src/NodeDev.Core/Nodes/DeclareVariableNode.cs b/src/NodeDev.Core/Nodes/DeclareVariableNode.cs new file mode 100644 index 0000000..2fccb0a --- /dev/null +++ b/src/NodeDev.Core/Nodes/DeclareVariableNode.cs @@ -0,0 +1,32 @@ +using NodeDev.Core.Connections; +using NodeDev.Core.Types; +using System.Linq.Expressions; + +namespace NodeDev.Core.Nodes; + +public class DeclareVariableNode : FlowNode +{ + public DeclareVariableNode(Graph graph, string name, TypeBase type, string? id = null) : base(graph, id) + { + Name = name; + VariableType = type; + + var type = new UndefinedGenericType("T"); + Outputs.Add(new Connection("Variable", this, type)); + Inputs.Add(new Connection("InitialValue", this, type)); + } + + public override string TitleColor => "blue"; + + public override bool IsFlowNode => true; + + internal override Expression BuildExpression(Dictionary? subChunks, BuildExpressionInfo info) + { + return Expression.Assign(variable, info.LocalVariables[Inputs[0]]); + } + + internal override void BuildInlineExpression(BuildExpressionInfo info) + { + throw new NotImplementedException(); + } +} diff --git a/src/NodeDev.Core/Nodes/SetVariableValueNode.cs b/src/NodeDev.Core/Nodes/SetVariableValueNode.cs new file mode 100644 index 0000000..886d916 --- /dev/null +++ b/src/NodeDev.Core/Nodes/SetVariableValueNode.cs @@ -0,0 +1,22 @@ +using NodeDev.Core.Connections; +using NodeDev.Core.Types; +using System.Linq.Expressions; + +namespace NodeDev.Core.Nodes; + +public class SetVariableValueNode : NormalFlowNode +{ + public SetVariableValueNode(Graph graph, string name, string? id = null) : base(graph, id) + { + Name = name; + + var type = new UndefinedGenericType("T"); + Inputs.Add(new Connection("Variable", this, type)); + Inputs.Add(new Connection("Value", this, type)); + } + + internal override Expression BuildExpression(Dictionary? subChunks, BuildExpressionInfo info) + { + return Expression.Assign(info.LocalVariables[Inputs[1]], info.LocalVariables[Inputs[2]]); + } +} diff --git a/src/NodeDev.Tests/GraphExecutorTests.cs b/src/NodeDev.Tests/GraphExecutorTests.cs index 12a1afe..82090d4 100644 --- a/src/NodeDev.Tests/GraphExecutorTests.cs +++ b/src/NodeDev.Tests/GraphExecutorTests.cs @@ -290,4 +290,42 @@ public void TestProjectRun(SerializableBuildOptions options) output = Run(graph.Project, options, [-1, -2]); Assert.Equal(1, output); } -} \ No newline at end of file + + [Theory] + [MemberData(nameof(GetBuildOptions))] + public void TestDeclareAndSetVariable(SerializableBuildOptions options) + { + var project = new Project(Guid.NewGuid()); + var nodeClass = new NodeClass("Program", "Test", project); + project.Classes.Add(nodeClass); + + var graph = new Graph(); + var method = new NodeClassMethod(nodeClass, "MainInternal", nodeClass.TypeFactory.Get(), graph, true); + nodeClass.Methods.Add(method); + graph.SelfMethod = method; + + method.Parameters.Add(new("A", nodeClass.TypeFactory.Get(), method)); + + var entryNode = new EntryNode(graph); + var declareVariableNode = new DeclareVariableNode(graph, "Variable", nodeClass.TypeFactory.Get()); + var setVariableValueNode = new SetVariableValueNode(graph, "SetVariable"); + var returnNode = new ReturnNode(graph); + + graph.AddNode(entryNode, false); + graph.AddNode(declareVariableNode, false); + graph.AddNode(setVariableValueNode, false); + graph.AddNode(returnNode, false); + + graph.Connect(entryNode.Outputs[0], declareVariableNode.Inputs[0], false); + graph.Connect(declareVariableNode.Outputs[0], setVariableValueNode.Inputs[0], false); + graph.Connect(entryNode.Outputs[1], setVariableValueNode.Inputs[1], false); + graph.Connect(setVariableValueNode.Outputs[0], returnNode.Inputs[0], false); + graph.Connect(declareVariableNode.Outputs[0], returnNode.Inputs[1], false); + + CreateStaticMainWithConversion(nodeClass, method); + + var output = Run(graph.Project, options, [5]); + + Assert.Equal(5, output); + } +} From 5b09e349cf6b5f379456ca549d4f21d4469227c2 Mon Sep 17 00:00:00 2001 From: snakex64 Date: Fri, 15 Nov 2024 20:02:21 -0500 Subject: [PATCH 2/4] Fix auto code gen --- src/NodeDev.Core/Nodes/DeclareVariableNode.cs | 15 +++--- src/NodeDev.Tests/GraphExecutorTests.cs | 51 +++++++++++++++++-- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/NodeDev.Core/Nodes/DeclareVariableNode.cs b/src/NodeDev.Core/Nodes/DeclareVariableNode.cs index 2fccb0a..70ff488 100644 --- a/src/NodeDev.Core/Nodes/DeclareVariableNode.cs +++ b/src/NodeDev.Core/Nodes/DeclareVariableNode.cs @@ -4,25 +4,22 @@ namespace NodeDev.Core.Nodes; -public class DeclareVariableNode : FlowNode +public class DeclareVariableNode : NormalFlowNode { - public DeclareVariableNode(Graph graph, string name, TypeBase type, string? id = null) : base(graph, id) + public DeclareVariableNode(Graph graph, string name, string? id = null) : base(graph, id) { Name = name; - VariableType = type; - var type = new UndefinedGenericType("T"); - Outputs.Add(new Connection("Variable", this, type)); - Inputs.Add(new Connection("InitialValue", this, type)); + var t = new UndefinedGenericType("T"); + Outputs.Add(new Connection("Variable", this, t)); + Inputs.Add(new Connection("InitialValue", this, t)); } public override string TitleColor => "blue"; - public override bool IsFlowNode => true; - internal override Expression BuildExpression(Dictionary? subChunks, BuildExpressionInfo info) { - return Expression.Assign(variable, info.LocalVariables[Inputs[0]]); + return Expression.Assign(info.LocalVariables[Outputs[1]], info.LocalVariables[Inputs[1]]); } internal override void BuildInlineExpression(BuildExpressionInfo info) diff --git a/src/NodeDev.Tests/GraphExecutorTests.cs b/src/NodeDev.Tests/GraphExecutorTests.cs index 82090d4..ce9afe5 100644 --- a/src/NodeDev.Tests/GraphExecutorTests.cs +++ b/src/NodeDev.Tests/GraphExecutorTests.cs @@ -307,13 +307,18 @@ public void TestDeclareAndSetVariable(SerializableBuildOptions options) method.Parameters.Add(new("A", nodeClass.TypeFactory.Get(), method)); var entryNode = new EntryNode(graph); - var declareVariableNode = new DeclareVariableNode(graph, "Variable", nodeClass.TypeFactory.Get()); - var setVariableValueNode = new SetVariableValueNode(graph, "SetVariable"); - var returnNode = new ReturnNode(graph); - graph.AddNode(entryNode, false); + + var declareVariableNode = new DeclareVariableNode(graph, "Variable"); + declareVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); + declareVariableNode.Outputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); graph.AddNode(declareVariableNode, false); + + var setVariableValueNode = new SetVariableValueNode(graph, "SetVariable"); + setVariableValueNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); graph.AddNode(setVariableValueNode, false); + + var returnNode = new ReturnNode(graph); graph.AddNode(returnNode, false); graph.Connect(entryNode.Outputs[0], declareVariableNode.Inputs[0], false); @@ -328,4 +333,42 @@ public void TestDeclareAndSetVariable(SerializableBuildOptions options) Assert.Equal(5, output); } + + [Theory] + [MemberData(nameof(GetBuildOptions))] + public void TestDeclareVariableDefaultValue(SerializableBuildOptions options) + { + var project = new Project(Guid.NewGuid()); + var nodeClass = new NodeClass("Program", "Test", project); + project.Classes.Add(nodeClass); + + var graph = new Graph(); + var method = new NodeClassMethod(nodeClass, "MainInternal", nodeClass.TypeFactory.Get(), graph, true); + nodeClass.Methods.Add(method); + graph.SelfMethod = method; + + method.Parameters.Add(new("A", nodeClass.TypeFactory.Get(), method)); + + var entryNode = new EntryNode(graph); + graph.AddNode(entryNode, false); + + var declareVariableNode = new DeclareVariableNode(graph, "Variable"); + declareVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); + declareVariableNode.Outputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); + graph.AddNode(declareVariableNode, false); + + var returnNode = new ReturnNode(graph); + graph.AddNode(returnNode, false); + + graph.Connect(entryNode.Outputs[0], declareVariableNode.Inputs[0], false); + graph.Connect(entryNode.Outputs[1], declareVariableNode.Inputs[1], false); + graph.Connect(declareVariableNode.Outputs[0], returnNode.Inputs[0], false); + graph.Connect(declareVariableNode.Outputs[1], returnNode.Inputs[1], false); + + CreateStaticMainWithConversion(nodeClass, method); + + var output = Run(graph.Project, options, [5]); + + Assert.Equal(5, output); + } } From a900e278f069caf4049652282660ac69c91c5fb0 Mon Sep 17 00:00:00 2001 From: snakex64 Date: Fri, 15 Nov 2024 20:25:54 -0500 Subject: [PATCH 3/4] Fix unit test Get/set local variables --- .../Components/SourceViewer.razor | 5 +-- .../Class/NodeClassTypeCreator.cs | 43 +++++-------------- src/NodeDev.Tests/GraphExecutorTests.cs | 16 ++++--- 3 files changed, 22 insertions(+), 42 deletions(-) diff --git a/src/NodeDev.Blazor/Components/SourceViewer.razor b/src/NodeDev.Blazor/Components/SourceViewer.razor index 6ddf3b3..4f0c4a6 100644 --- a/src/NodeDev.Blazor/Components/SourceViewer.razor +++ b/src/NodeDev.Blazor/Components/SourceViewer.razor @@ -95,13 +95,12 @@ else try { var temp = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); - //var assemblyPath = Method.Graph.Project.Build(Core.BuildOptions.Debug with { OutputPath = temp }); - Method.Graph.Project.BuildAndGetAssembly(Core.BuildOptions.Debug); + var assemblyPath = Method.Graph.Project.Build(Core.BuildOptions.Debug with { OutputPath = temp }); Creator = Method.Graph.Project.NodeClassTypeCreator; try { - Creator!.GetBodyAsCsAndMsilCode("", Method, out CodeCs, out CodeMsil); + Creator!.GetBodyAsCsAndMsilCode(assemblyPath, Method, out CodeCs, out CodeMsil); CodeCs = $"// Pseudo code for debugging.{System.Environment.NewLine}// This is not the actual code executed, we execute IL directly!{System.Environment.NewLine}{CodeCs}"; diff --git a/src/NodeDev.Core/Class/NodeClassTypeCreator.cs b/src/NodeDev.Core/Class/NodeClassTypeCreator.cs index 731bb89..2a847bf 100644 --- a/src/NodeDev.Core/Class/NodeClassTypeCreator.cs +++ b/src/NodeDev.Core/Class/NodeClassTypeCreator.cs @@ -37,18 +37,16 @@ internal NodeClassTypeCreator(Project project, BuildOptions buildOptions) public void CreateProjectClassesAndAssembly() { // TODO Remove this when the new System.Reflection.Emit is available in .NET 10 - //if (TemporaryReflectionAssembly == null) - //{ - // var assembly = System.Reflection.Assembly.GetExecutingAssembly(); - // using var stream = assembly.GetManifestResourceStream("NodeDev.Core.Dependencies.System.Reflection.Emit.dll")!; - // var bytes = new byte[stream.Length]; - // stream.ReadExactly(bytes); - // TemporaryReflectionAssembly = System.Reflection.Assembly.Load(bytes); - //} - //var persisted = Activator.CreateInstance(TemporaryReflectionAssembly.ExportedTypes.First(), new AssemblyName("NodeProject_" + this.Project.Id.ToString().Replace('-', '_')), typeof(object).Assembly, null)!; - //Assembly = (AssemblyBuilder)persisted; - - Assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("NodeProject_" + this.Project.Id.ToString().Replace('-', '_')), AssemblyBuilderAccess.RunAndCollect); + if (TemporaryReflectionAssembly == null) + { + var assembly = System.Reflection.Assembly.GetExecutingAssembly(); + using var stream = assembly.GetManifestResourceStream("NodeDev.Core.Dependencies.System.Reflection.Emit.dll")!; + var bytes = new byte[stream.Length]; + stream.ReadExactly(bytes); + TemporaryReflectionAssembly = System.Reflection.Assembly.Load(bytes); + } + var persisted = Activator.CreateInstance(TemporaryReflectionAssembly.ExportedTypes.First(), new AssemblyName("NodeProject_" + this.Project.Id.ToString().Replace('-', '_')), typeof(object).Assembly, null)!; + Assembly = (AssemblyBuilder)persisted; // https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.assemblybuilder?view=net-7.0 //var persisted = new PersistedAssemblyBuilder(new AssemblyName("NodeProject_" + this.Project.Id.ToString().Replace('-', '_')), typeof(object).Assembly); @@ -150,8 +148,7 @@ public void GetBodyAsCsAndMsilCode(string assemblyPath, NodeClassMethod method, cs = str.ToString(); - //var assembly = context.LoadFromAssemblyPath(assemblyPath); - var assembly = Assembly; + var assembly = context.LoadFromAssemblyPath(assemblyPath); var type = assembly.GetType(HiddenName(method.Class.Name)); if(type == null) { @@ -183,24 +180,6 @@ private void GenerateHiddenMethodBody(NodeClassMethod method, MethodBuilder meth // Generate the expression tree for the method var expression = method.Graph.BuildExpression(Options.BuildExpressionOptions); - - var returnLabelTarget = Expression.Label(typeof(int), "ReturnLabel"); - - var tryBody = Expression.Call(typeof(Console).GetMethod("Clear")!); - var catchBody = Expression.Return(returnLabelTarget, Expression.Constant(10)); - - var tryCatch = Expression.TryCatch(tryBody, Expression.Catch(typeof(Exception), catchBody)); - - var afterCatch = Expression.Block( - Expression.Call(typeof(Console).GetMethod("Clear")!), - Expression.Return(returnLabelTarget, Expression.Constant(5)), - Expression.Label(returnLabelTarget, Expression.Constant(0))); - - var body = Expression.Block(tryCatch, afterCatch); - - expression = Expression.Lambda(body); - - var v = expression.CompileFast(); var ilGenerator = methodBuilder.GetILGenerator(); var result = expression.CompileFastToIL(ilGenerator, CompilerFlags.ThrowOnNotSupportedExpression); diff --git a/src/NodeDev.Tests/GraphExecutorTests.cs b/src/NodeDev.Tests/GraphExecutorTests.cs index e55bc03..d66d7ac 100644 --- a/src/NodeDev.Tests/GraphExecutorTests.cs +++ b/src/NodeDev.Tests/GraphExecutorTests.cs @@ -190,7 +190,8 @@ public static T Run(Project project, BuildOptions buildOptions, params object finally { // Clean up - Directory.Delete(buildOptions.OutputPath, true); + if(Directory.Exists(buildOptions.OutputPath)) + Directory.Delete(buildOptions.OutputPath, true); } } @@ -346,7 +347,6 @@ public void TestTryCatchNode(SerializableBuildOptions options) Assert.Equal(1, output); } -} [Theory] [MemberData(nameof(GetBuildOptions))] @@ -367,12 +367,13 @@ public void TestDeclareAndSetVariable(SerializableBuildOptions options) graph.AddNode(entryNode, false); var declareVariableNode = new DeclareVariableNode(graph, "Variable"); - declareVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); - declareVariableNode.Outputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); + declareVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Initial value + declareVariableNode.Outputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Variable graph.AddNode(declareVariableNode, false); var setVariableValueNode = new SetVariableValueNode(graph, "SetVariable"); - setVariableValueNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); + setVariableValueNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Variable + setVariableValueNode.Inputs[2].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Value graph.AddNode(setVariableValueNode, false); var returnNode = new ReturnNode(graph); @@ -380,9 +381,10 @@ public void TestDeclareAndSetVariable(SerializableBuildOptions options) graph.Connect(entryNode.Outputs[0], declareVariableNode.Inputs[0], false); graph.Connect(declareVariableNode.Outputs[0], setVariableValueNode.Inputs[0], false); - graph.Connect(entryNode.Outputs[1], setVariableValueNode.Inputs[1], false); + graph.Connect(declareVariableNode.Outputs[1], setVariableValueNode.Inputs[1], false); + graph.Connect(entryNode.Outputs[1], setVariableValueNode.Inputs[2], false); graph.Connect(setVariableValueNode.Outputs[0], returnNode.Inputs[0], false); - graph.Connect(declareVariableNode.Outputs[0], returnNode.Inputs[1], false); + graph.Connect(declareVariableNode.Outputs[1], returnNode.Inputs[1], false); CreateStaticMainWithConversion(nodeClass, method); From a3eeea45674ef986988d36d4c1d67a78846ffa37 Mon Sep 17 00:00:00 2001 From: snakex64 Date: Fri, 15 Nov 2024 20:49:11 -0500 Subject: [PATCH 4/4] Fix TryCatch unit test --- src/NodeDev.Core/Nodes/DeclareVariableNode.cs | 4 +- .../Nodes/SetVariableValueNode.cs | 4 +- src/NodeDev.Tests/GraphExecutorTests.cs | 55 ++++++++++++------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/NodeDev.Core/Nodes/DeclareVariableNode.cs b/src/NodeDev.Core/Nodes/DeclareVariableNode.cs index 70ff488..e08087c 100644 --- a/src/NodeDev.Core/Nodes/DeclareVariableNode.cs +++ b/src/NodeDev.Core/Nodes/DeclareVariableNode.cs @@ -6,9 +6,9 @@ namespace NodeDev.Core.Nodes; public class DeclareVariableNode : NormalFlowNode { - public DeclareVariableNode(Graph graph, string name, string? id = null) : base(graph, id) + public DeclareVariableNode(Graph graph, string? id = null) : base(graph, id) { - Name = name; + Name = "Declare Variable"; var t = new UndefinedGenericType("T"); Outputs.Add(new Connection("Variable", this, t)); diff --git a/src/NodeDev.Core/Nodes/SetVariableValueNode.cs b/src/NodeDev.Core/Nodes/SetVariableValueNode.cs index 886d916..148d108 100644 --- a/src/NodeDev.Core/Nodes/SetVariableValueNode.cs +++ b/src/NodeDev.Core/Nodes/SetVariableValueNode.cs @@ -6,9 +6,9 @@ namespace NodeDev.Core.Nodes; public class SetVariableValueNode : NormalFlowNode { - public SetVariableValueNode(Graph graph, string name, string? id = null) : base(graph, id) + public SetVariableValueNode(Graph graph, string? id = null) : base(graph, id) { - Name = name; + Name = "Set Variable"; var type = new UndefinedGenericType("T"); Inputs.Add(new Connection("Variable", this, type)); diff --git a/src/NodeDev.Tests/GraphExecutorTests.cs b/src/NodeDev.Tests/GraphExecutorTests.cs index d66d7ac..4b94031 100644 --- a/src/NodeDev.Tests/GraphExecutorTests.cs +++ b/src/NodeDev.Tests/GraphExecutorTests.cs @@ -318,34 +318,51 @@ public void TestTryCatchNode(SerializableBuildOptions options) graph.AddNode(entryNode, false); graph.AddNode(tryCatchNode, false); - graph.Connect(entryNode.Outputs[0], tryCatchNode.Inputs[0], false); + // Create local variable + var declareVariableNode = new DeclareVariableNode(graph); + declareVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Initial value + declareVariableNode.Outputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Variable + graph.AddNode(declareVariableNode, false); + + graph.Connect(entryNode.Outputs[0], declareVariableNode.Inputs[0], false); + graph.Connect(declareVariableNode.Outputs[0], tryCatchNode.Inputs[0], false); - var catchReturnNode = new ReturnNode(graph); - catchReturnNode.Inputs.Add(new("Result", catchReturnNode, nodeClass.TypeFactory.Get())); - catchReturnNode.Inputs[1].UpdateTextboxText("1"); - graph.AddNode(catchReturnNode, false); - graph.Connect(tryCatchNode.Outputs[1], catchReturnNode.Inputs[0], false); + var returnNode = new ReturnNode(graph); + graph.Connect(declareVariableNode.Outputs[1], returnNode.Inputs[1], false); + graph.AddNode(returnNode, false); - var parseNode = new MethodCall(graph); + // Create the catch block body + var catchVariableNode = new SetVariableValueNode(graph); + catchVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Variable + catchVariableNode.Inputs[2].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Value + catchVariableNode.Inputs[2].UpdateTextboxText("2"); + graph.AddNode(catchVariableNode, false); + graph.Connect(tryCatchNode.Outputs[1], catchVariableNode.Inputs[0], false); + graph.Connect(declareVariableNode.Outputs[1], catchVariableNode.Inputs[1], false); + graph.Connect(catchVariableNode.Outputs[0], returnNode.Inputs[0], false); + + // Create the try block body + var parseNode = new MethodCall(graph); parseNode.SetMethodTarget(new RealMethodInfo(nodeClass.TypeFactory, typeof(int).GetMethod("Parse", new[] { typeof(string) })!, nodeClass.TypeFactory.Get())); - parseNode.Inputs[0].UpdateTextboxText("invalid"); + parseNode.Inputs[1].UpdateTextboxText("invalid"); graph.AddNode(parseNode, false); graph.Connect(tryCatchNode.Outputs[0], parseNode.Inputs[0], false); - var tryReturnNode = new ReturnNode(graph); - tryReturnNode.Inputs.Add(new("Result", tryReturnNode, nodeClass.TypeFactory.Get())); - tryReturnNode.Inputs[1].UpdateTextboxText("0"); - graph.AddNode(tryReturnNode, false); - // Both the try and finally merge to the same "return", as there is nothing to actually put in the "finally" we can reuse the same return for simplicity - graph.Connect(parseNode.Outputs[0], tryReturnNode.Inputs[0], false); - graph.Connect(tryCatchNode.Outputs[2], tryReturnNode.Inputs[0], false); + var tryVariableNode = new SetVariableValueNode(graph); + tryVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Variable + tryVariableNode.Inputs[2].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Value + tryVariableNode.Inputs[2].UpdateTextboxText("1"); + graph.AddNode(tryVariableNode, false); + graph.Connect(parseNode.Outputs[0], tryVariableNode.Inputs[0], false); + graph.Connect(declareVariableNode.Outputs[1], tryVariableNode.Inputs[1], false); + graph.Connect(tryVariableNode.Outputs[0], returnNode.Inputs[0], false); CreateStaticMainWithConversion(nodeClass, method); var output = Run(project, options); - Assert.Equal(1, output); + Assert.Equal(2, output); } [Theory] @@ -366,12 +383,12 @@ public void TestDeclareAndSetVariable(SerializableBuildOptions options) var entryNode = new EntryNode(graph); graph.AddNode(entryNode, false); - var declareVariableNode = new DeclareVariableNode(graph, "Variable"); + var declareVariableNode = new DeclareVariableNode(graph); declareVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Initial value declareVariableNode.Outputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Variable graph.AddNode(declareVariableNode, false); - var setVariableValueNode = new SetVariableValueNode(graph, "SetVariable"); + var setVariableValueNode = new SetVariableValueNode(graph); setVariableValueNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Variable setVariableValueNode.Inputs[2].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); // Value graph.AddNode(setVariableValueNode, false); @@ -411,7 +428,7 @@ public void TestDeclareVariableDefaultValue(SerializableBuildOptions options) var entryNode = new EntryNode(graph); graph.AddNode(entryNode, false); - var declareVariableNode = new DeclareVariableNode(graph, "Variable"); + var declareVariableNode = new DeclareVariableNode(graph); declareVariableNode.Inputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); declareVariableNode.Outputs[1].UpdateTypeAndTextboxVisibility(nodeClass.TypeFactory.Get(), true); graph.AddNode(declareVariableNode, false);