Skip to content

Commit

Permalink
Improve getClassComment API (#10215)
Browse files Browse the repository at this point in the history
- Return the comment after the constrainedby clause on a replaceable
  class if available.

Fixes #10030
  • Loading branch information
perost committed Feb 15, 2023
1 parent 2569af6 commit 323fdd2
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 7 deletions.
13 changes: 13 additions & 0 deletions OMCompiler/Compiler/FrontEnd/AbsynUtil.mo
Expand Up @@ -4296,6 +4296,19 @@ algorithm
outElts := listReverseInPlace(outElts);
end getDefineUnitsInElements;

public function getClassPartsInClass
input Absyn.Class cls;
output list<Absyn.ClassPart> parts;
protected
Absyn.ClassDef cdef = cls.body;
algorithm
parts := match cdef
case Absyn.ClassDef.PARTS() then cdef.classParts;
case Absyn.ClassDef.CLASS_EXTENDS() then cdef.parts;
else {};
end match;
end getClassPartsInClass;

public function getElementItemsInClass
"Returns the public and protected elements in a class."
input Absyn.Class inClass;
Expand Down
37 changes: 30 additions & 7 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Expand Up @@ -662,7 +662,7 @@ algorithm
FCore.Graph env;
Absyn.Program p,pnew;
Absyn.Class absynClass;
Absyn.ClassDef cdef;
Absyn.Element elem;
Absyn.Exp aexp;
DAE.DAElist dae;
BackendDAE.BackendDAE daelow;
Expand Down Expand Up @@ -756,8 +756,8 @@ algorithm

case ("getClassComment",{Values.CODE(Absyn.C_TYPENAME(path))})
equation
Absyn.CLASS(body = cdef) = InteractiveUtil.getPathedClassInProgram(path, SymbolTable.getAbsyn());
str = System.unescapedString(getClassComment(cdef));
elem = InteractiveUtil.getPathedElementInProgram(path, SymbolTable.getAbsyn());
str = System.unescapedString(getClassElementComment(elem));
then
Values.STRING(str);

Expand Down Expand Up @@ -5550,7 +5550,6 @@ algorithm
String file_dir,init_filename,method_str,filenameprefix,exeFile,s3,simflags;
Absyn.Path classname;
Absyn.Program p;
Absyn.Class cdef;
Real edit,build,globalEdit,globalBuild,timeCompile;
FCore.Graph env;
SimCode.SimulationSettings simSettings;
Expand Down Expand Up @@ -7561,7 +7560,7 @@ protected
algorithm
Absyn.CLASS(name,partialPrefix,finalPrefix,encapsulatedPrefix,restr,cdef,_,_,SOURCEINFO(file,isReadOnly,sl,sc,el,ec,_)) := InteractiveUtil.getPathedClassInProgram(path, p);
res := Dump.unparseRestrictionStr(restr);
cmt := getClassComment(cdef);
cmt := getClassDefComment(cdef);
file := Testsuite.friendly(file);
if AbsynUtil.pathIsIdent(AbsynUtil.makeNotFullyQualified(path)) then
isProtectedClass := false;
Expand Down Expand Up @@ -7613,7 +7612,31 @@ algorithm
end match;
end getClassDimensions;

function getClassComment "Returns the class comment of a Absyn.ClassDef"
function getClassElementComment
"Returns the comment on a class element."
input Absyn.Element element;
output String commentStr;
protected
Absyn.Class cls;
algorithm
commentStr := match element
case Absyn.Element.ELEMENT(specification = Absyn.ElementSpec.CLASSDEF(class_ = cls))
algorithm
// The comment can go either before and/or after the constrainedby clause,
// the one after has higher priority.
commentStr := InteractiveUtil.getConstrainingClassComment(element.constrainClass);

if stringEmpty(commentStr) then
commentStr := getClassDefComment(cls.body);
end if;
then
commentStr;

else "";
end match;
end getClassElementComment;

function getClassDefComment "Returns the class comment of a Absyn.ClassDef"
input Absyn.ClassDef inClassDef;
output String outString;
algorithm
Expand All @@ -7634,7 +7657,7 @@ algorithm
case (Absyn.CLASS_EXTENDS(comment = SOME(str))) then str;
else "";
end match;
end getClassComment;
end getClassDefComment;

protected function getAnnotationInEquation
"This function takes an `EquationItem\' and returns a comma separated
Expand Down
70 changes: 70 additions & 0 deletions OMCompiler/Compiler/Script/InteractiveUtil.mo
Expand Up @@ -4509,5 +4509,75 @@ algorithm
outElements := List.deleteMemberOnTrue(name, inElements, classElementItemIsNamed);
end removeClassInElementitemlist;

public function getPathedElementInProgram
"Looks up a class element in the program using the given path."
input Absyn.Path path;
input Absyn.Program program;
output Absyn.Element element;
protected
Absyn.Class cls;
algorithm
cls := getClassInProgram(AbsynUtil.pathFirstIdent(path), program);

if AbsynUtil.pathIsIdent(path) then
// Since the program only stores classes instead of elements we have to
// create a dummy element if we find a top-level class.
element := Absyn.Element.ELEMENT(false, NONE(), Absyn.InnerOuter.NOT_INNER_OUTER(),
Absyn.ElementSpec.CLASSDEF(false, cls), cls.info, NONE());
else
SOME(element) := getPathedElementInClass(AbsynUtil.pathRest(path), cls);
end if;
end getPathedElementInProgram;

protected function getPathedElementInClass
input Absyn.Path path;
input Absyn.Class cls;
output Option<Absyn.Element> element = NONE();
algorithm
for part in AbsynUtil.getClassPartsInClass(cls) loop
element := getPathedElementInClassPart(path, part);

if isSome(element) then
break;
end if;
end for;
end getPathedElementInClass;

protected function getPathedElementInClassPart
input Absyn.Path path;
input Absyn.ClassPart part;
output Option<Absyn.Element> element = NONE();
protected
Absyn.Element e;
algorithm
for item in AbsynUtil.getElementItemsInClassPart(part) loop
if AbsynUtil.isElementItemClassNamed(AbsynUtil.pathFirstIdent(path), item) then
Absyn.ElementItem.ELEMENTITEM(element = e) := item;

if AbsynUtil.pathIsIdent(path) then
element := SOME(e);
else
element := getPathedElementInElement(AbsynUtil.pathRest(path), e);
end if;

break;
end if;
end for;
end getPathedElementInClassPart;

protected function getPathedElementInElement
input Absyn.Path path;
input Absyn.Element element;
output Option<Absyn.Element> outElement;
protected
Absyn.Class cls;
algorithm
outElement := match element
case Absyn.Element.ELEMENT(specification = Absyn.ElementSpec.CLASSDEF(class_ = cls))
then getPathedElementInClass(path, cls);
else NONE();
end match;
end getPathedElementInElement;

annotation(__OpenModelica_Interface="backend");
end InteractiveUtil;
1 change: 1 addition & 0 deletions testsuite/openmodelica/interactive-API/Makefile
Expand Up @@ -34,6 +34,7 @@ ForStatement5fail.mos \
ForStatement6.mos \
ForStatement7.mos \
ForStatement8.mos \
getClassComment.mos \
getClassNames.mos \
getCommandLineOptions.mos \
GetComponents.mos \
Expand Down
35 changes: 35 additions & 0 deletions testsuite/openmodelica/interactive-API/getClassComment.mos
@@ -0,0 +1,35 @@
// name: getClassComment
// keywords:
// status: correct
// cflags: -d=newInst

loadString("
package P \"P comment\"
replaceable model M1 = M constrainedby M \"After constraint\";
replaceable model M2 = M \"Before constraint\" constrainedby M;
replaceable model M3 = M \"Before constraint\" constrainedby M \"After constraint\";

model M \"M comment\"
end M;

model extends ME \"ME comment\"
end ME;
end P;
");

getClassComment(P);
getClassComment(P.M1);
getClassComment(P.M2);
getClassComment(P.M3);
getClassComment(P.M);
getClassComment(P.ME);

// Result:
// true
// "P comment"
// "After constraint"
// "Before constraint"
// "After constraint"
// "M comment"
// "ME comment"
// endResult

0 comments on commit 323fdd2

Please sign in to comment.