Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 22.7% 15 / 0 / 66
Functions: -% 0 / 1 / 1
Branches: 18.0% 9 / 0 / 50

OMCompiler/Compiler/NFFrontEnd/NFPackage.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 NFPackage
37 import FlatModel = NFFlatModel;
38 import InstContext = NFInstContext;
39 import NFFlatten.FunctionTree;
40
41 protected
42 import Absyn;
43 import Algorithm = NFAlgorithm;
44 import Binding = NFBinding;
45 import Ceval = NFCeval;
46 import Class = NFClass;
47 import ClassTree = NFClassTree;
48 import Component = NFComponent;
49 import ComponentRef = NFComponentRef;
50 import Equation = NFEquation;
51 import ExecStat.execStat;
52 import Expression = NFExpression;
53 import Flatten = NFFlatten;
54 import List;
55 import NFFunction.Function;
56 import NFInstNode.InstNode;
57 import Sections = NFSections;
58 import Statement = NFStatement;
59 import Type = NFType;
60 import Typing = NFTyping;
61 import Variable = NFVariable;
62
63 public
64 type Constants = ConstantsSetImpl.Tree;
65
66 encapsulated package ConstantsSetImpl
67 import BaseAvlSet;
68 import ComponentRef = NFComponentRef;
69 extends BaseAvlSet;
70
71 redeclare type Key = ComponentRef;
72
73 redeclare function extends keyStr
74 algorithm
75 ✗ outString := ComponentRef.toString(inKey);
76 end keyStr;
77
78 redeclare function extends keyCompare
79 algorithm
80 ✗ outResult := ComponentRef.compare(inKey1, inKey2);
81 end keyCompare;
82 end ConstantsSetImpl;
83
84 public
85 function collectConstants
86 input output FlatModel flatModel;
87 protected
88 list<Variable> vars;
89 Constants constants;
90 algorithm
91 1574 constants := Constants.new();
92 1574 constants := List.fold(flatModel.variables, collectVariableConstants, constants);
93 1574 constants := Equation.foldExpList(flatModel.equations, collectExpConstants, constants);
94 1574 constants := Equation.foldExpList(flatModel.initialEquations, collectExpConstants, constants);
95 1574 constants := Algorithm.foldExpList(flatModel.algorithms, collectExpConstants, constants);
96 1574 constants := Algorithm.foldExpList(flatModel.initialAlgorithms, collectExpConstants, constants);
97 //constants := FunctionTree.fold(functions, collectFuncConstants, constants);
98
99
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1574 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1574 times.
1574 vars := listReverse(Variable.fromCref(c) for c in Constants.listKeys(constants));
100
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1574 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1574 times.
1574 vars := listAppend(Variable.expand(v) for v in vars);
101 1574 flatModel.variables := listAppend(vars, flatModel.variables);
102
103 1574 execStat(getInstanceName());
104 end collectConstants;
105
106 function replaceConstants
107 input output FlatModel flatModel;
108 input output FunctionTree functions;
109 algorithm
110 ✗ flatModel.variables := list(replaceVariableConstants(c) for c in flatModel.variables);
111 flatModel.equations := Equation.mapExpList(flatModel.equations, replaceExpConstants);
112 flatModel.initialEquations := Equation.mapExpList(flatModel.initialEquations, replaceExpConstants);
113 flatModel.algorithms := Algorithm.mapExpList(flatModel.algorithms, replaceExpConstants);
114 flatModel.initialAlgorithms := Algorithm.mapExpList(flatModel.initialAlgorithms, replaceExpConstants);
115 ✗ functions := FunctionTree.map(functions, replaceFuncConstants);
116 ✗ execStat(getInstanceName());
117 end replaceConstants;
118
119 function collectVariableConstants
120 input Variable var;
121 input output Constants constants;
122 algorithm
123 240842 constants := collectBindingConstants(var.binding, constants);
124
125 // TODO: The component's attributes (i.e. start, etc) might also contain
126 // package constants.
127 end collectVariableConstants;
128
129 function collectBindingConstants
130 input Binding binding;
131 input output Constants constants;
132 algorithm
133
2/2
✓ Branch 1 taken 109773 times.
✓ Branch 2 taken 131069 times.
240842 if Binding.isExplicitlyBound(binding) then
134 131069 constants := collectExpConstants(Binding.getTypedExp(binding), constants);
135 end if;
136 end collectBindingConstants;
137
138 function collectExpConstants
139 input Expression exp;
140 input output Constants constants;
141 algorithm
142 412287 constants := Expression.fold(exp, collectExpConstants_traverser, constants);
143 end collectExpConstants;
144
145 function collectExpConstants_traverser
146 input Expression exp;
147 input output Constants constants;
148 protected
149 ComponentRef cref;
150 Binding binding;
151 algorithm
152 () := match exp
153 case Expression.CREF(cref = cref as ComponentRef.CREF())
154 algorithm
155
3/4
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 450053 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
450065 if ComponentRef.isPackageConstant(cref) and not Expression.isFunctionPointer(exp) then
156 ✗ binding := getPackageConstantBinding(cref);
157 // Add the constant to the set.
158 ✗ constants := Constants.add(constants, ComponentRef.stripSubscriptsAll(cref));
159 // Collect constants from the constant's binding.
160 ✗ constants := collectBindingConstants(binding, constants);
161 end if;
162 then
163 ();
164
165 else ();
166 end match;
167 end collectExpConstants_traverser;
168
169 function getPackageConstantBinding
170 input ComponentRef cref;
171 output Binding binding;
172 protected
173 InstNode cr_node = ComponentRef.node(cref);
174 algorithm
175 ✗ Typing.typeComponentBinding(cr_node, NFInstContext.CLASS);
176 ✗ binding := Component.getImplicitBinding(InstNode.component(cr_node), InstNode.instanceParent(cr_node));
177
178 ✗ if Binding.isUnbound(binding) then
179 ✗ binding := getPackageConstantBinding2(cr_node, ComponentRef.rest(cref));
180 ✗ InstNode.componentApply(cr_node, Component.setBinding, binding);
181 end if;
182 end getPackageConstantBinding;
183
184 function getPackageConstantBinding2
185 input InstNode fieldNode;
186 input ComponentRef cref;
187 output Binding binding;
188 protected
189 InstNode cr_node;
190 Boolean is_record;
191 algorithm
192 ✗ if not ComponentRef.isCref(cref) then
193 binding := NFBinding.EMPTY_BINDING;
194 ✗ return;
195 end if;
196
197 ✗ is_record := Type.isRecord(Type.arrayElementType(ComponentRef.nodeType(cref)));
198 ✗ cr_node := ComponentRef.node(cref);
199
200 ✗ if not (InstNode.isComponent(cr_node) and is_record) then
201 binding := NFBinding.EMPTY_BINDING;
202 ✗ return;
203 end if;
204
205 ✗ Typing.typeComponentBinding(cr_node, NFInstContext.CLASS);
206 ✗ binding := Component.getBinding(InstNode.component(cr_node));
207
208 ✗ if Binding.isUnbound(binding) then
209 ✗ binding := getPackageConstantBinding2(cr_node, ComponentRef.rest(cref));
210 end if;
211
212 ✗ if Binding.isBound(binding) then
213 ✗ binding := Binding.recordFieldBinding(fieldNode, binding);
214 end if;
215 end getPackageConstantBinding2;
216
217 function collectFuncConstants
218 input Absyn.Path name;
219 input Function func;
220 input output Constants constants;
221 protected
222 Class cls;
223 array<InstNode> comps;
224 Sections sections;
225 algorithm
226 ✗ cls := InstNode.getClass(InstNode.fromHandle(func.node));
227
228 () := match cls
229 case Class.INSTANCED_CLASS(elements = ClassTree.FLAT_TREE(components = comps),
230 sections = sections)
231 algorithm
232 ✗ for c in comps loop
233 ✗ constants := collectBindingConstants(
234 Component.getBinding(InstNode.component(c)), constants);
235 end for;
236
237 () := match sections
238 case Sections.SECTIONS()
239 algorithm
240 ✗ constants := Algorithm.foldExpList(sections.algorithms, collectExpConstants, constants);
241 then
242 ();
243
244 case Sections.EXTERNAL()
245 algorithm
246 ✗ for arg in sections.args loop
247 ✗ constants := collectExpConstants(arg, constants);
248 end for;
249 then
250 ();
251
252 else ();
253 end match;
254 then
255 ();
256
257 else ();
258 end match;
259 end collectFuncConstants;
260
261 function replaceVariableConstants
262 input output Variable var;
263 protected
264 Binding binding;
265 algorithm
266 ✗ binding := replaceBindingConstants(var.binding);
267
268 ✗ if not referenceEq(binding, var.binding) then
269 ✗ var.binding := binding;
270 end if;
271 end replaceVariableConstants;
272
273 function replaceBindingConstants
274 input output Binding binding;
275 algorithm
276 () := match binding
277 case Binding.TYPED_BINDING()
278 algorithm
279 ✗ binding.bindingExp := replaceExpConstants(binding.bindingExp);
280 then
281 ();
282
283 else ();
284 end match;
285 end replaceBindingConstants;
286
287 function replaceExpConstants
288 input output Expression exp;
289 algorithm
290 ✗ exp := Expression.map(exp, replaceExpConstants_traverser);
291 end replaceExpConstants;
292
293 function replaceExpConstants_traverser
294 input output Expression exp;
295 protected
296 ComponentRef cref;
297 algorithm
298 exp := match exp
299 case Expression.CREF(cref = cref as ComponentRef.CREF())
300 ✗ then if ComponentRef.isPackageConstant(cref) then Ceval.evalExp(exp) else exp;
301
302 else exp;
303 end match;
304 end replaceExpConstants_traverser;
305
306 function replaceFuncConstants
307 input Absyn.Path name;
308 input output Function func;
309 protected
310 Class cls;
311 array<InstNode> comps;
312 Sections sections;
313 Component comp;
314 Binding binding, eval_binding;
315 algorithm
316 ✗ cls := InstNode.getClass(InstNode.fromHandle(func.node));
317
318 () := match cls
319 case Class.INSTANCED_CLASS(elements = ClassTree.FLAT_TREE(components = comps),
320 sections = sections)
321 algorithm
322 ✗ for c in comps loop
323 ✗ comp := InstNode.component(c);
324 ✗ binding := Component.getBinding(comp);
325 ✗ eval_binding := replaceBindingConstants(binding);
326
327 ✗ if not referenceEq(binding, eval_binding) then
328 ✗ comp := Component.setBinding(eval_binding, comp);
329 ✗ InstNode.updateComponent(comp, c);
330 end if;
331 end for;
332
333 () := match sections
334 case Sections.SECTIONS()
335 algorithm
336 ✗ sections.algorithms := list(Algorithm.mapExp(a, replaceExpConstants) for a in sections.algorithms);
337 ✗ cls.sections := sections;
338 ✗ InstNode.updateClass(cls, InstNode.fromHandle(func.node));
339 then
340 ();
341
342 case Sections.EXTERNAL()
343 algorithm
344 ✗ sections.args := list(replaceExpConstants(arg) for arg in sections.args);
345 ✗ cls.sections := sections;
346 ✗ InstNode.updateClass(cls, InstNode.fromHandle(func.node));
347 then
348 ();
349
350 else ();
351 end match;
352 then
353 ();
354
355 end match;
356 end replaceFuncConstants;
357
358 annotation(__OpenModelica_Interface="nf_frontend");
359 end NFPackage;
360