Skip to content

Commit

Permalink
OMEdit fixes 1.22.1 (#11655)
Browse files Browse the repository at this point in the history
* fix OMSimulator PYTHONPATH in OMEdit (#11526)

* update subModule OMSimulator

* Check if we have a parameter modification or a binding (#11599)

Fixes #11595

* Do not use elided text for multiline string with fixed font size (#11610)

Fixes #8383

* Add loadClassContentString API (#11574)

* Rename conflicting elements in loadClassContentString (#11613)

Fixes #11596

* Added a tab widget at the bottom of MainWindow (#11627)

* Added a tab widget at the bottom of MainWindow

The tab widget mimics the Messages Browser. It is a shorter version of it.
Only shown when Messages Browser is hidden.
Messages Browser can now only be docked at the bottom.

Scroll to bottom when a new simulation output is added.

Fixes #9889

* Set the index to 0

* Fix the context menu for shapes (#11634)

This is a regression introduced in afb86a3

* Use the `loadClassContentString` API for cut, copy and paste (#11598)

Instead of using the OMEdit internal structures for pasting elements use `loadClassContentString` to merge.
Generate the Modelica code from the selected elements and then merge the code using `loadClassContentString`.
Put the data in the form of string and JSON on the clipboard. Use it when paste is called.

* Show the typed dimensions of array parameter in the dialog (#11629)

* Improve loadClassContentString (#11644)

- Traverse equations/algorithms manually when renaming instead of using
  the AbsynUtil traversal functions, since the traversal functions only
  traverses expressions and not crefs in e.g. connect equations.
- Rewrite the conflict handling to avoid generating new names that
  conflicts with the elements being added.

* Do not call show documentation when editing documentation

Fixes #11638
Calling show documentation while editing causes a recursion

* Do not push intermediate commands to stack

* Use QScrollArea for welcome page buttons

Fixes #10235

---------

Co-authored-by: arun3688 <rain100falls@gmail.com>
Co-authored-by: Per Östlund <per.ostlund@liu.se>
  • Loading branch information
3 people committed Nov 28, 2023
1 parent 4f4bc9c commit 239e4da
Show file tree
Hide file tree
Showing 36 changed files with 1,882 additions and 269 deletions.
167 changes: 125 additions & 42 deletions OMCompiler/Compiler/FrontEnd/AbsynUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ algorithm
end match;
end traverseClassPartBidir;

protected function traverseEquationItemListBidir<Arg>
public function traverseEquationItemListBidir<Arg>
input list<Absyn.EquationItem> inEquationItems;
input FuncType enterFunc;
input FuncType exitFunc;
Expand All @@ -626,7 +626,7 @@ algorithm
(outEquationItems, outArg) := List.map2FoldCheckReferenceEq(inEquationItems, traverseEquationItemBidir, enterFunc, exitFunc, inArg);
end traverseEquationItemListBidir;

protected function traverseAlgorithmItemListBidir<Arg>
public function traverseAlgorithmItemListBidir<Arg>
input list<Absyn.AlgorithmItem> inAlgs;
input FuncType enterFunc;
input FuncType exitFunc;
Expand Down Expand Up @@ -931,14 +931,12 @@ algorithm
annotation(__OpenModelica_EarlyInline = true);
end makeQualifiedPathFromStrings;

public function className "returns the class name of a Absyn.Class as a Absyn.Path"
public function className
"Returns the class name of a Absyn.Class."
input Absyn.Class cl;
output Absyn.Path name;
protected
String id;
output String name;
algorithm
Absyn.CLASS(name = id) := cl;
name := Absyn.IDENT(id);
Absyn.CLASS(name = name) := cl;
end className;

public function isClassNamed
Expand Down Expand Up @@ -978,6 +976,37 @@ algorithm
end match;
end elementSpecName;

public function elementItemNames
input Absyn.ElementItem item;
output list<String> names;
algorithm
names := match item
case Absyn.ElementItem.ELEMENTITEM() then elementNames(item.element);
else {};
end match;
end elementItemNames;

public function elementNames
input Absyn.Element element;
output list<String> names;
algorithm
names := match element
case Absyn.Element.ELEMENT() then elementSpecNames(element.specification);
else {};
end match;
end elementNames;

public function elementSpecNames
input Absyn.ElementSpec spec;
output list<String> names;
algorithm
names := match spec
case Absyn.ElementSpec.CLASSDEF() then {className(spec.class_)};
case Absyn.ElementSpec.COMPONENTS() then list(componentName(c) for c in spec.components);
else {};
end match;
end elementSpecNames;

public function isClassdef
input Absyn.Element inElement;
output Boolean b;
Expand Down Expand Up @@ -4339,7 +4368,7 @@ algorithm
end match;
end opIsElementWise;

protected function dummyTraverseExp<Arg>
public function dummyTraverseExp<Arg>
input Absyn.Exp inExp;
input Arg inArg;
output Absyn.Exp outExp;
Expand Down Expand Up @@ -4376,25 +4405,41 @@ algorithm
end match;
end getClassPartsInClass;

public function getElementItemsInElement
"Returns the public and protected elements in a class."
input Absyn.Element element;
output list<Absyn.ElementItem> outElements;
protected
Absyn.Class cls;
algorithm
outElements := match element
case Absyn.Element.ELEMENT(specification = Absyn.ElementSpec.CLASSDEF(class_ = cls))
then getElementItemsInClass(cls);
else {};
end match;
end getElementItemsInElement;

public function getElementItemsInClass
"Returns the public and protected elements in a class."
input Absyn.Class inClass;
output list<Absyn.ElementItem> outElements = getElementItemsInClassDef(inClass.body);
end getElementItemsInClass;

public function getElementItemsInClassDef
"Returns the public and protected elements in a class definition."
input Absyn.ClassDef classDef;
output list<Absyn.ElementItem> outElements;
algorithm
outElements := match(inClass)
local
list<Absyn.ClassPart> parts;

case Absyn.CLASS(body = Absyn.PARTS(classParts = parts))
then List.mapFlat(parts, getElementItemsInClassPart);
outElements := match classDef
case Absyn.ClassDef.PARTS()
then List.mapFlat(classDef.classParts, getElementItemsInClassPart);

case Absyn.CLASS(body = Absyn.CLASS_EXTENDS(parts = parts))
then List.mapFlat(parts, getElementItemsInClassPart);
case Absyn.ClassDef.CLASS_EXTENDS()
then List.mapFlat(classDef.parts, getElementItemsInClassPart);

else {};

end match;
end getElementItemsInClass;
end getElementItemsInClassDef;

public function getElementItemsInClassPart
"Returns the public and protected elements in a class part."
Expand Down Expand Up @@ -5270,7 +5315,7 @@ algorithm
case ((class_ :: _),_,_,_,_)
equation
print("-traverse_classes2 failed on class:");
print(AbsynUtil.pathString(AbsynUtil.className(class_)));
print(AbsynUtil.className(class_));
print("\n");
then
fail();
Expand Down Expand Up @@ -5634,35 +5679,40 @@ algorithm
end isUniontype;

public function traverseClassElements<ArgT>
input Absyn.Class inClass;
input FuncType inFunc;
input ArgT inArg;
output Absyn.Class outClass = inClass;
output ArgT outArg;
input output Absyn.Class cls;
input FuncType func;
input output ArgT arg;

partial function FuncType
input Absyn.Element inElement;
input ArgT inArg;
output Absyn.Element outElement;
output ArgT outArg;
output Boolean outContinue;
input output Absyn.Element element;
input output ArgT arg;
output Boolean outContinue;
end FuncType;
protected
Absyn.ClassDef body;
algorithm
outClass := match(outClass)
local
Absyn.ClassDef body;
(body, arg) := traverseClassDefElements(cls.body, func, arg);

case Absyn.CLASS()
algorithm
(body, outArg) := traverseClassDef(outClass.body,
function traverseClassPartElements(inFunc = inFunc), inArg);
if not referenceEq(body, outClass.body) then outClass.body := body; end if;
then
outClass;

end match;
if not referenceEq(body, cls.body) then
cls.body := body;
end if;
end traverseClassElements;

public function traverseClassDefElements<ArgT>
input output Absyn.ClassDef classDef;
input FuncType func;
input output ArgT arg;

partial function FuncType
input output Absyn.Element element;
input output ArgT arg;
output Boolean outContinue;
end FuncType;
algorithm
(classDef, arg) := traverseClassDef(classDef,
function traverseClassPartElements(inFunc = func), arg);
end traverseClassDefElements;

protected function traverseClassPartElements<ArgT>
input Absyn.ClassPart inClassPart;
input FuncType inFunc;
Expand Down Expand Up @@ -6364,5 +6414,38 @@ algorithm
end if;
end purityEqual;

function isElementSection
input Absyn.ClassPart part;
output Boolean res;
algorithm
res := match part
case Absyn.ClassPart.PUBLIC() then true;
case Absyn.ClassPart.PROTECTED() then true;
else false;
end match;
end isElementSection;

function isEquationSection
input Absyn.ClassPart part;
output Boolean res;
algorithm
res := match part
case Absyn.ClassPart.EQUATIONS() then true;
case Absyn.ClassPart.INITIALEQUATIONS() then true;
else false;
end match;
end isEquationSection;

function isAlgorithmSection
input Absyn.ClassPart part;
output Boolean res;
algorithm
res := match part
case Absyn.ClassPart.ALGORITHMS() then true;
case Absyn.ClassPart.INITIALALGORITHMS() then true;
else false;
end match;
end isAlgorithmSection;

annotation(__OpenModelica_Interface="frontend");
end AbsynUtil;
37 changes: 37 additions & 0 deletions OMCompiler/Compiler/FrontEnd/ModelicaBuiltin.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,43 @@ external "builtin";
annotation(preferredView="text");
end loadString;

function loadClassContentString
"Loads class elements from a string and inserts them into the given loaded class."
input String data;
input TypeName className;
output Boolean success;
external "builtin";
annotation(preferredView="test",Documentation(info="<html>
<p>Loads class content from a string and inserts it into the given loaded class.
The existing class must be a long class definition, either normal or class
extends. The content is merged according to the following rules:</p>
<p>
<ul>
<li>public/protected sections: Merged with the last public/protected section if the protection is the same.</li>
<li>equation sections: Merged with the last equation section.</li>
<li>external declaration: The new declaration overwrites the old.</li>
<li>annotations: The new annotation is merged with the old.
</ul>
</p>
<p>
Any section not merged is added after the last section of the same type, or
where they would normally be placed if no such section exists (i.e.
public/protected first, then equations, etc). </p>
<p>
Example:
<blockquote>
<pre>
loadClassContentString(\"
Real y;
equation
y = x;
\", P.M);
</pre>
</blockquote>
</p>
</html>"));
end loadClassContentString;

function parseString
input String data;
input String filename = "<interactive>";
Expand Down
4 changes: 2 additions & 2 deletions OMCompiler/Compiler/Main/Main.mo
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,14 @@ algorithm

case(Absyn.PROGRAM(classes=cls,within_=Absyn.WITHIN(scope)))
equation
names = List.map(cls,AbsynUtil.className);
names = list(Absyn.Path.IDENT(AbsynUtil.className(c)) for c in cls);
names = List.map1(names,AbsynUtil.joinPaths,scope);
res = "{" + stringDelimitList(list(AbsynUtil.pathString(n) for n in names),",") + "}\n";
then res;

case(Absyn.PROGRAM(classes=cls,within_=Absyn.TOP()))
equation
names = List.map(cls,AbsynUtil.className);
names = list(Absyn.Path.IDENT(AbsynUtil.className(c)) for c in cls);
res = "{" + stringDelimitList(list(AbsynUtil.pathString(n) for n in names),",") + "}\n";
then res;

Expand Down
37 changes: 37 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFModelicaBuiltin.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1451,6 +1451,43 @@ external "builtin";
annotation(preferredView="text");
end loadString;

function loadClassContentString
"Loads class elements from a string and inserts them into the given loaded class."
input String data;
input TypeName className;
output Boolean success;
external "builtin";
annotation(preferredView="test",Documentation(info="<html>
<p>Loads class content from a string and inserts it into the given loaded class.
The existing class must be a long class definition, either normal or class
extends. The content is merged according to the following rules:</p>
<p>
<ul>
<li>public/protected sections: Merged with the last public/protected section if the protection is the same.</li>
<li>equation sections: Merged with the last equation section if it's the same type of equation section (normal/initial).</li>
<li>external declaration: The new declaration overwrites the old.</li>
<li>annotations: The new annotation is merged with the old.
</ul>
</p>
<p>
Any section not merged is added after the last section of the same type, or
where they would normally be placed if no such section exists (i.e.
public/protected first, then equations, etc). </p>
<p>
Example:
<blockquote>
<pre>
loadClassContentString(\"
Real y;
equation
y = x;
\", P.M);
</pre>
</blockquote>
</p>
</html>"));
end loadClassContentString;

function parseString
input String data;
input String filename = "<interactive>";
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/Script/CevalScript.mo
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ algorithm
case ("parseString",{Values.STRING(str1),Values.STRING(str2)})
algorithm
Absyn.PROGRAM(classes=classes,within_=within_) := Parser.parsestring(str1,str2);
paths := List.map(classes,AbsynUtil.className);
paths := list(Absyn.Path.IDENT(AbsynUtil.className(c)) for c in classes);
paths := List.map1r(paths,AbsynUtil.joinWithinPath,within_);
vals := List.map(paths,ValuesUtil.makeCodeTypeName);
then
Expand Down
8 changes: 8 additions & 0 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Original file line number Diff line number Diff line change
Expand Up @@ -3145,6 +3145,14 @@ algorithm
then
Values.BOOL(b);
case ("loadClassContentString",
{Values.STRING(str), Values.CODE(Absyn.C_TYPENAME(classpath))})
algorithm
(p, b) := InteractiveUtil.loadClassContentString(str, classpath, SymbolTable.getAbsyn());
SymbolTable.setAbsyn(p);
then
Values.BOOL(b);
end matchcontinue;
end cevalInteractiveFunctions4;
Expand Down

0 comments on commit 239e4da

Please sign in to comment.