From dcdcb5629d1f7760762a8d7dcca6d1425f4d3b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Mon, 15 Apr 2024 14:30:54 +0200 Subject: [PATCH] Merge array bindings in AbsynUtil.mergeAnnotations (#12249) - Add special case for array bindings in `AbsynUtil.mergeAnnotations` to allow merging e.g. `Diagram(graphics = {...})` annotations with `loadClassContentString`. --- OMCompiler/Compiler/FrontEnd/AbsynUtil.mo | 46 +++++++++++++++++++ .../openmodelica/diff/AddClassAnnotation1.mos | 5 +- .../interactive-API/AddClassAnnotation.mos | 12 ++--- .../openmodelica/interactive-API/Makefile | 1 + .../interactive_api_classes.mos | 12 ++--- .../loadClassContentString2.mos | 22 +++++++++ 6 files changed, 83 insertions(+), 15 deletions(-) create mode 100644 testsuite/openmodelica/interactive-API/loadClassContentString2.mos diff --git a/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo b/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo index a21888437d3..1a2567a719d 100644 --- a/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo +++ b/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo @@ -4003,6 +4003,7 @@ algorithm try mod2 := List.find(res, function isModificationOfPath(path=p)); mod1 := subModsInSameOrder(mod2, mod); + mod1 := mergeAnnotationEqMod(mod2, mod1); (res, true) := List.replaceOnTrue(mod1, res, function isModificationOfPath(path=p)); else res := mod::res; @@ -4011,6 +4012,51 @@ algorithm res := listReverse(res); end mergeAnnotations2; +function mergeAnnotationEqMod + input Absyn.ElementArg oldMod; + input output Absyn.ElementArg newMod; +protected + Absyn.Modification mod1, mod2; +algorithm + () := match (oldMod, newMod) + case (Absyn.ElementArg.MODIFICATION(modification = SOME(mod1)), + Absyn.ElementArg.MODIFICATION()) + algorithm + if isSome(newMod.modification) then + SOME(mod2) := newMod.modification; + mod2.eqMod := mergeAnnotationEqMod2(mod1.eqMod, mod2.eqMod); + newMod.modification := SOME(mod2); + else + newMod.modification := SOME(mod1); + end if; + then + (); + + else (); + end match; +end mergeAnnotationEqMod; + +function mergeAnnotationEqMod2 + input Absyn.EqMod oldEqMod; + input output Absyn.EqMod newEqMod; +protected + Absyn.Exp e1, e2; +algorithm + newEqMod := match (oldEqMod, newEqMod) + // Special merging rule for annotations, concatenate array bindings + // (such as Diagram(graphics = {...})). + case (Absyn.EqMod.EQMOD(exp = e1 as Absyn.Exp.ARRAY()), + Absyn.EqMod.EQMOD(exp = e2 as Absyn.Exp.ARRAY())) + algorithm + newEqMod.exp := Absyn.Exp.ARRAY(listAppend(e1.arrayExp, e2.arrayExp)); + then + newEqMod; + + case (_, Absyn.EqMod.EQMOD()) then newEqMod; + else oldEqMod; + end match; +end mergeAnnotationEqMod2; + public function mergeCommentAnnotation "Merges an annotation into a Absyn.Comment option." input Absyn.Annotation inAnnotation; diff --git a/testsuite/openmodelica/diff/AddClassAnnotation1.mos b/testsuite/openmodelica/diff/AddClassAnnotation1.mos index 99884629a54..ac1dc0324df 100644 --- a/testsuite/openmodelica/diff/AddClassAnnotation1.mos +++ b/testsuite/openmodelica/diff/AddClassAnnotation1.mos @@ -24,9 +24,8 @@ answer := "model M1 Line(points={{-60,50},{60,50}}, color={0,0,255}), Line(points={{0,90},{0,50}}, color={0,0,255})}), Diagram(coordinateSystem( - preserveAspectRatio=false, - extent={{-100,-100},{100,100}}, initialScale = 0.1, grid = {2, 2}), graphics={ - Line(points={{-60,50},{60,50}}, color={0,0,255}), Rectangle(origin = {-30, -43}, extent = {{-74, 49}, {74, -49}})})); + preserveAspectRatio=false, extent = {{-100, -100}, {100, 100}, {-100, -100}, {100, 100}}, initialScale = 0.1, grid = {2, 2}), graphics={ + Line(points={{-60,50},{60,50}}, color={0,0,255}), Line(points = {{-60, 50}, {60, 50}}, color = {0, 0, 255}), Rectangle(origin = {-30, -43}, extent = {{-74, 49}, {74, -49}})})); end M1;"; s2 := listFile(M1); s3 := diffModelicaFileListings(s1, s2, OpenModelica.Scripting.DiffFormat.plain); diff --git a/testsuite/openmodelica/interactive-API/AddClassAnnotation.mos b/testsuite/openmodelica/interactive-API/AddClassAnnotation.mos index 46e38d3de61..65f8f905070 100644 --- a/testsuite/openmodelica/interactive-API/AddClassAnnotation.mos +++ b/testsuite/openmodelica/interactive-API/AddClassAnnotation.mos @@ -48,10 +48,10 @@ getIconAnnotation(EB); // true // true // true -// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0, 50}, {100, 0}, {0, -50}, {0, 50}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100, 100}, {100, -100}}, 0)}} -// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0, 50}, {100, 0}, {0, -50}, {0, 50}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100, 100}, {100, -100}}, 0)}} -// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0, 50}, {100, 0}, {0, -50}, {0, 50}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100, 100}, {100, -100}}, 0)}} -// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0, 50}, {100, 0}, {0, -50}, {0, 50}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100, 100}, {100, -100}}, 0)}} -// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0, 50}, {100, 0}, {0, -50}, {0, 50}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100, 100}, {100, -100}}, 0)}} -// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0, 50}, {100, 0}, {0, -50}, {0, 50}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100, 100}, {100, -100}}, 0)}} +// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{-100.0, 100.0}, {100.0, 0.0}, {-100.0, -100.0}}, Smooth.None), Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0.0, 50.0}, {100.0, 0.0}, {0.0, -50.0}, {0.0, 50.0}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0.0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100.0, 100.0}, {100.0, -100.0}}, 0.0)}} +// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0.0, 50.0}, {100.0, 0.0}, {0.0, -50.0}, {0.0, 50.0}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0.0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100.0, 100.0}, {100.0, -100.0}}, 0.0)}} +// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{-100.0, 100.0}, {100.0, 0.0}, {-100.0, -100.0}}, Smooth.None), Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0.0, 50.0}, {100.0, 0.0}, {0.0, -50.0}, {0.0, 50.0}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0.0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100.0, 100.0}, {100.0, -100.0}}, 0.0)}} +// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0.0, 50.0}, {100.0, 0.0}, {0.0, -50.0}, {0.0, 50.0}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0.0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100.0, 100.0}, {100.0, -100.0}}, 0.0)}} +// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{-100.0, 100.0}, {100.0, 0.0}, {-100.0, -100.0}}, Smooth.None), Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0.0, 50.0}, {100.0, 0.0}, {0.0, -50.0}, {0.0, 50.0}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0.0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100.0, 100.0}, {100.0, -100.0}}, 0.0)}} +// {-,-,-,-,-,-,-,,{Polygon(true, {0.0, 0.0}, 0.0, {0, 0, 127}, {0, 0, 127}, LinePattern.Solid, FillPattern.Solid, 0.25, {{0.0, 50.0}, {100.0, 0.0}, {0.0, -50.0}, {0.0, 50.0}}, Smooth.None), Rectangle(true, {0.0, 0.0}, 0.0, {0, 0, 255}, {0, 0, 255}, LinePattern.Solid, FillPattern.None, 0.25, BorderPattern.None, {{-100.0, 100.0}, {100.0, -100.0}}, 0.0)}} // endResult diff --git a/testsuite/openmodelica/interactive-API/Makefile b/testsuite/openmodelica/interactive-API/Makefile index 021e2c82587..ed26f6edcd6 100644 --- a/testsuite/openmodelica/interactive-API/Makefile +++ b/testsuite/openmodelica/interactive-API/Makefile @@ -79,6 +79,7 @@ ListExpressions.mos \ ListImport.mos \ ListMultilineComment.mos \ loadClassContentString1.mos \ +loadClassContentString2.mos \ loadFileInteractiveQualified.mos \ matrices.mos \ Modelica.Media.Examples.getComponents.mos \ diff --git a/testsuite/openmodelica/interactive-API/interactive_api_classes.mos b/testsuite/openmodelica/interactive-API/interactive_api_classes.mos index a20741ae91c..eeadc0c8e3f 100644 --- a/testsuite/openmodelica/interactive-API/interactive_api_classes.mos +++ b/testsuite/openmodelica/interactive-API/interactive_api_classes.mos @@ -139,7 +139,7 @@ getClassNames(B, includeConstants=true); // Integer x = 33; // Real z; // annotation( -// Icon(graphics = {Line(color = {127, 127, 127}, arrow = {Arrow.None, Arrow.Open}, points = {{-50, -50}, {50, 50}, {100, 0}, {0, 100}})}), +// Icon(graphics = {Line(points = {{0, 0}, {100, 100}}), Line(color = {127, 127, 127}, arrow = {Arrow.None, Arrow.Open}, points = {{-50, -50}, {50, 50}, {100, 0}, {0, 100}})}), // Diagram(graphics = {Line(color = {127, 127, 127}, arrow = {Arrow.None, Arrow.Open}, points = {{-50, -50}, {50, 50}, {100, 0}, {0, 100}})}), // Documentation(info = \"foo\", revisions = \"1.0\")); // end test; @@ -147,11 +147,11 @@ getClassNames(B, includeConstants=true); // Evaluating: getErrorString() // "" // Evaluating: getIconAnnotation(A.test) -// {-,-,-,-,-,-,-,,{Line(true, {0.0, 0.0}, 0, {{-50, -50}, {50, 50}, {100, 0}, {0, 100}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3, Smooth.None)}} +// {-,-,-,-,-,-,-,,{Line(true, {0.0, 0.0}, 0.0, {{0.0, 0.0}, {100.0, 100.0}}, {0, 0, 0}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.None}, 3.0, Smooth.None), Line(true, {0.0, 0.0}, 0.0, {{-50.0, -50.0}, {50.0, 50.0}, {100.0, 0.0}, {0.0, 100.0}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3.0, Smooth.None)}} // Evaluating: getErrorString() // "" // Evaluating: getDiagramAnnotation(A.test) -// {-,-,-,-,-,-,-,,{Line(true, {0.0, 0.0}, 0, {{-50, -50}, {50, 50}, {100, 0}, {0, 100}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3, Smooth.None)}} +// {-,-,-,-,-,-,-,,{Line(true, {0.0, 0.0}, 0.0, {{-50.0, -50.0}, {50.0, 50.0}, {100.0, 0.0}, {0.0, 100.0}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3.0, Smooth.None)}} // Evaluating: getErrorString() // "" // Evaluating: getDocumentationAnnotation(A.test) @@ -218,7 +218,7 @@ getClassNames(B, includeConstants=true); // Integer x = 33; // Real z; // annotation( -// Icon(graphics = {Line(color = {127, 127, 127}, arrow = {Arrow.None, Arrow.Open}, points = {{-50, -50}, {50, 50}, {100, 0}, {0, 100}})}), +// Icon(graphics = {Line(points = {{0, 0}, {100, 100}}), Line(color = {127, 127, 127}, arrow = {Arrow.None, Arrow.Open}, points = {{-50, -50}, {50, 50}, {100, 0}, {0, 100}})}), // Diagram(graphics = {Line(color = {127, 127, 127}, arrow = {Arrow.None, Arrow.Open}, points = {{-50, -50}, {50, 50}, {100, 0}, {0, 100}})}), // Documentation(info = \"foo\", revisions = \"1.0\")); // end test; @@ -226,11 +226,11 @@ getClassNames(B, includeConstants=true); // Evaluating: getErrorString() // "" // Evaluating: getIconAnnotation(A.test) -// {-10.0,-10.0,10.0,10.0,{Line(true, {{-50, -50}, {50, 50}, {100, 0}, {0, 100}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3.0, false)}} +// {-10.0,-10.0,10.0,10.0,{Line(true, {{0.0, 0.0}, {100.0, 100.0}}, {0, 0, 0}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.None}, 3.0, false), Line(true, {{-50.0, -50.0}, {50.0, 50.0}, {100.0, 0.0}, {0.0, 100.0}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3.0, false)}} // Evaluating: getErrorString() // "" // Evaluating: getDiagramAnnotation(A.test) -// {-100.0,-100.0,100.0,100.0,{Line(true, {{-50, -50}, {50, 50}, {100, 0}, {0, 100}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3.0, false)}} +// {-100.0,-100.0,100.0,100.0,{Line(true, {{-50.0, -50.0}, {50.0, 50.0}, {100.0, 0.0}, {0.0, 100.0}}, {127, 127, 127}, LinePattern.Solid, 0.25, {Arrow.None, Arrow.Open}, 3.0, false)}} // Evaluating: getErrorString() // "" // Evaluating: getDocumentationAnnotation(A.test) diff --git a/testsuite/openmodelica/interactive-API/loadClassContentString2.mos b/testsuite/openmodelica/interactive-API/loadClassContentString2.mos new file mode 100644 index 00000000000..fa50c9737d5 --- /dev/null +++ b/testsuite/openmodelica/interactive-API/loadClassContentString2.mos @@ -0,0 +1,22 @@ +// name: loadClassContentString2 +// keywords: +// status: correct +// cflags: -d=newInst + +loadString(" + model M + annotation(Diagram(graphics = {Rectangle(origin = {1, 2}, extent = {{-1, 1}, {1, -1}})})); + end M; +"); + +loadClassContentString("annotation(Diagram(graphics = {Text(textString = \"text\")}));", M); +list(M); + +// Result: +// true +// true +// "model M +// annotation( +// Diagram(graphics = {Rectangle(origin = {1, 2}, extent = {{-1, 1}, {1, -1}}), Text(textString = \"text\")})); +// end M;" +// endResult