From c544e586d22fe1cf06e80c57ea3084f238bc2f2c Mon Sep 17 00:00:00 2001 From: john pierson Date: Mon, 8 Jun 2026 12:11:11 -0600 Subject: [PATCH 1/5] DYN-9663 fix missing parameter DataType in NodeDocumentationMarkdownGenerator BuildParameters in AssemblyHandler.cs extracted only the parameter name from each VarDeclNode, ignoring arg.ArgumentType. Pass the ProtoCore.Type to TypedParameter so TypeName and TypeRank are populated in the generated node help data. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- src/Tools/NodeDocumentationMarkdownGenerator/AssemblyHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tools/NodeDocumentationMarkdownGenerator/AssemblyHandler.cs b/src/Tools/NodeDocumentationMarkdownGenerator/AssemblyHandler.cs index 60c14eb112f..4f0b6b09c12 100644 --- a/src/Tools/NodeDocumentationMarkdownGenerator/AssemblyHandler.cs +++ b/src/Tools/NodeDocumentationMarkdownGenerator/AssemblyHandler.cs @@ -422,7 +422,7 @@ private static List BuildParameters(ArgumentSignatureNode signat } } - typeParams.Add(new TypedParameter(name)); + typeParams.Add(new TypedParameter(name, arg.ArgumentType)); } return typeParams; From 66d8a372293d3df57871a4d003aa99f82df690e4 Mon Sep 17 00:00:00 2001 From: john pierson Date: Mon, 8 Jun 2026 12:23:28 -0600 Subject: [PATCH 2/5] DYN-9663 fix missing DataType cell in output port table Output table had 3 column headers (Name, Description, DataType) but only emitted 2 cells per row, leaving the DataType column always empty. Add the missing DataType cell using GetTypeFromDescription, consistent with the input port table rendering. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../NodeDocumentationHtmlGenerator.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs b/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs index 505fadc90d1..5829012a2e2 100644 --- a/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs +++ b/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs @@ -292,6 +292,7 @@ private static string CreateInputsAndOutputs(OpenNodeAnnotationEventArgs e) sb.AppendLine(" "); sb.AppendLine($"{e.OutputNames.ElementAt(i)}"); sb.AppendLine($"{GetNthRowFromStringSplit(e.OutputDescriptions.ElementAt(i), 0)}"); + sb.AppendLine($"{GetTypeFromDescription(e.OutputDescriptions.ElementAt(i))}"); sb.AppendLine(@""); } From b2633993e97691df8692c2e19717b0db73b892c6 Mon Sep 17 00:00:00 2001 From: john pierson Date: Mon, 8 Jun 2026 13:02:33 -0600 Subject: [PATCH 3/5] DYN-9663 use GetInputPortType/GetOutPortType for doc browser type column GetTypeFromDescription parsed type from a multi-line tooltip string, which only worked when a parameter had a non-empty XML doc Summary. Nodes without Summary (common) or NodeModel nodes always showed empty type columns. Add InputTypes/OutputTypes to OpenNodeAnnotationEventArgs, populated via PortModel.GetInputPortType() and GetOutPortType() which correctly handle ZeroTouch, DesignScript, custom node, and NodeModel ([InPortTypes] attr) paths. Remove the now-unused GetTypeFromDescription helper. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- .../NodeDocumentationHtmlGenerator.cs | 11 ++--------- .../ViewModels/Core/DynamoViewModelEventArgs.cs | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs b/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs index 5829012a2e2..28185608796 100644 --- a/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs +++ b/src/DocumentationBrowserViewExtension/NodeDocumentationHtmlGenerator.cs @@ -268,7 +268,7 @@ private static string CreateInputsAndOutputs(OpenNodeAnnotationEventArgs e) { sb.AppendLine(""); sb.AppendLine($"{e.InputNames.ElementAt(i)}"); - sb.AppendLine($"{GetTypeFromDescription(e.InputDescriptions.ElementAt(i))}"); + sb.AppendLine($"{e.InputTypes.ElementAt(i)}"); sb.AppendLine($"{GetNthRowFromStringSplit(e.InputDescriptions.ElementAt(i), 0)}"); sb.AppendLine($"{GetDefaultValueFromDescription(e.InputDescriptions.ElementAt(i))}"); sb.AppendLine(@""); @@ -292,7 +292,7 @@ private static string CreateInputsAndOutputs(OpenNodeAnnotationEventArgs e) sb.AppendLine(" "); sb.AppendLine($"{e.OutputNames.ElementAt(i)}"); sb.AppendLine($"{GetNthRowFromStringSplit(e.OutputDescriptions.ElementAt(i), 0)}"); - sb.AppendLine($"{GetTypeFromDescription(e.OutputDescriptions.ElementAt(i))}"); + sb.AppendLine($"{e.OutputTypes.ElementAt(i)}"); sb.AppendLine(@""); } @@ -303,13 +303,6 @@ private static string CreateInputsAndOutputs(OpenNodeAnnotationEventArgs e) return sb.ToString(); } - private static string GetTypeFromDescription(string element) - { - var stringArr = element.Split(new string[] {"\r\n", "\r", "\n"}, StringSplitOptions.None); - if(stringArr.Length > 2) return stringArr[2]; - return string.Empty; - } - private static string GetDefaultValueFromDescription(string element) { var stringArr = element.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); diff --git a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelEventArgs.cs b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelEventArgs.cs index 5b766bba0a6..2a57be22486 100644 --- a/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelEventArgs.cs +++ b/src/DynamoCoreWpf/ViewModels/Core/DynamoViewModelEventArgs.cs @@ -217,6 +217,14 @@ public class OpenNodeAnnotationEventArgs : OpenDocumentationLinkEventArgs /// public IEnumerable OutputDescriptions { get; private set; } /// + /// Collection of the nodes input port types. + /// + public IEnumerable InputTypes { get; private set; } + /// + /// Collection of the nodes output port types. + /// + public IEnumerable OutputTypes { get; private set; } + /// /// Collection of the nodes collection of warnings/errors/infos. /// public IEnumerable NodeInfos { get; private set; } @@ -247,33 +255,38 @@ private void SetOutputs(NodeModel nodeModel) { var outputNames = new List(); var outputDescriptions = new List(); + var outputTypes = new List(); var outputs = nodeModel.OutPorts; foreach (var output in outputs) { outputNames.Add(output.Name); outputDescriptions.Add(output.ToolTip); + outputTypes.Add(output.GetOutPortType() ?? string.Empty); } OutputNames = outputNames; OutputDescriptions = outputDescriptions; + OutputTypes = outputTypes; } private void SetInputs(NodeModel nodeModel) { var inputNames = new List(); var inputDescriptions = new List(); + var inputTypes = new List(); var inputs = nodeModel.InPorts; foreach (var input in inputs) { inputNames.Add(input.Name); inputDescriptions.Add(input.ToolTip); + inputTypes.Add(input.GetInputPortType() ?? string.Empty); } InputNames = inputNames; InputDescriptions = inputDescriptions; - + InputTypes = inputTypes; } } From aa11f5c4c2fe0de06f2cdcf275212f9eec343538 Mon Sep 17 00:00:00 2001 From: john pierson Date: Mon, 8 Jun 2026 13:08:55 -0600 Subject: [PATCH 4/5] DYN-9663 infer NodeModel input port type from DefaultValue when no attribute NodeModel nodes without [InPortTypes] always returned null from GetInputPortType(), leaving the DataType column empty in the doc browser. As a fallback after the attribute check, infer the type string from the port's DefaultValue AST node: IntNode->int, DoubleNode->double, BooleanNode->bool, StringNode->string. Co-Authored-By: Claude Sonnet 4.6 (1M context) --- src/DynamoCore/Graph/Nodes/PortModel.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/DynamoCore/Graph/Nodes/PortModel.cs b/src/DynamoCore/Graph/Nodes/PortModel.cs index 821e6f6f4a3..481a060cd93 100644 --- a/src/DynamoCore/Graph/Nodes/PortModel.cs +++ b/src/DynamoCore/Graph/Nodes/PortModel.cs @@ -515,12 +515,23 @@ internal string GetInputPortType() try { - return inPortAttribute?.PortTypes.ElementAt(Index); + var attrType = inPortAttribute?.PortTypes.ElementAt(Index); + if (attrType != null) return attrType; } catch (Exception e) { Log(e.Message); } + + // Fallback: infer from the port's default value node type. + return DefaultValue switch + { + IntNode _ => "int", + DoubleNode _ => "double", + BooleanNode _ => "bool", + StringNode _ => "string", + _ => null + }; } return null; } From 1afece986ad9988ac3c03ec737a81f7f0d35abc5 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 12 Jun 2026 08:57:12 -0600 Subject: [PATCH 5/5] Address node annotation type review feedback Add the new OpenNodeAnnotationEventArgs input and output type properties to the WPF public API list. Cover the NodeModel input-port type fallback path for ports that omit InPortTypes but provide default value AST nodes. --- src/DynamoCoreWpf/PublicAPI.Unshipped.txt | 2 ++ test/DynamoCoreWpf3Tests/NodeViewTests.cs | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt index 946f2f99586..bc9d8900f77 100644 --- a/src/DynamoCoreWpf/PublicAPI.Unshipped.txt +++ b/src/DynamoCoreWpf/PublicAPI.Unshipped.txt @@ -26,6 +26,8 @@ Dynamo.ViewModels.DynamoViewModel.PythonEngineUpgradeToastRequested -> System.Ac Dynamo.ViewModels.DynamoViewModel.ToastManager.get -> Dynamo.Wpf.UI.ToastManager Dynamo.ViewModels.DynamoViewModel.ToastManager.set -> void Dynamo.ViewModels.DynamoViewModel.ShowPythonEngineUpgradeCanvasToast(string message, bool stayOpen = true, string filePath = null) -> void +Dynamo.ViewModels.OpenNodeAnnotationEventArgs.InputTypes.get -> System.Collections.Generic.IEnumerable +Dynamo.ViewModels.OpenNodeAnnotationEventArgs.OutputTypes.get -> System.Collections.Generic.IEnumerable Dynamo.ViewModels.PreferencesViewModel.AutoSyncDocumentBrowserIsChecked.get -> bool Dynamo.ViewModels.PreferencesViewModel.AutoSyncDocumentBrowserIsChecked.set -> void Dynamo.ViewModels.PreferencesViewModel.ShowPythonAutoMigrationNotificationIsChecked.get -> bool diff --git a/test/DynamoCoreWpf3Tests/NodeViewTests.cs b/test/DynamoCoreWpf3Tests/NodeViewTests.cs index f581679cd2e..1efa27b3e73 100644 --- a/test/DynamoCoreWpf3Tests/NodeViewTests.cs +++ b/test/DynamoCoreWpf3Tests/NodeViewTests.cs @@ -9,6 +9,7 @@ using System.Windows.Media; using Dynamo.Controls; using Dynamo.Graph; +using Dynamo.Graph.Nodes; using Dynamo.Graph.Workspaces; using Dynamo.Models; using Dynamo.Selection; @@ -16,12 +17,24 @@ using Dynamo.ViewModels; using DynamoCoreWpfTests.Utility; using NUnit.Framework; +using ProtoCore.AST.AssociativeAST; namespace DynamoCoreWpfTests { public class NodeViewTests : DynamoTestUIBase { // adapted from: http://stackoverflow.com/questions/9336165/correct-method-for-using-the-wpf-dispatcher-in-unit-tests + private class DefaultValueInputTypeNode : NodeModel + { + internal DefaultValueInputTypeNode() + { + InPorts.Add(new PortModel(PortType.Input, this, new PortData("integer", "integer", AstFactory.BuildIntNode(1)))); + InPorts.Add(new PortModel(PortType.Input, this, new PortData("number", "number", AstFactory.BuildDoubleNode(1.0)))); + InPorts.Add(new PortModel(PortType.Input, this, new PortData("boolean", "boolean", AstFactory.BuildBooleanNode(true)))); + InPorts.Add(new PortModel(PortType.Input, this, new PortData("text", "text", AstFactory.BuildStringNode("value")))); + RegisterAllPorts(); + } + } protected override void GetLibrariesToPreload(List libraries) { @@ -361,6 +374,16 @@ public void InputPortType_NodeModelNode_AreCorrect() Assert.AreEqual("System.Drawing.Bitmap", type); } + [Test] + public void InputPortType_NodeModelNodeWithoutInPortTypes_FallsBackToDefaultValueType() + { + var node = new DefaultValueInputTypeNode(); + + CollectionAssert.AreEqual( + new[] { "int", "double", "bool", "string" }, + node.InPorts.Select(port => port.GetInputPortType())); + } + [Test] [Category("RegressionTests")] public void GettingNodeNameDoesNotTriggerPropertyChangeCycle()