Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 0.0% 0 / 0 / 68
Functions: -% 0 / 1 / 1
Branches: 0.0% 0 / 0 / 2

OMCompiler/Compiler/FrontEnd/DumpGraphviz.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package DumpGraphviz
37 " file: DumpGraphviz.mo
38 package: DumpGraphviz
39 description: Dumps the AST to a graph representation that can be read by the graphviz tool.
40
41
42 "
43
44 public import Absyn;
45 public import AbsynUtil;
46 public import Graphviz;
47 protected import Dump;
48
49 public function dump "Dumps a Program to a Graphviz graph."
50 input Absyn.Program p;
51 protected
52 Graphviz.Node r;
53 algorithm
54 ✗ r := buildGraphviz(p);
55 ✗ Graphviz.dump(r);
56 end dump;
57
58 protected function buildGraphviz "Build the graphviz graph for a Program."
59 input Absyn.Program inProgram;
60 output Graphviz.Node outNode;
61 algorithm
62 outNode := match inProgram
63 local
64 list<Graphviz.Node> nl;
65 list<Absyn.Class> cs;
66
67 case Absyn.PROGRAM(classes = cs)
68 algorithm
69 ✗ nl := printClasses(cs);
70 ✗ then
71 Graphviz.NODE("ROOT",{},nl);
72 end match;
73 end buildGraphviz;
74
75 protected function printClasses "Creates Nodes from a Class list."
76 input list<Absyn.Class> inAbsynClassLst;
77 output list<Graphviz.Node> outNodeLst;
78 algorithm
79 outNodeLst := match inAbsynClassLst
80 local
81 Graphviz.Node node;
82 list<Graphviz.Node> nl;
83 Absyn.Class c;
84 list<Absyn.Class> cs;
85
86 case {} then {};
87
88 case c :: cs
89 algorithm
90 ✗ node := printClass(c);
91 ✗ nl := printClasses(cs);
92 then
93 (node :: nl);
94 end match;
95 end printClasses;
96
97 protected function printClass "Creates a Node for a Class."
98 input Absyn.Class inClass;
99 output Graphviz.Node outNode;
100 algorithm
101 outNode := match inClass
102 local
103 String rs;
104 list<Graphviz.Node> nl;
105 Absyn.Restriction r;
106 list<Absyn.ClassPart> parts;
107
108 case Absyn.CLASS(restriction = r,body = Absyn.PARTS(classParts = parts))
109 algorithm
110 ✗ rs := AbsynUtil.restrString(r);
111 ✗ nl := printParts(parts);
112 ✗ then
113 Graphviz.NODE(rs,{},nl);
114 end match;
115 end printClass;
116
117 protected function printParts "Creates a Node list from a ClassPart list."
118 input list<Absyn.ClassPart> inAbsynClassPartLst;
119 output list<Graphviz.Node> outNodeLst;
120 algorithm
121 outNodeLst := match inAbsynClassPartLst
122 local
123 Graphviz.Node node;
124 list<Graphviz.Node> nl;
125 Absyn.ClassPart c;
126 list<Absyn.ClassPart> cs;
127
128 case {} then {};
129
130 case c :: cs
131 algorithm
132 ✗ node := printClassPart(c);
133 ✗ nl := printParts(cs);
134 then
135 (node :: nl);
136 end match;
137 end printParts;
138
139 protected function printClassPart "Creates a Node from A ClassPart."
140 input Absyn.ClassPart inClassPart;
141 output Graphviz.Node outNode;
142 algorithm
143 outNode := matchcontinue inClassPart
144 local
145 list<Graphviz.Node> nl;
146 list<Absyn.ElementItem> el;
147 list<Absyn.EquationItem> eqs;
148 list<Absyn.AlgorithmItem> als;
149
150 case Absyn.PUBLIC(contents = el)
151 algorithm
152 ✗ nl := printElementitems(el);
153 ✗ then
154 Graphviz.NODE("PUBLIC",{},nl);
155
156 case Absyn.PROTECTED(contents = el)
157 algorithm
158 ✗ nl := printElementitems(el);
159 ✗ then
160 Graphviz.NODE("PROTECTED",{},nl);
161
162 case Absyn.EQUATIONS(contents = eqs)
163 algorithm
164 ✗ nl := printEquations(eqs);
165 ✗ then
166 Graphviz.NODE("EQUATIONS",{},nl);
167
168 case Absyn.ALGORITHMS(contents = als)
169 algorithm
170 ✗ nl := printAlgorithms(als);
171 ✗ then
172 Graphviz.NODE("ALGORITHMS",{},nl);
173
174 else Graphviz.NODE(" DumpGraphViz.printClassPart PART_ERROR",{},{});
175 end matchcontinue;
176 end printClassPart;
177
178 protected function printElementitems "Creates a Node list from ElementItem list."
179 input list<Absyn.ElementItem> inAbsynElementItemLst;
180 output list<Graphviz.Node> outNodeLst;
181 algorithm
182 outNodeLst := match inAbsynElementItemLst
183 local
184 list<Graphviz.Node> nl;
185 list<Absyn.ElementItem> el;
186 Graphviz.Node node;
187 Absyn.Element e;
188
189 case {} then {};
190
191 case Absyn.ELEMENTITEM(element = e) :: el
192 algorithm
193 ✗ node := printElement(e);
194 ✗ nl := printElementitems(el);
195 then
196 (node :: nl);
197 end match;
198 end printElementitems;
199
200 protected function makeBoolAttr "Create an Attribute from a bool value and a description string."
201 input String str;
202 input Boolean flag;
203 output Graphviz.Attribute outAttribute;
204 algorithm
205 ✗ outAttribute := Graphviz.ATTR(str, boolString(flag));
206 end makeBoolAttr;
207
208 protected function makeLeaf "Create a leaf Node from a string an a list of attributes."
209 input String str;
210 input list<Graphviz.Attribute> al;
211 output Graphviz.Node outNode;
212 algorithm
213 ✗ outNode := Graphviz.NODE(str,al,{});
214 end makeLeaf;
215
216 protected function printElement "Create a Node from an Element."
217 input Absyn.Element inElement;
218 output Graphviz.Node outNode;
219 algorithm
220 outNode := match inElement
221 local
222 Graphviz.Attribute fa;
223 Graphviz.Node elsp;
224 Boolean finalPrefix;
225 Absyn.ElementSpec spec;
226
227 case Absyn.ELEMENT(finalPrefix = finalPrefix,specification = spec)
228 algorithm
229 ✗ fa := makeBoolAttr("final", finalPrefix);
230 ✗ elsp := printElementspec(spec);
231 ✗ then
232 Graphviz.NODE("ELEMENT",{fa},{elsp});
233 end match;
234 end printElement;
235
236 protected function printPath "Create a Node from a Path."
237 input Absyn.Path p;
238 output Graphviz.Node pn;
239 protected
240 String s;
241 algorithm
242 ✗ s := AbsynUtil.pathString(p);
243 ✗ pn := makeLeaf(s, {});
244 end printPath;
245
246 protected function printElementspec "Create a Node from an ElementSpec"
247 input Absyn.ElementSpec inElementSpec;
248 output Graphviz.Node outNode;
249 algorithm
250 outNode := matchcontinue inElementSpec
251 local
252 Graphviz.Node en,pn;
253 Graphviz.Attribute ra;
254 Boolean repl;
255 Absyn.Class cl;
256 Absyn.Path p;
257 list<Graphviz.Node> cns;
258 Absyn.TypeSpec tspec;
259 list<Absyn.ComponentItem> cs;
260 String s;
261
262 case Absyn.CLASSDEF(replaceable_ = repl,class_ = cl)
263 algorithm
264 ✗ printClass(cl);
265 ✗ ra := makeBoolAttr("replaceable", repl);
266 ✗ then
267 Graphviz.NODE("CLASSDEF",{ra},{});
268
269 case Absyn.EXTENDS(path = p)
270 algorithm
271 ✗ en := printPath(p);
272 ✗ then
273 Graphviz.NODE("EXTENDS",{},{en});
274
275 case Absyn.COMPONENTS(typeSpec = tspec,components = cs)
276 algorithm
277 ✗ s := Dump.unparseTypeSpec(tspec);
278 ✗ pn := makeLeaf(s, {});
279 ✗ cns := printComponents(cs);
280 ✗ then
281 Graphviz.NODE("COMPONENTS",{},(pn :: cns));
282
283 else Graphviz.NODE(" DumpGraphviz.printElementspec ELSPEC_ERROR",{},{});
284 end matchcontinue;
285 end printElementspec;
286
287 protected function printComponents "Create a Node list from a ComponentItem list."
288 input list<Absyn.ComponentItem> inAbsynComponentItemLst;
289 output list<Graphviz.Node> outNodeLst;
290 algorithm
291 outNodeLst := match inAbsynComponentItemLst
292 local
293 Graphviz.Node n;
294 list<Graphviz.Node> nl;
295 Absyn.ComponentItem c;
296 list<Absyn.ComponentItem> cs;
297
298 case {} then {};
299
300 case c :: cs
301 algorithm
302 ✗ n := printComponentitem(c);
303 ✗ nl := printComponents(cs);
304 then
305 (n :: nl);
306 end match;
307 end printComponents;
308
309 protected function printComponentitem "Create a Node from a ComponentItem."
310 input Absyn.ComponentItem inComponentItem;
311 output Graphviz.Node outNode;
312 algorithm
313 outNode := match inComponentItem
314 local
315 Graphviz.Node nn;
316 String n;
317
318 case Absyn.COMPONENTITEM(component = Absyn.COMPONENT(name = n))
319 algorithm
320 ✗ nn := Graphviz.NODE(n,{},{});
321 ✗ then
322 Graphviz.LNODE("COMPONENT",{n},{},{nn});
323 end match;
324 end printComponentitem;
325
326 protected function printEquations "Create a Node list from an EquationItem list."
327 input list<Absyn.EquationItem> inAbsynEquationItemLst;
328 output list<Graphviz.Node> outNodeLst;
329 algorithm
330 outNodeLst := match inAbsynEquationItemLst
331 local
332 Graphviz.Node node;
333 list<Graphviz.Node> nl;
334 Absyn.Equation eq;
335 list<Absyn.EquationItem> el;
336
337 case {} then {};
338
339 case Absyn.EQUATIONITEM(equation_ = eq) :: el
340 algorithm
341 ✗ node := printEquation(eq);
342 ✗ nl := printEquations(el);
343 then
344 (node :: nl);
345 end match;
346 end printEquations;
347
348 protected function printEquation
349 " Create a Node from an Equation."
350 input Absyn.Equation inEquation;
351 output Graphviz.Node outNode;
352 algorithm
353 outNode := matchcontinue inEquation
354 local
355 String s1,s2,s3,s,s_1,s_2,es;
356 Absyn.Exp e1,e2;
357 Absyn.ComponentRef c1,c2;
358 list<Graphviz.Node> eqn;
359 list<Absyn.EquationItem> eqs;
360 Absyn.ForIterators iterators;
361
362 case Absyn.EQ_EQUALS(leftSide = e1,rightSide = e2)
363 algorithm
364 ✗ s1 := Dump.printExpStr(e1);
365 ✗ s2 := Dump.printExpStr(e2);
366 ✗ s := stringAppend(s1, " = ");
367 ✗ s_1 := stringAppend(s, s2);
368 ✗ then
369 Graphviz.LNODE("EQ_EQUALS",{s_1},{},{});
370
371 case Absyn.EQ_PDE(leftSide = e1,rightSide = e2,domain = c1)
372 algorithm
373 ✗ s1 := Dump.printExpStr(e1);
374 ✗ s2 := Dump.printExpStr(e2);
375 ✗ s3 := Dump.printComponentRefStr(c1);
376 ✗ s := stringAppend(s1, " = ");
377 ✗ s_1 := stringAppend(s, s2);
378 ✗ s_1 := stringAppend(s_1, " indomain ");
379 ✗ s_1 := stringAppend(s_1, s3);
380 ✗ then
381 Graphviz.LNODE("EQ_PDE",{s_1},{},{});
382
383
384 case Absyn.EQ_CONNECT(connector1 = c1,connector2 = c2)
385 algorithm
386 ✗ s1 := Dump.printComponentRefStr(c1);
387 ✗ s2 := Dump.printComponentRefStr(c2);
388 ✗ s := stringAppend("connect(", s1);
389 ✗ s_1 := stringAppend(s, s2);
390 ✗ s_2 := stringAppend(s_1, ")");
391 ✗ then
392 Graphviz.LNODE("EQ_CONNECT",{s_2},{},{});
393
394 case Absyn.EQ_FOR(iterators=iterators,forEquations = eqs)
395 algorithm
396 ✗ eqn := printEquations(eqs);
397 ✗ es := Dump.printIteratorsStr(iterators);
398 ✗ then
399 Graphviz.LNODE("EQ_FOR",{es},{},eqn);
400
401 else Graphviz.NODE("EQ_ERROR",{},{});
402
403 end matchcontinue;
404 end printEquation;
405
406 protected function printAlgorithms "Create a Node list from an AlgorithmItem list."
407 input list<Absyn.AlgorithmItem> inAbsynAlgorithmItemLst;
408 output list<Graphviz.Node> outNodeLst;
409 algorithm
410 outNodeLst := match inAbsynAlgorithmItemLst
411 local
412 Graphviz.Node node;
413 list<Graphviz.Node> nl;
414 Absyn.AlgorithmItem e;
415 list<Absyn.AlgorithmItem> el;
416
417 case {} then {};
418
419 case e :: el
420 algorithm
421 ✗ node := printAlgorithmitem(e);
422 ✗ nl := printAlgorithms(el);
423 then
424 (node :: nl);
425 end match;
426 end printAlgorithms;
427
428 protected function printAlgorithmitem "Create a Node from an AlgorithmItem."
429 input Absyn.AlgorithmItem inAlgorithmItem;
430 output Graphviz.Node outNode;
431 algorithm
432 outNode := match inAlgorithmItem
433 local
434 Graphviz.Node node;
435 Absyn.Algorithm alg;
436
437 case Absyn.ALGORITHMITEM(algorithm_ = alg)
438 algorithm
439 ✗ node := printAlgorithm(alg);
440 then
441 node;
442 else Graphviz.NODE("ALG_ERROR",{},{});
443 end match;
444 end printAlgorithmitem;
445
446 protected function printAlgorithm "Create a Node from an Algorithm."
447 input Absyn.Algorithm inAlgorithm;
448 output Graphviz.Node outNode;
449 algorithm
450 outNode := match inAlgorithm
451 local
452
453 case Absyn.ALG_ASSIGN() then Graphviz.NODE("ALG_ASSIGN",{},{});
454 else Graphviz.NODE(" DumpGraphviz.printAlgorithm ALG_ERROR",{},{});
455 end match;
456 end printAlgorithm;
457
458 protected function variabilitySymbol "Return Variability as a string."
459 input Absyn.Variability inVariability;
460 output String outString;
461 algorithm
462 outString := match inVariability
463 case Absyn.VAR() then "";
464 case Absyn.DISCRETE() then "DISCRETE";
465 case Absyn.PARAM() then "PARAM";
466 case Absyn.CONST() then "CONST";
467 end match;
468 end variabilitySymbol;
469
470 protected function directionSymbol "Return direction as a string."
471 input Absyn.Direction inDirection;
472 output String outString;
473 algorithm
474 outString := match inDirection
475 case Absyn.BIDIR() then "";
476 case Absyn.INPUT() then "INPUT";
477 case Absyn.OUTPUT() then "OUTPUT";
478 end match;
479 end directionSymbol;
480
481 annotation(__OpenModelica_Interface="dump_extra");
482 end DumpGraphviz;
483
484