From 9541e7f12b7caf71257176c6b9c2caf464a5e5d4 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 15:59:46 +0000 Subject: [PATCH 1/5] test(view): record how a tree draws calculation, action and constraint parameters Directed parameters of calc, action and constraint definitions and usages render as attribute children of their owner, and an anonymous result parameter as a bare attribute. The fixture pins the rendering as it stands before the fix. Co-Authored-By: jason.han --- internal/ir/view/dot_test.go | 2 + internal/ir/view/plantuml_test.go | 2 + internal/ir/view/render_test.go | 2 + .../calc-parameter-definitions.d2.golden | 34 ++++++++ .../calc-parameter-definitions.dot.golden | 37 +++++++++ .../calc-parameter-definitions.mermaid.golden | 68 ++++++++++++++++ ...calc-parameter-definitions.plantuml.golden | 73 +++++++++++++++++ .../calc-parameter-definitions.text.golden | 32 ++++++++ .../view/testdata/calc-parameters.d2.golden | 41 ++++++++++ .../view/testdata/calc-parameters.dot.golden | 43 ++++++++++ .../testdata/calc-parameters.mermaid.golden | 75 ++++++++++++++++++ .../testdata/calc-parameters.plantuml.golden | 79 +++++++++++++++++++ .../ir/view/testdata/calc-parameters.sysml | 67 ++++++++++++++++ .../view/testdata/calc-parameters.text.golden | 36 +++++++++ 14 files changed, 591 insertions(+) create mode 100644 internal/ir/view/testdata/calc-parameter-definitions.d2.golden create mode 100644 internal/ir/view/testdata/calc-parameter-definitions.dot.golden create mode 100644 internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden create mode 100644 internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden create mode 100644 internal/ir/view/testdata/calc-parameter-definitions.text.golden create mode 100644 internal/ir/view/testdata/calc-parameters.d2.golden create mode 100644 internal/ir/view/testdata/calc-parameters.dot.golden create mode 100644 internal/ir/view/testdata/calc-parameters.mermaid.golden create mode 100644 internal/ir/view/testdata/calc-parameters.plantuml.golden create mode 100644 internal/ir/view/testdata/calc-parameters.sysml create mode 100644 internal/ir/view/testdata/calc-parameters.text.golden diff --git a/internal/ir/view/dot_test.go b/internal/ir/view/dot_test.go index 8788fcdf45..4ae6bfe3bb 100644 --- a/internal/ir/view/dot_test.go +++ b/internal/ir/view/dot_test.go @@ -56,6 +56,8 @@ func TestGoldenDOT(t *testing.T) { {"glyphs-definition", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::definitionGlyphs", KindDefinition, false}, {"glyphs-package", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::packageGlyphs", KindPackage, false}, {"glyphs-tree", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::treeGlyphs", KindTree, false}, + {"calc-parameters", "calc-parameters.sysml", "ParameterCalcViews::calculations", KindTree, false}, + {"calc-parameter-definitions", "calc-parameters.sysml", "ParameterCalcViews::definitions", KindTree, false}, {"glyphs-interconnection", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::lineGlyphs", KindInterconnection, false}, {"glyphs-action", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::fillGlyphs", KindAction, false}, {"glyphs-mixed", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::mixedGlyphs", KindMixed, false}, diff --git a/internal/ir/view/plantuml_test.go b/internal/ir/view/plantuml_test.go index ad4fc22260..3e3204746e 100644 --- a/internal/ir/view/plantuml_test.go +++ b/internal/ir/view/plantuml_test.go @@ -55,6 +55,8 @@ var plantumlGoldenCases = []struct { {"glyphs-definition", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::definitionGlyphs", KindDefinition}, {"glyphs-package", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::packageGlyphs", KindPackage}, {"glyphs-tree", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::treeGlyphs", KindTree}, + {"calc-parameters", "calc-parameters.sysml", "ParameterCalcViews::calculations", KindTree}, + {"calc-parameter-definitions", "calc-parameters.sysml", "ParameterCalcViews::definitions", KindTree}, {"glyphs-interconnection", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::lineGlyphs", KindInterconnection}, {"glyphs-action", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::fillGlyphs", KindAction}, {"glyphs-mixed", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::mixedGlyphs", KindMixed}, diff --git a/internal/ir/view/render_test.go b/internal/ir/view/render_test.go index 05c7edc1f9..c3c9e4eda0 100644 --- a/internal/ir/view/render_test.go +++ b/internal/ir/view/render_test.go @@ -172,6 +172,8 @@ func TestGoldenRenderings(t *testing.T) { {"glyphs-definition", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::definitionGlyphs", KindDefinition}, {"glyphs-package", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::packageGlyphs", KindPackage}, {"glyphs-tree", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::treeGlyphs", KindTree}, + {"calc-parameters", "calc-parameters.sysml", "ParameterCalcViews::calculations", KindTree}, + {"calc-parameter-definitions", "calc-parameters.sysml", "ParameterCalcViews::definitions", KindTree}, {"glyphs-interconnection", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::lineGlyphs", KindInterconnection}, {"glyphs-action", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::fillGlyphs", KindAction}, {"glyphs-mixed", "notation-glyphs.sysml", "NotationGlyphs::Diagrams::mixedGlyphs", KindMixed}, diff --git a/internal/ir/view/testdata/calc-parameter-definitions.d2.golden b/internal/ir/view/testdata/calc-parameter-definitions.d2.golden new file mode 100644 index 0000000000..727224746b --- /dev/null +++ b/internal/ir/view/testdata/calc-parameter-definitions.d2.golden @@ -0,0 +1,34 @@ +# ParameterCalcViews::definitions — tree rendering (render asTreeDiagram) +classes: { + definition: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14 } } + usage: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14; border-radius: 8 } } + reference: { source-arrowhead: { shape: diamond; style: { filled: false } }; style: { stroke: "#181818"; font-size: 13; font-color: black; stroke-width: 1 } } +} +n0: "«calc def»\nAdd" { class: definition } +n1: "«attribute»\nx" { class: usage } +n2: "«attribute»\ny" { class: usage } +n3: "attribute" { class: usage } +n4: "«calc def»\nScale" { class: definition } +n5: "«attribute»\nx" { class: usage } +n6: "«attribute»\nfactor" { class: usage } +n7: "«attribute»\ncount" { class: usage } +n8: "«attribute»\ndoubled" { class: usage } +n9: "«attribute»\nr" { class: usage } +n10: "«action def»\nHeat" { class: definition } +n11: "«attribute»\nbread" { class: usage } +n12: "«attribute»\ntoast" { class: usage } +n13: "«constraint def»\nBetween" { class: definition } +n14: "«attribute»\nlow" { class: usage } +n15: "«attribute»\nvalue" { class: usage } +n0 <- n1: { class: reference } +n0 <- n2: { class: reference } +n0 <- n3: { class: reference } +n4 <- n5: { class: reference } +n4 <- n6: { class: reference } +n4 <- n7: { class: reference } +n4 <- n8: { class: reference } +n4 <- n9: { class: reference } +n10 <- n11: { class: reference } +n10 <- n12: { class: reference } +n13 <- n14: { class: reference } +n13 <- n15: { class: reference } diff --git a/internal/ir/view/testdata/calc-parameter-definitions.dot.golden b/internal/ir/view/testdata/calc-parameter-definitions.dot.golden new file mode 100644 index 0000000000..798945e766 --- /dev/null +++ b/internal/ir/view/testdata/calc-parameter-definitions.dot.golden @@ -0,0 +1,37 @@ +// view: ParameterCalcViews::definitions +// kind: tree +// stated: render asTreeDiagram +// layout: dot +digraph "ParameterCalcViews::definitions" { + graph [fontname="Helvetica"]; + node [shape=box, style=filled, fillcolor=white, color="#181818", fontname="Helvetica", fontsize=14, penwidth=0.5]; + edge [color="#181818", fontname="Helvetica", fontsize=13, penwidth=1]; + "n0" [label=<«calc def»
Add>]; + "n1" [style="rounded,filled", label=<«attribute»
x>]; + "n2" [style="rounded,filled", label=<«attribute»
y>]; + "n3" [style="rounded,filled", label=<attribute>]; + "n4" [label=<«calc def»
Scale>]; + "n5" [style="rounded,filled", label=<«attribute»
x>]; + "n6" [style="rounded,filled", label=<«attribute»
factor>]; + "n7" [style="rounded,filled", label=<«attribute»
count>]; + "n8" [style="rounded,filled", label=<«attribute»
doubled>]; + "n9" [style="rounded,filled", label=<«attribute»
r>]; + "n10" [label=<«action def»
Heat>]; + "n11" [style="rounded,filled", label=<«attribute»
bread>]; + "n12" [style="rounded,filled", label=<«attribute»
toast>]; + "n13" [label=<«constraint def»
Between>]; + "n14" [style="rounded,filled", label=<«attribute»
low>]; + "n15" [style="rounded,filled", label=<«attribute»
value>]; + "n0" -> "n1" [dir=back, arrowtail=odiamond]; + "n0" -> "n2" [dir=back, arrowtail=odiamond]; + "n0" -> "n3" [dir=back, arrowtail=odiamond]; + "n4" -> "n5" [dir=back, arrowtail=odiamond]; + "n4" -> "n6" [dir=back, arrowtail=odiamond]; + "n4" -> "n7" [dir=back, arrowtail=odiamond]; + "n4" -> "n8" [dir=back, arrowtail=odiamond]; + "n4" -> "n9" [dir=back, arrowtail=odiamond]; + "n10" -> "n11" [dir=back, arrowtail=odiamond]; + "n10" -> "n12" [dir=back, arrowtail=odiamond]; + "n13" -> "n14" [dir=back, arrowtail=odiamond]; + "n13" -> "n15" [dir=back, arrowtail=odiamond]; +} diff --git a/internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden b/internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden new file mode 100644 index 0000000000..2abf8aeb0c --- /dev/null +++ b/internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden @@ -0,0 +1,68 @@ +--- +config: + fontFamily: "Helvetica, Arial, sans-serif" + theme: base + themeCSS: ".edgeLabel rect { opacity: 1 !important; } .cluster-label .nodeLabel { text-align: center; }" + themeVariables: + fontFamily: "Helvetica, Arial, sans-serif" + fontSize: "14px" + primaryColor: "#FFFFFF" + secondaryColor: "#FFFFFF" + tertiaryColor: "#FFFFFF" + background: "#FFFFFF" + primaryBorderColor: "#181818" + primaryTextColor: "#000000" + lineColor: "#181818" + textColor: "#000000" + noteBkgColor: "#FEFFDD" + noteBorderColor: "#181818" + noteTextColor: "#000000" + clusterBkg: "#FFFFFF" + clusterBorder: "#181818" + edgeLabelBackground: "#FFFFFF" +--- +%% ParameterCalcViews::definitions — tree rendering (render asTreeDiagram) +flowchart TD + n0["`*«calc def»* +**Add**`"] + n1("`*«attribute»* +**x**`") + n2("`*«attribute»* +**y**`") + n3("`**attribute**`") + n4["`*«calc def»* +**Scale**`"] + n5("`*«attribute»* +**x**`") + n6("`*«attribute»* +**factor**`") + n7("`*«attribute»* +**count**`") + n8("`*«attribute»* +**doubled**`") + n9("`*«attribute»* +**r**`") + n10["`*«action def»* +**Heat**`"] + n11("`*«attribute»* +**bread**`") + n12("`*«attribute»* +**toast**`") + n13["`*«constraint def»* +**Between**`"] + n14("`*«attribute»* +**low**`") + n15("`*«attribute»* +**value**`") + n0 ---|"◇"| n1 + n0 ---|"◇"| n2 + n0 ---|"◇"| n3 + n4 ---|"◇"| n5 + n4 ---|"◇"| n6 + n4 ---|"◇"| n7 + n4 ---|"◇"| n8 + n4 ---|"◇"| n9 + n10 ---|"◇"| n11 + n10 ---|"◇"| n12 + n13 ---|"◇"| n14 + n13 ---|"◇"| n15 diff --git a/internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden b/internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden new file mode 100644 index 0000000000..4674090656 --- /dev/null +++ b/internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden @@ -0,0 +1,73 @@ +@startuml +' ParameterCalcViews::definitions — tree rendering (render asTreeDiagram) + +skinparam wrapWidth 300 +hide stereotype +hide circle +hide empty members +class "//«calc def»//\n**Add**" as n0 <> +class "//«attribute»//\n**x**" as n1 <> <> +class "//«attribute»//\n**y**" as n2 <> <> +class "**attribute**" as n3 <> <> +class "//«calc def»//\n**Scale**" as n4 <> +class "//«attribute»//\n**x**" as n5 <> <> +class "//«attribute»//\n**factor**" as n6 <> <> +class "//«attribute»//\n**count**" as n7 <> <> +class "//«attribute»//\n**doubled**" as n8 <> <> +class "//«attribute»//\n**r**" as n9 <> <> +class "//«action def»//\n**Heat**" as n10 <> +class "//«attribute»//\n**bread**" as n11 <> <> +class "//«attribute»//\n**toast**" as n12 <> <> +class "//«constraint def»//\n**Between**" as n13 <> +class "//«attribute»//\n**low**" as n14 <> <> +class "//«attribute»//\n**value**" as n15 <> <> +n0 o-- n1 +n0 o-- n2 +n0 o-- n3 +n4 o-- n5 +n4 o-- n6 +n4 o-- n7 +n4 o-- n8 +n4 o-- n9 +n10 o-- n11 +n10 o-- n12 +n13 o-- n14 +n13 o-- n15 +@enduml diff --git a/internal/ir/view/testdata/calc-parameter-definitions.text.golden b/internal/ir/view/testdata/calc-parameter-definitions.text.golden new file mode 100644 index 0000000000..a2643012c4 --- /dev/null +++ b/internal/ir/view/testdata/calc-parameter-definitions.text.golden @@ -0,0 +1,32 @@ +ParameterCalcViews::definitions - tree rendering (render asTreeDiagram) + +calc def Add + attribute x + attribute y + attribute +calc def Scale + attribute x + attribute factor + attribute count + attribute doubled + attribute r +action def Heat + attribute bread + attribute toast +constraint def Between + attribute low + attribute value + +relationships: + Add o-- x + Add o-- y + Add o-- attribute n3 + Scale o-- x + Scale o-- factor + Scale o-- count + Scale o-- doubled + Scale o-- r + Heat o-- bread + Heat o-- toast + Between o-- low + Between o-- value diff --git a/internal/ir/view/testdata/calc-parameters.d2.golden b/internal/ir/view/testdata/calc-parameters.d2.golden new file mode 100644 index 0000000000..e8d1f3ab4c --- /dev/null +++ b/internal/ir/view/testdata/calc-parameters.d2.golden @@ -0,0 +1,41 @@ +# ParameterCalcViews::calculations — tree rendering (render asTreeDiagram) +classes: { + definition: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14 } } + usage: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14; border-radius: 8 } } + edge: { style: { stroke: "#181818"; font-size: 13; font-color: black; stroke-width: 1 } } + reference: { source-arrowhead: { shape: diamond; style: { filled: false } }; style: { stroke: "#181818"; font-size: 13; font-color: black; stroke-width: 1 } } +} +n0: "«calc»\nadd" { class: usage } +n1: "«attribute»\nx" { class: usage } +n2: "«attribute»\ny" { class: usage } +n3: "attribute" { class: usage } +n4: "«part def»\nSensor" { class: definition } +n5: "«attribute»\na" { class: usage } +n6: "«attribute»\nb" { class: usage } +n7: "«attribute»\ngain" { class: usage } +n8: "«calc»\nsum" { class: usage } +n9: "«attribute»\nx" { class: usage } +n10: "«attribute»\n^y" { class: usage } +n11: "attribute" { class: usage } +n12: "«calc»\nscaled" { class: usage } +n13: "«attribute»\nfactor" { class: usage } +n14: "«attribute»\n^x" { class: usage } +n15: "«attribute»\n^count" { class: usage } +n16: "«attribute»\n^doubled" { class: usage } +n17: "«attribute»\n^r" { class: usage } +n4 -- n8: { class: edge } +n4 -- n12: { class: edge } +n0 <- n1: { class: reference } +n0 <- n2: { class: reference } +n0 <- n3: { class: reference } +n4 <- n5: { class: reference } +n4 <- n6: { class: reference } +n4 <- n7: { class: reference } +n8 <- n9: { class: reference } +n8 <- n10: { class: reference } +n8 <- n11: { class: reference } +n12 <- n13: { class: reference } +n12 <- n14: { class: reference } +n12 <- n15: { class: reference } +n12 <- n16: { class: reference } +n12 <- n17: { class: reference } diff --git a/internal/ir/view/testdata/calc-parameters.dot.golden b/internal/ir/view/testdata/calc-parameters.dot.golden new file mode 100644 index 0000000000..559e6cddaa --- /dev/null +++ b/internal/ir/view/testdata/calc-parameters.dot.golden @@ -0,0 +1,43 @@ +// view: ParameterCalcViews::calculations +// kind: tree +// stated: render asTreeDiagram +// layout: dot +digraph "ParameterCalcViews::calculations" { + graph [fontname="Helvetica"]; + node [shape=box, style=filled, fillcolor=white, color="#181818", fontname="Helvetica", fontsize=14, penwidth=0.5]; + edge [color="#181818", fontname="Helvetica", fontsize=13, penwidth=1]; + "n0" [style="rounded,filled", label=<«calc»
add>]; + "n1" [style="rounded,filled", label=<«attribute»
x>]; + "n2" [style="rounded,filled", label=<«attribute»
y>]; + "n3" [style="rounded,filled", label=<attribute>]; + "n4" [label=<«part def»
Sensor>]; + "n5" [style="rounded,filled", label=<«attribute»
a>]; + "n6" [style="rounded,filled", label=<«attribute»
b>]; + "n7" [style="rounded,filled", label=<«attribute»
gain>]; + "n8" [style="rounded,filled", label=<«calc»
sum>]; + "n9" [style="rounded,filled", label=<«attribute»
x>]; + "n10" [style="rounded,filled", label=<«attribute»
^y>]; + "n11" [style="rounded,filled", label=<attribute>]; + "n4" -> "n8" [arrowhead=none]; + "n12" [style="rounded,filled", label=<«calc»
scaled>]; + "n13" [style="rounded,filled", label=<«attribute»
factor>]; + "n14" [style="rounded,filled", label=<«attribute»
^x>]; + "n15" [style="rounded,filled", label=<«attribute»
^count>]; + "n16" [style="rounded,filled", label=<«attribute»
^doubled>]; + "n17" [style="rounded,filled", label=<«attribute»
^r>]; + "n4" -> "n12" [arrowhead=none]; + "n0" -> "n1" [dir=back, arrowtail=odiamond]; + "n0" -> "n2" [dir=back, arrowtail=odiamond]; + "n0" -> "n3" [dir=back, arrowtail=odiamond]; + "n4" -> "n5" [dir=back, arrowtail=odiamond]; + "n4" -> "n6" [dir=back, arrowtail=odiamond]; + "n4" -> "n7" [dir=back, arrowtail=odiamond]; + "n8" -> "n9" [dir=back, arrowtail=odiamond]; + "n8" -> "n10" [dir=back, arrowtail=odiamond]; + "n8" -> "n11" [dir=back, arrowtail=odiamond]; + "n12" -> "n13" [dir=back, arrowtail=odiamond]; + "n12" -> "n14" [dir=back, arrowtail=odiamond]; + "n12" -> "n15" [dir=back, arrowtail=odiamond]; + "n12" -> "n16" [dir=back, arrowtail=odiamond]; + "n12" -> "n17" [dir=back, arrowtail=odiamond]; +} diff --git a/internal/ir/view/testdata/calc-parameters.mermaid.golden b/internal/ir/view/testdata/calc-parameters.mermaid.golden new file mode 100644 index 0000000000..a0efef42c0 --- /dev/null +++ b/internal/ir/view/testdata/calc-parameters.mermaid.golden @@ -0,0 +1,75 @@ +--- +config: + fontFamily: "Helvetica, Arial, sans-serif" + theme: base + themeCSS: ".edgeLabel rect { opacity: 1 !important; } .cluster-label .nodeLabel { text-align: center; }" + themeVariables: + fontFamily: "Helvetica, Arial, sans-serif" + fontSize: "14px" + primaryColor: "#FFFFFF" + secondaryColor: "#FFFFFF" + tertiaryColor: "#FFFFFF" + background: "#FFFFFF" + primaryBorderColor: "#181818" + primaryTextColor: "#000000" + lineColor: "#181818" + textColor: "#000000" + noteBkgColor: "#FEFFDD" + noteBorderColor: "#181818" + noteTextColor: "#000000" + clusterBkg: "#FFFFFF" + clusterBorder: "#181818" + edgeLabelBackground: "#FFFFFF" +--- +%% ParameterCalcViews::calculations — tree rendering (render asTreeDiagram) +flowchart TD + n0("`*«calc»* +**add**`") + n1("`*«attribute»* +**x**`") + n2("`*«attribute»* +**y**`") + n3("`**attribute**`") + n4["`*«part def»* +**Sensor**`"] + n5("`*«attribute»* +**a**`") + n6("`*«attribute»* +**b**`") + n7("`*«attribute»* +**gain**`") + n8("`*«calc»* +**sum**`") + n9("`*«attribute»* +**x**`") + n10("`*«attribute»* +**^y**`") + n11("`**attribute**`") + n4 --- n8 + n12("`*«calc»* +**scaled**`") + n13("`*«attribute»* +**factor**`") + n14("`*«attribute»* +**^x**`") + n15("`*«attribute»* +**^count**`") + n16("`*«attribute»* +**^doubled**`") + n17("`*«attribute»* +**^r**`") + n4 --- n12 + n0 ---|"◇"| n1 + n0 ---|"◇"| n2 + n0 ---|"◇"| n3 + n4 ---|"◇"| n5 + n4 ---|"◇"| n6 + n4 ---|"◇"| n7 + n8 ---|"◇"| n9 + n8 ---|"◇"| n10 + n8 ---|"◇"| n11 + n12 ---|"◇"| n13 + n12 ---|"◇"| n14 + n12 ---|"◇"| n15 + n12 ---|"◇"| n16 + n12 ---|"◇"| n17 diff --git a/internal/ir/view/testdata/calc-parameters.plantuml.golden b/internal/ir/view/testdata/calc-parameters.plantuml.golden new file mode 100644 index 0000000000..7af145c7dd --- /dev/null +++ b/internal/ir/view/testdata/calc-parameters.plantuml.golden @@ -0,0 +1,79 @@ +@startuml +' ParameterCalcViews::calculations — tree rendering (render asTreeDiagram) + +skinparam wrapWidth 300 +hide stereotype +hide circle +hide empty members +class "//«calc»//\n**add**" as n0 <> <> +class "//«attribute»//\n**x**" as n1 <> <> +class "//«attribute»//\n**y**" as n2 <> <> +class "**attribute**" as n3 <> <> +class "//«part def»//\n**Sensor**" as n4 <> +class "//«attribute»//\n**a**" as n5 <> <> +class "//«attribute»//\n**b**" as n6 <> <> +class "//«attribute»//\n**gain**" as n7 <> <> +class "//«calc»//\n**sum**" as n8 <> <> +class "//«attribute»//\n**x**" as n9 <> <> +class "//«attribute»//\n**^y**" as n10 <> <> +class "**attribute**" as n11 <> <> +n4 -- n8 +class "//«calc»//\n**scaled**" as n12 <> <> +class "//«attribute»//\n**factor**" as n13 <> <> +class "//«attribute»//\n**^x**" as n14 <> <> +class "//«attribute»//\n**^count**" as n15 <> <> +class "//«attribute»//\n**^doubled**" as n16 <> <> +class "//«attribute»//\n**^r**" as n17 <> <> +n4 -- n12 +n0 o-- n1 +n0 o-- n2 +n0 o-- n3 +n4 o-- n5 +n4 o-- n6 +n4 o-- n7 +n8 o-- n9 +n8 o-- n10 +n8 o-- n11 +n12 o-- n13 +n12 o-- n14 +n12 o-- n15 +n12 o-- n16 +n12 o-- n17 +@enduml diff --git a/internal/ir/view/testdata/calc-parameters.sysml b/internal/ir/view/testdata/calc-parameters.sysml new file mode 100644 index 0000000000..35558f8f0b --- /dev/null +++ b/internal/ir/view/testdata/calc-parameters.sysml @@ -0,0 +1,67 @@ +// The directed parameters of calculations, actions and constraints: a tree draws them as +// parameter pins of their owner rather than as attribute members, and names the anonymous +// result parameter `result` as the standard names it. A calc usage typed by a calc def shows +// each parameter once: its own redefining one and the def's others as inherited. +package ParameterCalcs { + private import ScalarValues::*; + + // The reporter's shape: an anonymous result declared by `return`. + calc add { + in x : Integer; + in y : Integer; + return : Integer; + x + y + } + + calc def Add { + in x : Integer; + in y : Integer; + return : Integer = x + y; + } + + // Every direction, and a named result. + calc def Scale { + in x : Real; + in factor : Real; + inout count : Integer; + out doubled : Real = x + x; + return r : Real = x * factor; + } + + action def Heat { + in bread : Integer; + out toast : Integer; + } + + constraint def Between { + in attribute low : Real; + in attribute value : Real; + value >= low + } + + part def Sensor { + attribute a : Integer; + attribute b : Integer; + attribute gain : Real; + calc sum : Add { in x = a; } + calc scaled : Scale { in factor = gain; } + } +} + +package ParameterCalcViews { + private import Views::*; + + view calculations { + expose ParameterCalcs::add; + expose ParameterCalcs::Sensor; + render asTreeDiagram; + } + + view definitions { + expose ParameterCalcs::Add; + expose ParameterCalcs::Scale; + expose ParameterCalcs::Heat; + expose ParameterCalcs::Between; + render asTreeDiagram; + } +} diff --git a/internal/ir/view/testdata/calc-parameters.text.golden b/internal/ir/view/testdata/calc-parameters.text.golden new file mode 100644 index 0000000000..555ea9251f --- /dev/null +++ b/internal/ir/view/testdata/calc-parameters.text.golden @@ -0,0 +1,36 @@ +ParameterCalcViews::calculations - tree rendering (render asTreeDiagram) + +calc add + attribute x + attribute y + attribute +part def Sensor + attribute a + attribute b + attribute gain + calc sum + attribute x + attribute ^y + attribute + calc scaled + attribute factor + attribute ^x + attribute ^count + attribute ^doubled + attribute ^r + +relationships: + add o-- x + add o-- y + add o-- attribute n3 + Sensor o-- a + Sensor o-- b + Sensor o-- gain + sum o-- x + sum o-- y + sum o-- attribute n11 + scaled o-- factor + scaled o-- x + scaled o-- count + scaled o-- doubled + scaled o-- r From ec1dff06f9608260bb811bdc2246ef53af5cd873 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 Oct 2026 16:16:32 +0000 Subject: [PATCH 2/5] fix(view): render directed calc parameters as parameter pins in tree views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A tree drew the directed parameters of a calculation, action or constraint definition or usage as attribute members with membership edges, and an anonymous return as a bare attribute: treeNode appended every non-pinned member as a child and labelled it by its default kind, never reading its direction. They are now parameter pins of their owner's node, as §8.2.3.17, §8.2.3.19 and §8.2.3.20 set them, the anonymous result named result, a usage typed by a definition showing each parameter once. The text form lists the pins direction first, DOT and D2 draw them, Mermaid and PlantUML list them in a parameters compartment; a tree keeps them whatever parameter-symbols says, as it keeps its members. Co-Authored-By: jason.han --- .../unreleased/calc-parameter-pins.fixed.md | 1 + docs/project/view-rendering-forms.md | 22 ++- docs/reference/cli.md | 7 + internal/ir/view/d2.go | 11 +- internal/ir/view/label.go | 19 +++ internal/ir/view/mermaid.go | 2 + internal/ir/view/narrow.go | 3 +- internal/ir/view/plantuml.go | 4 + internal/ir/view/ports.go | 11 +- .../calc-parameter-definitions.d2.golden | 55 ++++--- .../calc-parameter-definitions.dot.golden | 32 +--- .../calc-parameter-definitions.mermaid.golden | 65 +++----- ...calc-parameter-definitions.plantuml.golden | 32 +--- .../calc-parameter-definitions.text.golden | 38 ++--- .../view/testdata/calc-parameters.d2.golden | 64 ++++---- .../view/testdata/calc-parameters.dot.golden | 46 ++---- .../testdata/calc-parameters.mermaid.golden | 73 ++++----- .../testdata/calc-parameters.plantuml.golden | 46 ++---- .../view/testdata/calc-parameters.text.golden | 33 ++-- internal/ir/view/text.go | 10 +- internal/ir/view/tree.go | 18 ++- internal/ir/view/tree_parameters.go | 54 +++++++ internal/ir/view/tree_parameters_test.go | 141 ++++++++++++++++++ 23 files changed, 444 insertions(+), 343 deletions(-) create mode 100644 changes/unreleased/calc-parameter-pins.fixed.md create mode 100644 internal/ir/view/tree_parameters.go create mode 100644 internal/ir/view/tree_parameters_test.go diff --git a/changes/unreleased/calc-parameter-pins.fixed.md b/changes/unreleased/calc-parameter-pins.fixed.md new file mode 100644 index 0000000000..b746b8f477 --- /dev/null +++ b/changes/unreleased/calc-parameter-pins.fixed.md @@ -0,0 +1 @@ +- A tree rendering (`-render '#tree:…'`, `%viz`, the Jupyter kernel's default) drew the directed parameters of a calculation, action or constraint definition or usage — `in x`, `out y`, `return` — as `attribute` members with membership edges, and an anonymous `return` as a bare `attribute`. They are now parameter pins of their owner's node, direction first (`in x : Integer`), the anonymous result named `result` as the standard names it; a usage typed by a definition shows each parameter once, the definition's as inherited. The text form lists them under the node, DOT and D2 draw them as pins, Mermaid and PlantUML list them in a `parameters` compartment. diff --git a/docs/project/view-rendering-forms.md b/docs/project/view-rendering-forms.md index 3e0dca64fd..4bcaec65c1 100644 --- a/docs/project/view-rendering-forms.md +++ b/docs/project/view-rendering-forms.md @@ -43,7 +43,18 @@ the usage's end — the glyphs of SysML v2 §8.2.3.6, the diamond read from the `Feature::isComposite` (`semantics.Model.UsageIsComposite`: a `ref`, an attribute, a port outside a port, an end, a directed or an enumeration usage is non-composite). The writers draw that edge in place of the containment line they draw to every other child, so a usage hangs off its owner by its -membership glyph alone. A usage listed in a compartment row instead of drawn as a node (the +membership glyph alone. The directed parameters of a calculation, action or constraint definition +or usage — `in`, `out`, `inout` and `return` — are no member nodes of a tree: `treeParameter` +(`tree_parameters.go`) pins each on its owner's node as a `Port` with `Parameter` set and the +direction `pinDirection` reads, where §8.2.3.17, §8.2.3.19 and §8.2.3.20 set a calc's, action's and +constraint's parameters (`param-l*`, `param-r*`, `param-b*`). A `return` declaring no name is the +`result` pin, named by the `Function::result` it redefines (§7.19.2); a usage typed by a definition +pins each parameter once, its own redefining ones as declared and the definition's others as +inherited (`^y`). The text form lists the pins under their node direction first (`in x : Integer`, +the type under `typings`), DOT and D2 draw them as pins, and Mermaid's flowchart and PlantUML's +class diagram, which have no pin on a tree node, list them in a `parameters` compartment +(`labeller.parameterLines`). The pins are the tree's model structure and stay whatever +`parameter-symbols` says, as its members do. A usage listed in a compartment row instead of drawn as a node (the compartment foldings, or a positioned tree's unplaced members) folds its membership and typing into one edge from its owner to each drawn definition, labelled with the usage's name and multiplicity at the definition's end — the property association a block definition diagram draws. Both @@ -451,7 +462,7 @@ table records what each rendering feature writes: | Feature | Mermaid syntax and behavior | | --- | --- | | Definitions, regions, package kinds | Square flowchart nodes, `n0["…"]`; cases use stadium nodes, actors and subjects use keyword-bearing rectangles, and objectives use note nodes. Other non-symbol leaves are rounded `n0("…")` nodes. Cameo follows the DOT skin's rounded rule. | -| Tree containment | Plain shaped nodes joined by `---`; tree nodes are never subgraphs and have no synthetic anchors. | +| Tree containment | Plain shaped nodes joined by `---`; tree nodes are never subgraphs and have no synthetic anchors. A calc's, action's or constraint's parameter pins are lines of the node's label under a `parameters` heading (`in x : Integer`). | | Initial, final, junction, fork and join | `f-circ` for initial and junction nodes, `fr-circ` for final nodes, and `fork` for fork/join bars. Only fork/join bars use the `control` class. Named fork/join nodes are listed in a notice because the bar draws no label. | | Decision, merge, choice and history | Diamonds; empty and synthesized decision names use a blank diamond. Shallow/deep history use `(("H"))` and `(("H*"))`. | | State pseudostates and final transitions | Mermaid state stereotypes (`<>`, `<>`, `<>`) and `[*]` for initial/final markers. A final in the same state body is implicit; cross-body final transitions retain the explicit final and receive a notice. | @@ -1203,7 +1214,8 @@ pseudostate shape only when nothing else is attached. Mermaid and DOT trees draw containment — a tree of edges, no nested containers — so the three forms show the same picture and a tree has no blocks. The Pilot's `comp def`/`comp usage` element kinds exist only in the PlantUML fork and are not emitted; every element is a standard - `class`. + `class`, a calc's, action's or constraint's parameter pins listed in its label under a + `parameters` heading, as the Mermaid tree lists them. - **`interconnection`** — nested `rectangle` blocks: a node with children is `rectangle "…" as n <> {` … `}`, indented two spaces a level, a leaf a one-line `rectangle`. A port is a nested rectangle inside its owner, not a `portin`/`portout`: the released jar's port grammar @@ -1391,8 +1403,8 @@ attribute a rendering in the model chooses it by: | Element | Attribute | What it draws | Optional by | | --- | --- | --- | --- | -| `parameter-symbols` | `showParameterSymbols` | A case's `actor`, `subject` and `stakeholder` parameters and an action's parameter pins as squares on the node's boundary. Without them a connection that ended at a parameter ends at the node that declares it: one line per connection, one node per actor. A tree lists a case's parameters as members, which stay. | §7.26.5; §8.2.3 `distinguished-parameter`, `distinguished-parameter-link` | -| `port-symbols` | `showPortSymbols` | A part's ports, and a constraint's parameters, as pins on its boundary. Without them a connection that ended at a port ends at the part, a binding that ended at a parameter at the constraint; a port drawn as a nested member of a tree is model structure and stays. Default. | §7.26.5; §8.2.3 `port-node` | +| `parameter-symbols` | `showParameterSymbols` | A case's `actor`, `subject` and `stakeholder` parameters and an action's parameter pins as squares on the node's boundary. Without them a connection that ended at a parameter ends at the node that declares it: one line per connection, one node per actor. A tree lists a case's parameters as members and a calc's, action's or constraint's as pins of their owner, all of which stay. | §7.26.5; §8.2.3 `distinguished-parameter`, `distinguished-parameter-link` | +| `port-symbols` | `showPortSymbols` | A part's ports, and a constraint's parameters, as pins on its boundary. Without them a connection that ended at a port ends at the part, a binding that ended at a parameter at the constraint; a port drawn as a nested member of a tree is model structure and stays, as are a tree's parameter pins. Default. | §7.26.5; §8.2.3 `port-node` | | `compartments` | `showCompartments` | The lists of nested features inside a node. Default. | §7.26.5; §8.2.3 `compartment` | | `edge-labels` | `showEdgeLabels` | The names of connections, flows, bindings and allocations along their lines. Without them no label box is left. A sequence diagram's message lines keep their labels: the label is the message. | §8.2.3 `edge-label` | | `keywords` | `showKeywords` | The `«keyword»` over each name (`«part def»`, `«part»`, `«enum def»`, …), as the notation's examples, the pilot and SysON draw every node. Default. | §8.2.3 `keyword-list` | diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 1485cc00a2..83e01e033e 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -859,6 +859,13 @@ pins in the edge's label (`n0 -- n1 : bread = b`) and the pins in a `' not repre draws the pins an edge ends at as nodes nested in their owner, and names the rest in a `# not represented:` notice. +A tree rendering draws the directed parameters of a calculation, action or constraint definition or +usage — `in`, `out`, `inout` and `return` — as parameter pins of their owner's node rather than as +nested members, a `return` declaring no name as the `result` output: `text` lists them under the +node direction first (`in x : Integer` with `typings` shown), `dot` and `d2` draw them as pins, and +`mermaid` and `plantuml` list them in a `parameters` compartment of the node's label. A usage typed +by a definition shows each parameter once, the definition's as inherited (`^y`). + Every `subgraph` of a Mermaid flowchart opens on a `direction` statement restating the flowchart's, because Mermaid lays out a subgraph that states none without regard to the flowchart's; a tree draws containment as edges, not subgraphs, so it carries none. diff --git a/internal/ir/view/d2.go b/internal/ir/view/d2.go index c6cf8cc9e8..97ce3d7b53 100644 --- a/internal/ir/view/d2.go +++ b/internal/ir/view/d2.go @@ -354,10 +354,10 @@ func (w *d2Writer) writeNode(node *Node, scope, indent string) { } // pins are the ports drawn inside a node: an interconnection's under the -// ports display, an action's the ones an edge ends at. +// ports display, a tree's parameter pins, an action's the ones an edge ends at. func (w *d2Writer) pins(node *Node) []Port { switch { - case w.ports.interconnection: + case w.ports.interconnection, w.ports.tree: return w.ports.of(node) case w.ports.action: var pins []Port @@ -373,9 +373,12 @@ func (w *d2Writer) pins(node *Node) []Port { // pinLabel is a pin's label: on an interconnection the port's stereotype over // `name : Type` under the full display and the name alone under the minimal, -// on an action the pin's name. +// on a tree the parameter's direction, name and type, on an action the pin's name. func (w *d2Writer) pinLabel(port Port) string { - if !w.ports.interconnection { + switch { + case w.ports.tree: + return parameterPinLine(port) + case !w.ports.interconnection: return port.displayName() } label := w.ports.pinLabel(port) diff --git a/internal/ir/view/label.go b/internal/ir/view/label.go index 89313f5bc3..10cf6dc129 100644 --- a/internal/ir/view/label.go +++ b/internal/ir/view/label.go @@ -17,6 +17,9 @@ type labeller struct { simple map[*Node]string // a node's distinguishing suffix, when names are drawn simple skin dotSkin // the DOT skin labels are composed and measured for shown Shown // the optional notation elements the labels carry + // pinLines lists a node's parameter pins as label lines, for a form that + // draws no pin on a tree node. + pinLines bool } // labelsOf finds the namespace the named roots share — the longest run of @@ -349,6 +352,7 @@ func (l labeller) lines(node *Node) []string { } lines = append(lines, l.headLines(node)...) lines = append(lines, l.details(node)...) + lines = append(lines, l.parameterLines(node)...) return append(lines, l.compartmentLines(node)...) } @@ -361,9 +365,24 @@ func (l labeller) titleLines(node *Node) []string { } lines = append(lines, head...) lines = append(lines, l.details(node)...) + lines = append(lines, l.parameterLines(node)...) return append(lines, l.compartmentLines(node)...) } +// parameterLines are a node's parameter pins as the notation's `parameters` +// compartment, `in x : Integer` a line under the heading, where pinLines asks +// for them; nothing for a node with no pin. +func (l labeller) parameterLines(node *Node) []string { + if !l.pinLines || len(node.Ports) == 0 { + return nil + } + lines := []string{"parameters"} + for _, port := range node.Ports { + lines = append(lines, parameterPinLine(port)) + } + return lines +} + // cameoStateDetails splits a state's detail into Cameo's compartment lines, one // per behaviour, and drops the `initial` marker the initial dot already draws. // The detail is split as notation, so a name quoting a comma stays one; the diff --git a/internal/ir/view/mermaid.go b/internal/ir/view/mermaid.go index 799a180a0c..d8f6016113 100644 --- a/internal/ir/view/mermaid.go +++ b/internal/ir/view/mermaid.go @@ -46,6 +46,7 @@ func (r *Rendering) MermaidWith(options Options) string { direction := options.Direction var b strings.Builder labels := labelsOf(r.Roots, false, nil, r.Shown) + labels.pinLines = r.Kind == KindTree labels.skin = skinOf(options.Style) ports := r.portView(options.Ports) r.writeMermaidFrontmatter(&b, labels, options, ports) @@ -1288,6 +1289,7 @@ func mermaidLabel(node *Node, labels labeller, lines []string, title bool) strin markdown = append(markdown, "**"+line+"**") } markdown = append(markdown, labels.details(node)...) + markdown = append(markdown, labels.parameterLines(node)...) markdown = append(markdown, labels.compartmentLines(node)...) return `"` + "`" + strings.Join(markdown, "\n") + "`" + `"` } diff --git a/internal/ir/view/narrow.go b/internal/ir/view/narrow.go index 476d7436c5..442f9a9b5d 100644 --- a/internal/ir/view/narrow.go +++ b/internal/ir/view/narrow.go @@ -125,7 +125,8 @@ func (n *narrowing) narrow(node *Node) { for _, port := range node.Ports { pinShown := n.shown.Has(ElementPortSymbols) if port.Parameter { - pinShown = n.shown.Has(ElementParameterSymbols) + // A tree's parameter pins are model structure, listed as its members are. + pinShown = n.shown.Has(ElementParameterSymbols) || n.kind == KindTree } if !pinShown { n.redirect[port.ID] = node.ID diff --git a/internal/ir/view/plantuml.go b/internal/ir/view/plantuml.go index 6514f466f7..7c1d5f0f33 100644 --- a/internal/ir/view/plantuml.go +++ b/internal/ir/view/plantuml.go @@ -51,6 +51,7 @@ func (r *Rendering) PlantUMLWith(options Options) (string, error) { w := &plantumlWriter{kind: r.Kind, borders: r.Kind.paletteBorders(), fills: familyFills{palette: options.Palette, tree: r.Kind == KindTree}, labels: labelsOf(r.Roots, false, nil, r.Shown), ports: r.portView(options.Ports), links: options.Links, writtenPorts: make(map[string]struct{}), nesting: r.nestingEdges()} + w.labels.pinLines = r.Kind == KindTree for _, root := range r.Roots { w.fills.collect(root) } @@ -707,6 +708,9 @@ func (w *plantumlWriter) plantumlLabel(node *Node) string { for _, line := range w.labels.details(node) { parts = append(parts, plantumlText(line)) } + for _, line := range w.labels.parameterLines(node) { + parts = append(parts, plantumlText(line)) + } for _, line := range w.labels.compartmentLines(node) { parts = append(parts, plantumlText(line)) } diff --git a/internal/ir/view/ports.go b/internal/ir/view/ports.go index 444b9880ab..b3369de15c 100644 --- a/internal/ir/view/ports.go +++ b/internal/ir/view/ports.go @@ -85,9 +85,12 @@ type portView struct { // whose pins text writes under their nodes. interconnection bool action bool - mixed bool - minimal bool - connected map[string]bool + // tree reports a tree rendering, whose pins are the parameters of its + // calculations, actions and constraints, written direction first. + tree bool + mixed bool + minimal bool + connected map[string]bool } // portView is the ports the rendering draws under display, the minimal @@ -99,7 +102,7 @@ func (r *Rendering) portView(display Ports) portView { return r.portViewOver(dis // no pin stands for a connector the form leaves out. func (r *Rendering) portViewOver(display Ports, edges []Edge) portView { v := portView{interconnection: r.Kind == KindInterconnection || r.Kind == KindMixed, action: r.Kind == KindAction, - mixed: r.Kind == KindMixed, minimal: display != PortsFull && r.Kind.SupportsPorts()} + tree: r.Kind == KindTree, mixed: r.Kind == KindMixed, minimal: display != PortsFull && r.Kind.SupportsPorts()} if !v.minimal { return v } diff --git a/internal/ir/view/testdata/calc-parameter-definitions.d2.golden b/internal/ir/view/testdata/calc-parameter-definitions.d2.golden index 727224746b..4aade7cee2 100644 --- a/internal/ir/view/testdata/calc-parameter-definitions.d2.golden +++ b/internal/ir/view/testdata/calc-parameter-definitions.d2.golden @@ -1,34 +1,29 @@ # ParameterCalcViews::definitions — tree rendering (render asTreeDiagram) classes: { definition: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14 } } - usage: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14; border-radius: 8 } } - reference: { source-arrowhead: { shape: diamond; style: { filled: false } }; style: { stroke: "#181818"; font-size: 13; font-color: black; stroke-width: 1 } } + pin: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 10 } } +} +n0: "«calc def»\nAdd" { + class: definition + "n0.0": "in x" { class: pin } + "n0.1": "in y" { class: pin } + "n0.2": "out result" { class: pin } +} +n1: "«calc def»\nScale" { + class: definition + "n1.0": "in x" { class: pin } + "n1.1": "in factor" { class: pin } + "n1.2": "inout count" { class: pin } + "n1.3": "out doubled" { class: pin } + "n1.4": "out r" { class: pin } +} +n2: "«action def»\nHeat" { + class: definition + "n2.0": "in bread" { class: pin } + "n2.1": "out toast" { class: pin } +} +n3: "«constraint def»\nBetween" { + class: definition + "n3.0": "in low" { class: pin } + "n3.1": "in value" { class: pin } } -n0: "«calc def»\nAdd" { class: definition } -n1: "«attribute»\nx" { class: usage } -n2: "«attribute»\ny" { class: usage } -n3: "attribute" { class: usage } -n4: "«calc def»\nScale" { class: definition } -n5: "«attribute»\nx" { class: usage } -n6: "«attribute»\nfactor" { class: usage } -n7: "«attribute»\ncount" { class: usage } -n8: "«attribute»\ndoubled" { class: usage } -n9: "«attribute»\nr" { class: usage } -n10: "«action def»\nHeat" { class: definition } -n11: "«attribute»\nbread" { class: usage } -n12: "«attribute»\ntoast" { class: usage } -n13: "«constraint def»\nBetween" { class: definition } -n14: "«attribute»\nlow" { class: usage } -n15: "«attribute»\nvalue" { class: usage } -n0 <- n1: { class: reference } -n0 <- n2: { class: reference } -n0 <- n3: { class: reference } -n4 <- n5: { class: reference } -n4 <- n6: { class: reference } -n4 <- n7: { class: reference } -n4 <- n8: { class: reference } -n4 <- n9: { class: reference } -n10 <- n11: { class: reference } -n10 <- n12: { class: reference } -n13 <- n14: { class: reference } -n13 <- n15: { class: reference } diff --git a/internal/ir/view/testdata/calc-parameter-definitions.dot.golden b/internal/ir/view/testdata/calc-parameter-definitions.dot.golden index 798945e766..0f8f933987 100644 --- a/internal/ir/view/testdata/calc-parameter-definitions.dot.golden +++ b/internal/ir/view/testdata/calc-parameter-definitions.dot.golden @@ -6,32 +6,8 @@ digraph "ParameterCalcViews::definitions" { graph [fontname="Helvetica"]; node [shape=box, style=filled, fillcolor=white, color="#181818", fontname="Helvetica", fontsize=14, penwidth=0.5]; edge [color="#181818", fontname="Helvetica", fontsize=13, penwidth=1]; - "n0" [label=<«calc def»
Add>]; - "n1" [style="rounded,filled", label=<«attribute»
x>]; - "n2" [style="rounded,filled", label=<«attribute»
y>]; - "n3" [style="rounded,filled", label=<attribute>]; - "n4" [label=<«calc def»
Scale>]; - "n5" [style="rounded,filled", label=<«attribute»
x>]; - "n6" [style="rounded,filled", label=<«attribute»
factor>]; - "n7" [style="rounded,filled", label=<«attribute»
count>]; - "n8" [style="rounded,filled", label=<«attribute»
doubled>]; - "n9" [style="rounded,filled", label=<«attribute»
r>]; - "n10" [label=<«action def»
Heat>]; - "n11" [style="rounded,filled", label=<«attribute»
bread>]; - "n12" [style="rounded,filled", label=<«attribute»
toast>]; - "n13" [label=<«constraint def»
Between>]; - "n14" [style="rounded,filled", label=<«attribute»
low>]; - "n15" [style="rounded,filled", label=<«attribute»
value>]; - "n0" -> "n1" [dir=back, arrowtail=odiamond]; - "n0" -> "n2" [dir=back, arrowtail=odiamond]; - "n0" -> "n3" [dir=back, arrowtail=odiamond]; - "n4" -> "n5" [dir=back, arrowtail=odiamond]; - "n4" -> "n6" [dir=back, arrowtail=odiamond]; - "n4" -> "n7" [dir=back, arrowtail=odiamond]; - "n4" -> "n8" [dir=back, arrowtail=odiamond]; - "n4" -> "n9" [dir=back, arrowtail=odiamond]; - "n10" -> "n11" [dir=back, arrowtail=odiamond]; - "n10" -> "n12" [dir=back, arrowtail=odiamond]; - "n13" -> "n14" [dir=back, arrowtail=odiamond]; - "n13" -> "n15" [dir=back, arrowtail=odiamond]; + "n0" [label=<
xy
«calc def»
Add
result
>]; + "n1" [label=<
xfactorcount
«calc def»
Scale
doubledr
>]; + "n2" [label=<
bread
«action def»
Heat
toast
>]; + "n3" [label=<
lowvalue
«constraint def»
Between
>]; } diff --git a/internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden b/internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden index 2abf8aeb0c..83d2437e42 100644 --- a/internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden +++ b/internal/ir/view/testdata/calc-parameter-definitions.mermaid.golden @@ -24,45 +24,26 @@ config: %% ParameterCalcViews::definitions — tree rendering (render asTreeDiagram) flowchart TD n0["`*«calc def»* -**Add**`"] - n1("`*«attribute»* -**x**`") - n2("`*«attribute»* -**y**`") - n3("`**attribute**`") - n4["`*«calc def»* -**Scale**`"] - n5("`*«attribute»* -**x**`") - n6("`*«attribute»* -**factor**`") - n7("`*«attribute»* -**count**`") - n8("`*«attribute»* -**doubled**`") - n9("`*«attribute»* -**r**`") - n10["`*«action def»* -**Heat**`"] - n11("`*«attribute»* -**bread**`") - n12("`*«attribute»* -**toast**`") - n13["`*«constraint def»* -**Between**`"] - n14("`*«attribute»* -**low**`") - n15("`*«attribute»* -**value**`") - n0 ---|"◇"| n1 - n0 ---|"◇"| n2 - n0 ---|"◇"| n3 - n4 ---|"◇"| n5 - n4 ---|"◇"| n6 - n4 ---|"◇"| n7 - n4 ---|"◇"| n8 - n4 ---|"◇"| n9 - n10 ---|"◇"| n11 - n10 ---|"◇"| n12 - n13 ---|"◇"| n14 - n13 ---|"◇"| n15 +**Add** +parameters +in x +in y +out result`"] + n1["`*«calc def»* +**Scale** +parameters +in x +in factor +inout count +out doubled +out r`"] + n2["`*«action def»* +**Heat** +parameters +in bread +out toast`"] + n3["`*«constraint def»* +**Between** +parameters +in low +in value`"] diff --git a/internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden b/internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden index 4674090656..2a1a68467b 100644 --- a/internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden +++ b/internal/ir/view/testdata/calc-parameter-definitions.plantuml.golden @@ -42,32 +42,8 @@ skinparam wrapWidth 300 hide stereotype hide circle hide empty members -class "//«calc def»//\n**Add**" as n0 <> -class "//«attribute»//\n**x**" as n1 <> <> -class "//«attribute»//\n**y**" as n2 <> <> -class "**attribute**" as n3 <> <> -class "//«calc def»//\n**Scale**" as n4 <> -class "//«attribute»//\n**x**" as n5 <> <> -class "//«attribute»//\n**factor**" as n6 <> <> -class "//«attribute»//\n**count**" as n7 <> <> -class "//«attribute»//\n**doubled**" as n8 <> <> -class "//«attribute»//\n**r**" as n9 <> <> -class "//«action def»//\n**Heat**" as n10 <> -class "//«attribute»//\n**bread**" as n11 <> <> -class "//«attribute»//\n**toast**" as n12 <> <> -class "//«constraint def»//\n**Between**" as n13 <> -class "//«attribute»//\n**low**" as n14 <> <> -class "//«attribute»//\n**value**" as n15 <> <> -n0 o-- n1 -n0 o-- n2 -n0 o-- n3 -n4 o-- n5 -n4 o-- n6 -n4 o-- n7 -n4 o-- n8 -n4 o-- n9 -n10 o-- n11 -n10 o-- n12 -n13 o-- n14 -n13 o-- n15 +class "//«calc def»//\n**Add**\nparameters\nin x\nin y\nout result" as n0 <> +class "//«calc def»//\n**Scale**\nparameters\nin x\nin factor\ninout count\nout doubled\nout r" as n1 <> +class "//«action def»//\n**Heat**\nparameters\nin bread\nout toast" as n2 <> +class "//«constraint def»//\n**Between**\nparameters\nin low\nin value" as n3 <> @enduml diff --git a/internal/ir/view/testdata/calc-parameter-definitions.text.golden b/internal/ir/view/testdata/calc-parameter-definitions.text.golden index a2643012c4..582be1b594 100644 --- a/internal/ir/view/testdata/calc-parameter-definitions.text.golden +++ b/internal/ir/view/testdata/calc-parameter-definitions.text.golden @@ -1,32 +1,18 @@ ParameterCalcViews::definitions - tree rendering (render asTreeDiagram) calc def Add - attribute x - attribute y - attribute + in x + in y + out result calc def Scale - attribute x - attribute factor - attribute count - attribute doubled - attribute r + in x + in factor + inout count + out doubled + out r action def Heat - attribute bread - attribute toast + in bread + out toast constraint def Between - attribute low - attribute value - -relationships: - Add o-- x - Add o-- y - Add o-- attribute n3 - Scale o-- x - Scale o-- factor - Scale o-- count - Scale o-- doubled - Scale o-- r - Heat o-- bread - Heat o-- toast - Between o-- low - Between o-- value + in low + in value diff --git a/internal/ir/view/testdata/calc-parameters.d2.golden b/internal/ir/view/testdata/calc-parameters.d2.golden index e8d1f3ab4c..b0c0beb94c 100644 --- a/internal/ir/view/testdata/calc-parameters.d2.golden +++ b/internal/ir/view/testdata/calc-parameters.d2.golden @@ -2,40 +2,36 @@ classes: { definition: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14 } } usage: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 14; border-radius: 8 } } + pin: { style: { fill: white; stroke: "#181818"; stroke-width: 1; font-color: black; font-size: 10 } } edge: { style: { stroke: "#181818"; font-size: 13; font-color: black; stroke-width: 1 } } reference: { source-arrowhead: { shape: diamond; style: { filled: false } }; style: { stroke: "#181818"; font-size: 13; font-color: black; stroke-width: 1 } } } -n0: "«calc»\nadd" { class: usage } -n1: "«attribute»\nx" { class: usage } -n2: "«attribute»\ny" { class: usage } -n3: "attribute" { class: usage } -n4: "«part def»\nSensor" { class: definition } -n5: "«attribute»\na" { class: usage } -n6: "«attribute»\nb" { class: usage } -n7: "«attribute»\ngain" { class: usage } -n8: "«calc»\nsum" { class: usage } -n9: "«attribute»\nx" { class: usage } -n10: "«attribute»\n^y" { class: usage } -n11: "attribute" { class: usage } -n12: "«calc»\nscaled" { class: usage } -n13: "«attribute»\nfactor" { class: usage } -n14: "«attribute»\n^x" { class: usage } -n15: "«attribute»\n^count" { class: usage } -n16: "«attribute»\n^doubled" { class: usage } -n17: "«attribute»\n^r" { class: usage } -n4 -- n8: { class: edge } -n4 -- n12: { class: edge } -n0 <- n1: { class: reference } -n0 <- n2: { class: reference } -n0 <- n3: { class: reference } -n4 <- n5: { class: reference } -n4 <- n6: { class: reference } -n4 <- n7: { class: reference } -n8 <- n9: { class: reference } -n8 <- n10: { class: reference } -n8 <- n11: { class: reference } -n12 <- n13: { class: reference } -n12 <- n14: { class: reference } -n12 <- n15: { class: reference } -n12 <- n16: { class: reference } -n12 <- n17: { class: reference } +n0: "«calc»\nadd" { + class: usage + "n0.0": "in x" { class: pin } + "n0.1": "in y" { class: pin } + "n0.2": "out result" { class: pin } +} +n1: "«part def»\nSensor" { class: definition } +n2: "«attribute»\na" { class: usage } +n3: "«attribute»\nb" { class: usage } +n4: "«attribute»\ngain" { class: usage } +n5: "«calc»\nsum" { + class: usage + "n5.0": "in x" { class: pin } + "n5.1": "in ^y" { class: pin } + "n5.2": "out ^result" { class: pin } +} +n6: "«calc»\nscaled" { + class: usage + "n6.0": "in factor" { class: pin } + "n6.1": "in ^x" { class: pin } + "n6.2": "inout ^count" { class: pin } + "n6.3": "out ^doubled" { class: pin } + "n6.4": "out ^r" { class: pin } +} +n1 -- n5: { class: edge } +n1 -- n6: { class: edge } +n1 <- n2: { class: reference } +n1 <- n3: { class: reference } +n1 <- n4: { class: reference } diff --git a/internal/ir/view/testdata/calc-parameters.dot.golden b/internal/ir/view/testdata/calc-parameters.dot.golden index 559e6cddaa..8d9e7d4217 100644 --- a/internal/ir/view/testdata/calc-parameters.dot.golden +++ b/internal/ir/view/testdata/calc-parameters.dot.golden @@ -6,38 +6,16 @@ digraph "ParameterCalcViews::calculations" { graph [fontname="Helvetica"]; node [shape=box, style=filled, fillcolor=white, color="#181818", fontname="Helvetica", fontsize=14, penwidth=0.5]; edge [color="#181818", fontname="Helvetica", fontsize=13, penwidth=1]; - "n0" [style="rounded,filled", label=<«calc»
add>]; - "n1" [style="rounded,filled", label=<«attribute»
x>]; - "n2" [style="rounded,filled", label=<«attribute»
y>]; - "n3" [style="rounded,filled", label=<attribute>]; - "n4" [label=<«part def»
Sensor>]; - "n5" [style="rounded,filled", label=<«attribute»
a>]; - "n6" [style="rounded,filled", label=<«attribute»
b>]; - "n7" [style="rounded,filled", label=<«attribute»
gain>]; - "n8" [style="rounded,filled", label=<«calc»
sum>]; - "n9" [style="rounded,filled", label=<«attribute»
x>]; - "n10" [style="rounded,filled", label=<«attribute»
^y>]; - "n11" [style="rounded,filled", label=<attribute>]; - "n4" -> "n8" [arrowhead=none]; - "n12" [style="rounded,filled", label=<«calc»
scaled>]; - "n13" [style="rounded,filled", label=<«attribute»
factor>]; - "n14" [style="rounded,filled", label=<«attribute»
^x>]; - "n15" [style="rounded,filled", label=<«attribute»
^count>]; - "n16" [style="rounded,filled", label=<«attribute»
^doubled>]; - "n17" [style="rounded,filled", label=<«attribute»
^r>]; - "n4" -> "n12" [arrowhead=none]; - "n0" -> "n1" [dir=back, arrowtail=odiamond]; - "n0" -> "n2" [dir=back, arrowtail=odiamond]; - "n0" -> "n3" [dir=back, arrowtail=odiamond]; - "n4" -> "n5" [dir=back, arrowtail=odiamond]; - "n4" -> "n6" [dir=back, arrowtail=odiamond]; - "n4" -> "n7" [dir=back, arrowtail=odiamond]; - "n8" -> "n9" [dir=back, arrowtail=odiamond]; - "n8" -> "n10" [dir=back, arrowtail=odiamond]; - "n8" -> "n11" [dir=back, arrowtail=odiamond]; - "n12" -> "n13" [dir=back, arrowtail=odiamond]; - "n12" -> "n14" [dir=back, arrowtail=odiamond]; - "n12" -> "n15" [dir=back, arrowtail=odiamond]; - "n12" -> "n16" [dir=back, arrowtail=odiamond]; - "n12" -> "n17" [dir=back, arrowtail=odiamond]; + "n0" [style="rounded,filled", label=<
xy
«calc»
add
result
>]; + "n1" [label=<«part def»
Sensor>]; + "n2" [style="rounded,filled", label=<«attribute»
a>]; + "n3" [style="rounded,filled", label=<«attribute»
b>]; + "n4" [style="rounded,filled", label=<«attribute»
gain>]; + "n5" [style="rounded,filled", label=<
x^y
«calc»
sum
^result
>]; + "n1" -> "n5" [arrowhead=none]; + "n6" [style="rounded,filled", label=<
factor^x^count
«calc»
scaled
^doubled^r
>]; + "n1" -> "n6" [arrowhead=none]; + "n1" -> "n2" [dir=back, arrowtail=odiamond]; + "n1" -> "n3" [dir=back, arrowtail=odiamond]; + "n1" -> "n4" [dir=back, arrowtail=odiamond]; } diff --git a/internal/ir/view/testdata/calc-parameters.mermaid.golden b/internal/ir/view/testdata/calc-parameters.mermaid.golden index a0efef42c0..8899d01595 100644 --- a/internal/ir/view/testdata/calc-parameters.mermaid.golden +++ b/internal/ir/view/testdata/calc-parameters.mermaid.golden @@ -24,52 +24,35 @@ config: %% ParameterCalcViews::calculations — tree rendering (render asTreeDiagram) flowchart TD n0("`*«calc»* -**add**`") - n1("`*«attribute»* -**x**`") - n2("`*«attribute»* -**y**`") - n3("`**attribute**`") - n4["`*«part def»* +**add** +parameters +in x +in y +out result`") + n1["`*«part def»* **Sensor**`"] - n5("`*«attribute»* + n2("`*«attribute»* **a**`") - n6("`*«attribute»* + n3("`*«attribute»* **b**`") - n7("`*«attribute»* + n4("`*«attribute»* **gain**`") - n8("`*«calc»* -**sum**`") - n9("`*«attribute»* -**x**`") - n10("`*«attribute»* -**^y**`") - n11("`**attribute**`") - n4 --- n8 - n12("`*«calc»* -**scaled**`") - n13("`*«attribute»* -**factor**`") - n14("`*«attribute»* -**^x**`") - n15("`*«attribute»* -**^count**`") - n16("`*«attribute»* -**^doubled**`") - n17("`*«attribute»* -**^r**`") - n4 --- n12 - n0 ---|"◇"| n1 - n0 ---|"◇"| n2 - n0 ---|"◇"| n3 - n4 ---|"◇"| n5 - n4 ---|"◇"| n6 - n4 ---|"◇"| n7 - n8 ---|"◇"| n9 - n8 ---|"◇"| n10 - n8 ---|"◇"| n11 - n12 ---|"◇"| n13 - n12 ---|"◇"| n14 - n12 ---|"◇"| n15 - n12 ---|"◇"| n16 - n12 ---|"◇"| n17 + n5("`*«calc»* +**sum** +parameters +in x +in ^y +out ^result`") + n1 --- n5 + n6("`*«calc»* +**scaled** +parameters +in factor +in ^x +inout ^count +out ^doubled +out ^r`") + n1 --- n6 + n1 ---|"◇"| n2 + n1 ---|"◇"| n3 + n1 ---|"◇"| n4 diff --git a/internal/ir/view/testdata/calc-parameters.plantuml.golden b/internal/ir/view/testdata/calc-parameters.plantuml.golden index 7af145c7dd..272057e020 100644 --- a/internal/ir/view/testdata/calc-parameters.plantuml.golden +++ b/internal/ir/view/testdata/calc-parameters.plantuml.golden @@ -42,38 +42,16 @@ skinparam wrapWidth 300 hide stereotype hide circle hide empty members -class "//«calc»//\n**add**" as n0 <> <> -class "//«attribute»//\n**x**" as n1 <> <> -class "//«attribute»//\n**y**" as n2 <> <> -class "**attribute**" as n3 <> <> -class "//«part def»//\n**Sensor**" as n4 <> -class "//«attribute»//\n**a**" as n5 <> <> -class "//«attribute»//\n**b**" as n6 <> <> -class "//«attribute»//\n**gain**" as n7 <> <> -class "//«calc»//\n**sum**" as n8 <> <> -class "//«attribute»//\n**x**" as n9 <> <> -class "//«attribute»//\n**^y**" as n10 <> <> -class "**attribute**" as n11 <> <> -n4 -- n8 -class "//«calc»//\n**scaled**" as n12 <> <> -class "//«attribute»//\n**factor**" as n13 <> <> -class "//«attribute»//\n**^x**" as n14 <> <> -class "//«attribute»//\n**^count**" as n15 <> <> -class "//«attribute»//\n**^doubled**" as n16 <> <> -class "//«attribute»//\n**^r**" as n17 <> <> -n4 -- n12 -n0 o-- n1 -n0 o-- n2 -n0 o-- n3 -n4 o-- n5 -n4 o-- n6 -n4 o-- n7 -n8 o-- n9 -n8 o-- n10 -n8 o-- n11 -n12 o-- n13 -n12 o-- n14 -n12 o-- n15 -n12 o-- n16 -n12 o-- n17 +class "//«calc»//\n**add**\nparameters\nin x\nin y\nout result" as n0 <> <> +class "//«part def»//\n**Sensor**" as n1 <> +class "//«attribute»//\n**a**" as n2 <> <> +class "//«attribute»//\n**b**" as n3 <> <> +class "//«attribute»//\n**gain**" as n4 <> <> +class "//«calc»//\n**sum**\nparameters\nin x\nin ^y\nout ^result" as n5 <> <> +n1 -- n5 +class "//«calc»//\n**scaled**\nparameters\nin factor\nin ^x\ninout ^count\nout ^doubled\nout ^r" as n6 <> <> +n1 -- n6 +n1 o-- n2 +n1 o-- n3 +n1 o-- n4 @enduml diff --git a/internal/ir/view/testdata/calc-parameters.text.golden b/internal/ir/view/testdata/calc-parameters.text.golden index 555ea9251f..1b3639696f 100644 --- a/internal/ir/view/testdata/calc-parameters.text.golden +++ b/internal/ir/view/testdata/calc-parameters.text.golden @@ -1,36 +1,25 @@ ParameterCalcViews::calculations - tree rendering (render asTreeDiagram) calc add - attribute x - attribute y - attribute + in x + in y + out result part def Sensor attribute a attribute b attribute gain calc sum - attribute x - attribute ^y - attribute + in x + in ^y + out ^result calc scaled - attribute factor - attribute ^x - attribute ^count - attribute ^doubled - attribute ^r + in factor + in ^x + inout ^count + out ^doubled + out ^r relationships: - add o-- x - add o-- y - add o-- attribute n3 Sensor o-- a Sensor o-- b Sensor o-- gain - sum o-- x - sum o-- y - sum o-- attribute n11 - scaled o-- factor - scaled o-- x - scaled o-- count - scaled o-- doubled - scaled o-- r diff --git a/internal/ir/view/text.go b/internal/ir/view/text.go index fb56305045..6ab87d6f5c 100644 --- a/internal/ir/view/text.go +++ b/internal/ir/view/text.go @@ -245,7 +245,7 @@ func writeNodeText(b *strings.Builder, node *Node, depth int, labels map[string] b.WriteString(strings.Repeat(" ", depth+2) + rowLine(row) + "\n") } } - if ports.interconnection || ports.action { + if ports.interconnection || ports.action || ports.tree { for _, port := range ports.of(node) { labels[port.ID] = labels[node.ID] + "." + port.Name b.WriteString(strings.Repeat(" ", depth+1) + pinLine(port, ports) + "\n") @@ -289,10 +289,14 @@ func hiddenEdges(r *Rendering) []Edge { return edges } -// pinLine is a part port's `port