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 / 73
Functions: -% 0 / 1 / 1
Branches: 0.0% 0 / 0 / 26

OMCompiler/Compiler/FFrontEnd/FGraphDump.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 FGraphDump
37 " file: FGraphDump.mo
38 package: FGraphDump
39 description: A graph for instantiation
40
41
42 This module builds a graph out of SCode
43 "
44
45 public
46 import SCode;
47 import DAE;
48 import FCore;
49 import MutableWeak;
50 import FCore.RefTree;
51 import FNode;
52 import FGraph;
53 import GraphML;
54
55 public
56 type Name = FCore.Name;
57 type Id = FCore.Id;
58 type Seq = FCore.Seq;
59 type Next = FCore.Next;
60 type Node = FCore.Node;
61 type Data = FCore.Data;
62 type Kind = FCore.Kind;
63 type Ref = FCore.Ref;
64 type Refs = FCore.Refs;
65 type Children = FCore.Children;
66 type Parents = FCore.Parents;
67 type ImportTable = FCore.ImportTable;
68 type Extra = FCore.Extra;
69 type Visited = FCore.Visited;
70 type Import = FCore.Import;
71 type Graph = FCore.Graph;
72
73 type Type = DAE.Type;
74 type Types = list<DAE.Type>;
75
76 protected
77 import Flags;
78 import Dump;
79 import Absyn;
80 import SCodeUtil;
81 import Util;
82
83 public function dumpGraph
84 input Graph inGraph;
85 input String fileName;
86 algorithm
87 () := matchcontinue fileName
88 local
89 Integer g;
90 GraphML.GraphInfo gi;
91 Ref nr;
92
93 case _
94 algorithm
95 ✗ false := Flags.isSet(Flags.GRAPH_INST_GEN_GRAPH);
96 then
97 ();
98
99 case _
100 algorithm
101 ✗ gi := GraphML.createGraphInfo();
102 ✗ (gi,(_,g)) := GraphML.addGraph("G",false,gi);
103 ✗ nr := FGraph.top(inGraph);
104 ✗ (gi,g) := addNodes((gi,g), {nr});
105 ✗ print("Dumping graph file: " + fileName + " ....\n");
106 ✗ GraphML.dumpGraph(gi, fileName);
107 ✗ print("Dumped\n");
108 then
109 ();
110
111 end matchcontinue;
112 end dumpGraph;
113
114 protected function addNodes
115 input tuple<GraphML.GraphInfo,Integer> gin;
116 input list<Ref> inRefs;
117 output tuple<GraphML.GraphInfo,Integer> gout;
118 algorithm
119 gout := match(gin, inRefs)
120 local
121 tuple<GraphML.GraphInfo,Integer> g;
122 list<Ref> rest;
123 Ref n;
124
125 case (_, {}) then gin;
126
127 case (g, n::rest)
128 // if not userdefined or top, skip it
129 guard not FNode.isRefTop(n) and
130 not FNode.isRefUserDefined(n)
131 ✗ then addNodes(g, rest);
132
133
134 case (g, n::rest)
135 algorithm
136 ✗ g := addNode(g, FNode.fromRef(n));
137 ✗ then addNodes(g, rest);
138
139 end match;
140 end addNodes;
141
142 protected function addNode
143 input tuple<GraphML.GraphInfo,Integer> gin;
144 input Node node;
145 output tuple<GraphML.GraphInfo,Integer> gout;
146 algorithm
147 gout := match(gin, node)
148 local
149 GraphML.GraphInfo gi;
150 Integer i, id;
151 Children kids;
152 String nds, color, labelText;
153 GraphML.ShapeType shape;
154 FCore.WeakRef nr;
155 list<Ref> nrefs;
156 GraphML.NodeLabel label;
157
158 // top node
159 case ((gi,i), FCore.N(parents = {}, children = kids))
160 algorithm
161 ✗ (color, shape, nds) := graphml(node, true);
162 ✗ labelText := nds;
163 ✗ label := GraphML.NODELABEL_INTERNAL(labelText,NONE(),GraphML.FONTPLAIN());
164
165 ✗ (gi, _) := GraphML.addNode(
166 "n" + intString(FNode.id(node)),
167 color,GraphML.BORDERWIDTH_STANDARD, {label}, shape, NONE(), {}, i, gi);
168
169 ✗ nrefs := RefTree.listValues(kids);
170 ✗ (gi,i) := addNodes((gi,i), nrefs);
171 ✗ then
172 ((gi,i));
173
174 // empty REF node, add it with red as is unresolveds
175 case ((gi,i), FCore.N(parents = nr::_, children = kids, data = FCore.REF({})))
176 algorithm
177
178 ✗ (color, shape, nds) := graphml(node, true);
179
180 ✗ labelText := nds;
181 ✗ label := GraphML.NODELABEL_INTERNAL(labelText,NONE(),GraphML.FONTPLAIN());
182
183 ✗ (gi, _) := GraphML.addNode(
184 "n" + intString(FNode.id(node)),
185 color,GraphML.BORDERWIDTH_STANDARD, {label}, shape, NONE(), {}, i, gi);
186
187 ✗ (gi, _) := GraphML.addEdge(
188 "r" + intString(FNode.id(node)),
189 "n" + intString(FNode.id(node)),
190 "n" + intString(FNode.id(FNode.fromRef(MutableWeak.upgrade(nr)))),
191 GraphML.COLOR_RED,
192 GraphML.LINE(),
193 GraphML.LINEWIDTH_STANDARD,
194 false,
195 {}, // {elabel},
196 (GraphML.ARROWNONE(),GraphML.ARROWSTANDART()),
197 {},
198 gi);
199
200 /*/ add ref edge
201 (gi, _) = GraphML.addEdge(
202 "r" + intString(FNode.id(node)),
203 "n" + intString(FNode.id(FNode.fromRef(target))),
204 "n" + intString(FNode.id(FNode.fromRef(MutableWeak.upgrade(nr)))),
205 GraphML.COLOR_RED,
206 GraphML.DASHED(),
207 GraphML.LINEWIDTH_STANDARD,
208 false,
209 {elabel},
210 (GraphML.ARROWNONE(),GraphML.ARROWSTANDART()),
211 {},
212 gi);*/
213
214 ✗ nrefs := RefTree.listValues(kids);
215 ✗ (gi,i) := addNodes((gi,i), nrefs);
216 ✗ then
217 ((gi,i));
218
219 // something REF node, either add it as a new node or an edge (commented out)
220 case ((gi,i), FCore.N(parents = nr::_, children = kids, data = FCore.REF(_::_)))
221 algorithm
222
223 ✗ (color, shape, nds) := graphml(node, true);
224
225 ✗ labelText := nds;
226 ✗ label := GraphML.NODELABEL_INTERNAL(labelText,NONE(),GraphML.FONTPLAIN());
227
228 ✗ (gi, _) := GraphML.addNode(
229 "n" + intString(FNode.id(node)),
230 color,GraphML.BORDERWIDTH_STANDARD, {label}, shape, NONE(), {}, i, gi);
231
232 ✗ (gi, _) := GraphML.addEdge(
233 "r" + intString(FNode.id(node)),
234 "n" + intString(FNode.id(node)),
235 "n" + intString(FNode.id(FNode.fromRef(MutableWeak.upgrade(nr)))),
236 GraphML.COLOR_GREEN,
237 GraphML.LINE(),
238 GraphML.LINEWIDTH_STANDARD,
239 false,
240 {}, // {elabel},
241 (GraphML.ARROWNONE(),GraphML.ARROWSTANDART()),
242 {},
243 gi);
244
245 /*/ add ref edge
246 (gi, _) = GraphML.addEdge(
247 "r" + intString(FNode.id(node)),
248 "n" + intString(FNode.id(FNode.fromRef(target))),
249 "n" + intString(FNode.id(FNode.fromRef(MutableWeak.upgrade(nr)))),
250 GraphML.COLOR_RED,
251 GraphML.DASHED(),
252 GraphML.LINEWIDTH_STANDARD,
253 false,
254 {elabel},
255 (GraphML.ARROWNONE(),GraphML.ARROWSTANDART()),
256 {},
257 gi);*/
258
259 ✗ nrefs := RefTree.listValues(kids);
260 ✗ (gi,i) := addNodes((gi,i), nrefs);
261 ✗ then
262 ((gi,i));
263
264 // ignore coref nodes
265 case ((gi,i), FCore.N(parents = _::_, data = FCore.VR()))
266 ✗ then
267 ((gi,i));
268
269 // other nodes
270 case ((gi,i), FCore.N(parents = nr::_, children = kids))
271 algorithm
272 ✗ (color, shape, nds) := graphml(node, true);
273
274 ✗ labelText := nds;
275 ✗ label := GraphML.NODELABEL_INTERNAL(labelText,NONE(),GraphML.FONTPLAIN());
276
277 ✗ (gi, _) := GraphML.addNode(
278 "n" + intString(FNode.id(node)),
279 color,GraphML.BORDERWIDTH_STANDARD, {label}, shape, NONE(), {}, i, gi);
280
281 ✗ (gi, _) := GraphML.addEdge(
282 "e" + intString(FNode.id(node)),
283 "n" + intString(FNode.id(node)),
284 "n" + intString(FNode.id(FNode.fromRef(MutableWeak.upgrade(nr)))),
285 GraphML.COLOR_BLACK,
286 GraphML.LINE(),
287 GraphML.LINEWIDTH_STANDARD,
288 false,
289 {}, // {elabel},
290 (GraphML.ARROWNONE(),GraphML.ARROWNONE()),
291 {},
292 gi);
293
294 ✗ nrefs := RefTree.listValues(kids);
295 ✗ (gi,i) := addNodes((gi,i), nrefs);
296 ✗ then
297 ((gi,i));
298
299 end match;
300 end addNode;
301
302 public function graphml
303 input Node node;
304 input Boolean escape;
305 output String color;
306 output GraphML.ShapeType shape;
307 output String nname;
308 algorithm
309 (color, shape, nname) := matchcontinue node
310 local
311 Name name;
312 Data nd;
313 SCode.Element e;
314 Absyn.Exp exp;
315 Absyn.ComponentRef r;
316 String s;
317 Absyn.ArrayDim dims;
318 Ref target;
319 Boolean b;
320
321 // redeclare replaceable class
322 case FCore.N(_, _, _, _, FCore.CL(e = e))
323 algorithm
324 ✗ true := SCodeUtil.isElementRedeclare(e);
325 ✗ true := SCodeUtil.isElementReplaceable(e);
326 ✗ b := FNode.isClassExtends(node);
327 ✗ s := if b then "rdrpCE:" else "rdrpC:";
328 ✗ s := s + FNode.name(node);
329 then
330 (GraphML.COLOR_YELLOW, GraphML.HEXAGON(), s);
331
332 // redeclare class
333 case FCore.N(_, _, _, _, FCore.CL(e = e))
334 algorithm
335 ✗ true := SCodeUtil.isElementRedeclare(e);
336 ✗ b := FNode.isClassExtends(node);
337 ✗ s := if b then "rdCE:" else "rdC:";
338 ✗ s := s + FNode.name(node);
339 then
340 (GraphML.COLOR_YELLOW, GraphML.HEXAGON(), s);
341
342 // replaceable class
343 case FCore.N(_, _, _, _, FCore.CL(e = e))
344 algorithm
345 ✗ true := SCodeUtil.isElementReplaceable(e);
346 ✗ s := "rpC:" + FNode.name(node);
347 then
348 (GraphML.COLOR_RED, GraphML.RECTANGLE(), s);
349
350 // redeclare replaceable component
351 case FCore.N(_, _, _, _, FCore.CO(e = e))
352 algorithm
353 ✗ true := SCodeUtil.isElementRedeclare(e);
354 ✗ true := SCodeUtil.isElementReplaceable(e);
355 ✗ s := "rdrpc:" + FNode.name(node);
356 then
357 (GraphML.COLOR_YELLOW, GraphML.ELLIPSE(), s);
358
359 // redeclare component
360 case FCore.N(_, _, _, _, FCore.CO(e = e))
361 algorithm
362 ✗ true := SCodeUtil.isElementRedeclare(e);
363 ✗ s := "rdc:" + FNode.name(node);
364 then
365 (GraphML.COLOR_YELLOW, GraphML.ELLIPSE(), s);
366
367 // replaceable component
368 case FCore.N(_, _, _, _, FCore.CO(e = e))
369 algorithm
370 ✗ true := SCodeUtil.isElementReplaceable(e);
371 ✗ s := "rpc:" + FNode.name(node);
372 then
373 (GraphML.COLOR_RED, GraphML.ELLIPSE(), s);
374
375 // class
376 case FCore.N(_, _, _, _, nd as FCore.CL())
377 algorithm
378 ✗ s := FNode.dataStr(nd) + ":" + FNode.name(node);
379 then
380 (GraphML.COLOR_GRAY, GraphML.RECTANGLE(), s);
381
382 // component
383 case FCore.N(_, _, _, _, nd as FCore.CO())
384 algorithm
385 ✗ s := FNode.dataStr(nd) + ":" + FNode.name(node);
386 then
387 (GraphML.COLOR_WHITE, GraphML.ELLIPSE(), s);
388
389 // extends
390 case FCore.N(_, _, _, _, nd as FCore.EX())
391 algorithm
392 ✗ s := FNode.dataStr(nd) + ":" + FNode.name(node);
393 then
394 (GraphML.COLOR_GREEN, GraphML.ROUNDRECTANGLE(), s);
395
396 // expressions: bindings, condition in conditional components, array dim, etc
397 case FCore.N(_, _, _, _, nd as FCore.EXP(e = exp))
398 algorithm
399 ✗ s := Dump.printExpStr(exp);
400 ✗ s := FNode.dataStr(nd) + ":" + (if escape then Util.escapeModelicaStringToXmlString(s) else Util.stringTrunc(s, 100));
401 then
402 (GraphML.COLOR_PURPLE, GraphML.HEXAGON(), s);
403
404 // dimensions
405 case FCore.N(_, _, _, _, nd as FCore.DIMS(dims = dims))
406 algorithm
407 ✗ s := Dump.printArraydimStr(dims);
408 ✗ s := FNode.dataStr(nd) + ":" + (if escape then Util.escapeModelicaStringToXmlString(s) else Util.stringTrunc(s, 100));
409 then
410 (GraphML.COLOR_PINK, GraphML.TRIANGLE(), s);
411
412 // component references
413 case FCore.N(_, _, _, _, nd as FCore.CR(r = r))
414 algorithm
415 ✗ s := FNode.dataStr(nd) + ":" + Dump.printComponentRefStr(r);
416 then
417 (GraphML.COLOR_PURPLE, GraphML.OCTAGON(), s);
418
419 // ASSERT nodes
420 case FCore.N(_, _, _, _, nd as FCore.ASSERT(s))
421 algorithm
422 ✗ s := FNode.dataStr(nd) + ":" + FNode.name(node);
423 then
424 (GraphML.COLOR_RED, GraphML.PARALLELOGRAM(), s);
425
426 // empty REF nodes
427 case FCore.N(_, _, _, _, nd as FCore.REF({}))
428 algorithm
429 ✗ s := FNode.dataStr(nd) + ":" + "UNRESOLVED";
430 then
431 (GraphML.COLOR_RED, GraphML.PARALLELOGRAM(), s);
432
433 // non empty REF nodes
434 case FCore.N(_, _, _, _, nd as FCore.REF(target::_))
435 algorithm
436 ✗ s := FNode.dataStr(nd) + ":" + FNode.toPathStr(FNode.fromRef(target));
437 then
438 (GraphML.COLOR_GREEN, GraphML.TRAPEZOID(), s);
439
440 // all others
441 case FCore.N(_, _, _, _, nd)
442 algorithm
443 ✗ s := FNode.dataStr(nd) + ":" + FNode.name(node);
444 then
445 (GraphML.COLOR_BLUE, GraphML.ELLIPSE(), s);
446 end matchcontinue;
447 end graphml;
448
449 annotation(__OpenModelica_Interface="frontend");
450 end FGraphDump;
451