Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 88.9% 24 / 0 / 27
Functions: -% 0 / 1 / 1
Branches: 67.9% 19 / 0 / 28

OMCompiler/Compiler/NFFrontEnd/NFConnectBreakTree.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 NFConnectBreakTree
37 "A tree structure for handling `break connect` modifiers."
38 import AbsynUtil;
39 import BaseAvlTree;
40 import UnorderedMap;
41 import NFInstNode.InstNode;
42
43 protected
44 import Absyn;
45 import Dump;
46 import Lookup = NFLookup;
47 import Mutable;
48 import SCode;
49
50 public
51 uniontype Entry
52 record ENTRY
53 Boolean hasMatch;
54 SCode.Mod mod;
55 end ENTRY;
56 end Entry;
57
58 encapsulated package EntryTree
59 import BaseAvlTree;
60 import NFConnectBreakTree.Entry;
61
62 extends BaseAvlTree(redeclare type Key = Absyn.ComponentRef,
63 redeclare type Value = Mutable<Entry>);
64
65 redeclare function extends keyStr
66 algorithm
67 ✗ outString := Dump.printComponentRefStr(inKey);
68 end keyStr;
69
70 redeclare function extends valueStr
71 algorithm
72 outString := "";
73 end valueStr;
74
75 redeclare function extends keyCompare
76 algorithm
77 4 outResult := AbsynUtil.crefCompare(inKey1, inKey2);
78 end keyCompare;
79 end EntryTree;
80
81 type EntryTable = UnorderedMap<String, Entry>;
82
83 extends BaseAvlTree(redeclare type Key = Absyn.ComponentRef,
84 redeclare type Value = EntryTree.Tree);
85
86 redeclare function extends keyStr
87 algorithm
88 ✗ outString := Dump.printComponentRefStr(inKey);
89 end keyStr;
90
91 redeclare function extends valueStr
92 algorithm
93 outString := "";
94 end valueStr;
95
96 redeclare function extends keyCompare
97 algorithm
98 13414 outResult := AbsynUtil.crefCompare(inKey1, inKey2);
99 end keyCompare;
100
101 function appendBreaksInNode
102 "Appends any `break connect` modifiers from the node to the given tree, and
103 returns the new entries as a list that can be passed to
104 checkUnmatchedBreaks once the connects have been processed."
105 input InstNode node;
106 input output Tree tree;
107 output list<Mutable<Entry>> newEntries = {};
108 protected
109 SCode.Mod mod, break_mod;
110 Mutable<Entry> entry;
111
112 function add_entry
113 input Absyn.ComponentRef name;
114 input Mutable<Entry> entry;
115 input Option<EntryTree.Tree> oldTree;
116 output EntryTree.Tree outTree;
117 algorithm
118
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 if isSome(oldTree) then
119 ✗ SOME(outTree) := oldTree;
120 else
121 10 outTree := EntryTree.new();
122 end if;
123
124 10 outTree := EntryTree.update(outTree, name, entry);
125 end add_entry;
126 algorithm
127 () := match InstNode.extendsDefinition(node)
128 case SOME(SCode.Element.EXTENDS(modifications = mod as SCode.Mod.MOD()))
129 algorithm
130
2/2
✓ Branch 0 taken 21042 times.
✓ Branch 1 taken 3805 times.
24847 for sm in mod.subModLst loop
131 () := match sm
132 case SCode.NAMEMOD(mod = break_mod as SCode.Mod.BREAK_CONNECT())
133 algorithm
134 5 entry := Mutable.create(Entry.ENTRY(false, break_mod));
135 newEntries := entry :: newEntries;
136
137 // Add both rhs->lhs and lhs->rhs to reduce the amount of lookup needed,
138 // since there's presumably a lot more connects than breaks.
139 5 tree := addUpdate(tree, break_mod.rhs, function add_entry(name = break_mod.lhs, entry = entry));
140 5 tree := addUpdate(tree, break_mod.lhs, function add_entry(name = break_mod.rhs, entry = entry));
141 then
142 ();
143
144 else ();
145 end match;
146 end for;
147 then
148 ();
149
150 else ();
151 end match;
152 end appendBreaksInNode;
153
154 function isConnectBroken
155 "Checks if there's a matching `break connect` modifier for the given connectors,
156 and updates the entry in the tree if there is."
157 input Absyn.ComponentRef lhs;
158 input Absyn.ComponentRef rhs;
159 input InstNode scope;
160 input Tree connectBreaks;
161 output Boolean isBroken = false;
162 protected
163 Option<EntryTree.Tree> opt_entry_tree;
164 Option<Mutable<Entry>> opt_entry_ptr;
165 Mutable<Entry> entry_ptr;
166 Entry entry;
167
168 function is_broken
169 input Absyn.ComponentRef cref;
170 input InstNode scope;
171 output Boolean isBroken;
172 algorithm
173 try
174 6 isBroken := InstNode.isEmpty(Lookup.lookupLocalSimpleName(AbsynUtil.crefFirstIdent(cref), scope));
175 else
176 isBroken := false;
177 end try;
178 end is_broken;
179 algorithm
180 13400 opt_entry_tree := getOpt(connectBreaks, lhs);
181
182
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13400 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 13396 times.
13400 if isSome(opt_entry_tree) then
183 4 opt_entry_ptr := EntryTree.getOpt(Util.getOption(opt_entry_tree), rhs);
184
185 // Mark the entry as having a match if an entry was found, and neither connector has been
186 // deselected by a component break. Connections associated with deselected connectors should
187 // be removed first, but we do it after this, so just ignore them here.
188
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
4 if isSome(opt_entry_ptr) and not is_broken(lhs, scope) and not is_broken(rhs, scope) then
189
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 SOME(entry_ptr) := opt_entry_ptr;
190 3 entry := Mutable.access(entry_ptr);
191 3 entry.hasMatch := true;
192 3 Mutable.update(entry_ptr, entry);
193 isBroken := true;
194 end if;
195 end if;
196 end isConnectBroken;
197
198 function checkUnmatchedBreaks
199 "Prints an error message and fails if any entry in the list hasn't been
200 marked as having a matching connect."
201 input list<Mutable<Entry>> entries;
202 protected
203 Entry entry;
204 Absyn.ComponentRef lhs, rhs;
205 SourceInfo info;
206 algorithm
207
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 254152 times.
254157 for e in entries loop
208 5 entry := Mutable.access(e);
209
210
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if not entry.hasMatch then
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 SCode.Mod.BREAK_CONNECT(lhs = lhs, rhs = rhs, info = info) := entry.mod;
212 6 Error.addSourceMessage(Error.UNMATCHED_BREAK_CONNECT,
213 {Dump.printComponentRefStr(lhs), Dump.printComponentRefStr(rhs)}, info);
214 2 fail();
215 end if;
216 end for;
217 end checkUnmatchedBreaks;
218
219 annotation(__OpenModelica_Interface="nf_frontend");
220 end NFConnectBreakTree;
221