Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 83.1% 64 / 0 / 77
Functions: -% 0 / 1 / 1
Branches: 81.6% 31 / 0 / 38

OMCompiler/Compiler/NFFrontEnd/NFRestriction.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 uniontype NFRestriction
37 import Absyn;
38 import ClassInf;
39 import InstContext = NFInstContext;
40 import NFInstNode.InstNode;
41 import SCode;
42
43 protected
44 import Restriction = NFRestriction;
45 import SCodeUtil;
46
47 public
48 record BLOCK end BLOCK;
49 record CLASS end CLASS;
50 record CLOCK end CLOCK;
51
52 record CONNECTOR
53 Boolean isExpandable;
54 end CONNECTOR;
55
56 record ENUMERATION end ENUMERATION;
57 record EXTERNAL_OBJECT end EXTERNAL_OBJECT;
58 record FUNCTION end FUNCTION;
59 record MODEL end MODEL;
60 record PACKAGE end PACKAGE;
61 record OPERATOR end OPERATOR;
62
63 record RECORD
64 Boolean isOperator;
65 Boolean usedExternally;
66 end RECORD;
67
68 record RECORD_CONSTRUCTOR end RECORD_CONSTRUCTOR;
69 record TYPE end TYPE;
70 record UNKNOWN end UNKNOWN;
71
72 function fromSCode
73 input SCode.Restriction sres;
74 output Restriction res;
75 algorithm
76 res := match sres
77 case SCode.Restriction.R_BLOCK() then BLOCK();
78 case SCode.Restriction.R_CLASS() then CLASS();
79 case SCode.Restriction.R_PREDEFINED_CLOCK() then CLOCK();
80 3219 case SCode.Restriction.R_CONNECTOR() then CONNECTOR(sres.isExpandable);
81 case SCode.Restriction.R_ENUMERATION() then ENUMERATION();
82 case SCode.Restriction.R_FUNCTION() then FUNCTION();
83 case SCode.Restriction.R_MODEL() then MODEL();
84 case SCode.Restriction.R_OPERATOR() then OPERATOR();
85 case SCode.Restriction.R_PACKAGE() then PACKAGE();
86 3455 case SCode.Restriction.R_RECORD() then RECORD(sres.isOperator, false);
87 case SCode.Restriction.R_TYPE() then TYPE();
88 else MODEL();
89 end match;
90 end fromSCode;
91
92 function toDAE
93 input Restriction res;
94 input Absyn.Path path;
95 output ClassInf.State state;
96 algorithm
97 state := match res
98 800 case BLOCK() then ClassInf.State.BLOCK(path);
99 ✗ case CLOCK() then ClassInf.State.TYPE_CLOCK(path);
100 1346 case CONNECTOR() then ClassInf.State.CONNECTOR(path, res.isExpandable);
101 ✗ case ENUMERATION() then ClassInf.State.ENUMERATION(path);
102 32 case EXTERNAL_OBJECT() then ClassInf.State.EXTERNAL_OBJ(path);
103 ✗ case FUNCTION() then ClassInf.State.FUNCTION(path, false);
104 3289 case MODEL() then ClassInf.State.MODEL(path);
105 ✗ case OPERATOR() then ClassInf.State.FUNCTION(path, false);
106 9 case PACKAGE() then ClassInf.State.PACKAGE(path);
107 13523 case RECORD() then ClassInf.State.RECORD(path);
108 1575 case RECORD_CONSTRUCTOR() then ClassInf.State.RECORD(path);
109 ✗ case TYPE() then ClassInf.State.TYPE(path);
110 ✗ else ClassInf.State.UNKNOWN(path);
111 end match;
112 end toDAE;
113
114 function isConnector
115 input Restriction res;
116 output Boolean isConnector;
117 algorithm
118 isConnector := match res
119 case CONNECTOR() then true;
120 else false;
121 end match;
122 end isConnector;
123
124 function isExpandableConnector
125 input Restriction res;
126 output Boolean isConnector;
127 algorithm
128 isConnector := match res
129 48940 case CONNECTOR() then res.isExpandable;
130 else false;
131 end match;
132 end isExpandableConnector;
133
134 function isNonexpandableConnector
135 input Restriction res;
136 output Boolean isNonexpandable;
137 algorithm
138 isNonexpandable := match res
139 ✗ case CONNECTOR() then not res.isExpandable;
140 else false;
141 end match;
142 end isNonexpandableConnector;
143
144 function isExternalObject
145 input Restriction res;
146 output Boolean isExternalObject;
147 algorithm
148 isExternalObject := match res
149 case EXTERNAL_OBJECT() then true;
150 else false;
151 end match;
152 end isExternalObject;
153
154 function isFunction
155 input Restriction res;
156 output Boolean isFunction;
157 algorithm
158 isFunction := match res
159 case FUNCTION() then true;
160 else false;
161 end match;
162 end isFunction;
163
164 function isRecordConstructor
165 input Restriction res;
166 output Boolean isConstructor;
167 algorithm
168 isConstructor := match res
169 case RECORD_CONSTRUCTOR() then true;
170 else false;
171 end match;
172 end isRecordConstructor;
173
174 function isRecord
175 input Restriction res;
176 output Boolean isRecord;
177 algorithm
178 isRecord := match res
179 case RECORD() then true;
180 else false;
181 end match;
182 end isRecord;
183
184 function isExternalRecord
185 input Restriction res;
186 output Boolean isExtRecord;
187 algorithm
188 isExtRecord := match res
189 13523 case RECORD() then res.usedExternally;
190 else false;
191 end match;
192 end isExternalRecord;
193
194 function setExternalRecord
195 input output Restriction res;
196 algorithm
197 () := match res
198 case RECORD(usedExternally = false)
199 algorithm
200 10 res.usedExternally := true;
201 then
202 ();
203
204 else ();
205 end match;
206 end setExternalRecord;
207
208 function isOperatorRecord
209 input Restriction res;
210 output Boolean isOpRecord;
211 algorithm
212 isOpRecord := match res
213 134758 case RECORD() then res.isOperator;
214 else false;
215 end match;
216 end isOperatorRecord;
217
218 function isOperator
219 input Restriction res;
220 output Boolean isOperator;
221 algorithm
222 isOperator := match res
223 case OPERATOR() then true;
224 else false;
225 end match;
226 end isOperator;
227
228 function isType
229 input Restriction res;
230 output Boolean isType;
231 algorithm
232 isType := match res
233 case TYPE() then true;
234 else false;
235 end match;
236 end isType;
237
238 function isClock
239 input Restriction res;
240 output Boolean isClock;
241 algorithm
242 isClock := match res
243 case CLOCK() then true;
244 else false;
245 end match;
246 end isClock;
247
248 function isModel
249 input Restriction res;
250 output Boolean isModel;
251 algorithm
252 isModel := match res
253 case MODEL() then true;
254 else false;
255 end match;
256 end isModel;
257
258 function toString
259 input Restriction res;
260 output String str;
261 algorithm
262 str := match res
263 case BLOCK() then "block";
264 case CLASS() then "class";
265 case CLOCK() then "clock";
266 case CONNECTOR()
267
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 then if res.isExpandable then "expandable connector" else "connector";
268 case ENUMERATION() then "enumeration";
269 case EXTERNAL_OBJECT() then "ExternalObject";
270 case FUNCTION() then "function";
271 case MODEL() then "model";
272 case OPERATOR() then "operator";
273 case PACKAGE() then "package";
274 case RECORD() then "record";
275 case RECORD_CONSTRUCTOR() then "record";
276 case TYPE() then "type";
277 else "unknown";
278 end match;
279 end toString;
280
281 function assertNoEquations
282 input list<SCode.Equation> equations;
283 input list<SCode.Equation> initialEquations;
284 input Restriction res;
285 input Boolean onlyDeprecated = false;
286 protected
287 SCode.Equation eq;
288 algorithm
289
4/4
✓ Branch 0 taken 108953 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 108952 times.
✓ Branch 3 taken 1 time.
108959 if listEmpty(equations) and listEmpty(initialEquations) then
290 108952 return;
291 end if;
292
293
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 time.
13 eq := listHead(if listEmpty(equations) then initialEquations else equations);
294
295
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if onlyDeprecated then
296 6 Error.addSourceMessage(Error.DEPRECATED_TRANSITION_FAILURE,
297 {"Equation sections", Restriction.toString(res)}, SCodeUtil.getEquationInfo(eq));
298 else
299 8 Error.addSourceMessage(Error.EQUATION_TRANSITION_FAILURE,
300 {Restriction.toString(res)}, SCodeUtil.getEquationInfo(eq));
301 4 fail();
302 end if;
303 end assertNoEquations;
304
305 function assertNoAlgorithms
306 input list<SCode.AlgorithmSection> algorithms;
307 input list<SCode.AlgorithmSection> initialAlgorithms;
308 input Restriction res;
309 input Boolean onlyDeprecated = false;
310 protected
311 Option<SCode.AlgorithmSection> alg_opt = NONE();
312 SCode.AlgorithmSection alg;
313 SourceInfo info;
314 algorithm
315 88934 alg_opt := List.findOption(algorithms, SCodeUtil.isNonEmptyAlgorithm);
316
317
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88934 times.
✓ Branch 2 taken 88933 times.
✓ Branch 3 taken 1 time.
88934 if isNone(alg_opt) then
318 88933 alg_opt := List.findOption(initialAlgorithms, SCodeUtil.isNonEmptyAlgorithm);
319 end if;
320
321
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88934 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 88933 times.
88934 if isSome(alg_opt) then
322 1 SOME(alg) := alg_opt;
323 1 info := SCodeUtil.getStatementInfo(listHead(alg.statements));
324
325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if onlyDeprecated then
326 ✗ Error.addSourceMessage(Error.DEPRECATED_TRANSITION_FAILURE,
327 {"Algorithm sections", Restriction.toString(res)}, info);
328 ✗ return;
329 else
330 2 Error.addSourceMessage(Error.ALGORITHM_TRANSITION_FAILURE,
331 {Restriction.toString(res)}, info);
332 1 fail();
333 end if;
334 end if;
335 end assertNoAlgorithms;
336
337 function assertNoInitialAlgorithms
338 input list<SCode.AlgorithmSection> algs;
339 input Restriction res;
340 algorithm
341
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 20020 times.
20021 for alg in algs loop
342
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if not listEmpty(alg.statements) then
343 2 Error.addSourceMessage(Error.INITIAL_ALGORITHM_TRANSITION_FAILURE,
344 {Restriction.toString(res)}, SCodeUtil.getStatementInfo(listHead(alg.statements)));
345 1 fail();
346 end if;
347 end for;
348 end assertNoInitialAlgorithms;
349
350 function assertNoProtected
351 input list<SCode.Element> elements;
352 input Restriction res;
353 algorithm
354
2/2
✓ Branch 0 taken 591652 times.
✓ Branch 1 taken 78077 times.
669729 for e in elements loop
355
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 591650 times.
591652 if SCodeUtil.isElementProtected(e) then
356 4 Error.addSourceMessage(Error.PROTECTED_TRANSITION_FAILURE,
357 {Restriction.toString(res)}, SCodeUtil.elementInfo(e));
358 2 fail();
359 end if;
360 end for;
361 end assertNoProtected;
362
363 function assertNoComponents
364 input list<SCode.Element> elements;
365 input Restriction res;
366 algorithm
367
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9 times.
27 for e in elements loop
368
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 2 times.
18 if SCodeUtil.isComponent(e) then
369 32 Error.addSourceMessage(Error.DEPRECATED_TRANSITION_FAILURE,
370 {"Components", Restriction.toString(res)}, SCodeUtil.elementInfo(e));
371 end if;
372 end for;
373 end assertNoComponents;
374
375 function assertOnlyConstantComponents
376 input list<SCode.Element> elements;
377 input InstNode clsNode;
378 algorithm
379
2/2
✓ Branch 0 taken 356622 times.
✓ Branch 1 taken 10720 times.
367342 for e in elements loop
380 () := match e
381 case SCode.Element.COMPONENT()
382 guard not SCodeUtil.isConstant(SCodeUtil.attrVariability(e.attributes))
383 algorithm
384 ✗ Error.addSourceMessage(Error.PACKAGE_VARIABLE_NOT_CONSTANT,
385 {e.name, InstNode.name(clsNode)}, e.info);
386 ✗ then
387 fail();
388
389 else ();
390 end match;
391 end for;
392 end assertOnlyConstantComponents;
393
394 function assertOnlyFunctions
395 input list<SCode.Element> elements;
396 input Restriction res;
397 algorithm
398 ✗ for e in elements loop
399 ✗ if not SCodeUtil.isFunction(e) then
400
401 end if;
402 end for;
403 end assertOnlyFunctions;
404
405 function checkClass
406 input InstNode node;
407 input Restriction restriction;
408 input InstContext.Type context;
409 protected
410 SCode.ClassDef cdef;
411 algorithm
412
2/2
✓ Branch 1 taken 47860 times.
✓ Branch 2 taken 119179 times.
167039 if InstContext.inRelaxed(context) then
413 47860 return;
414 end if;
415
416 119179 cdef := SCodeUtil.getClassBody(InstNode.definition(node));
417
418 () := match cdef
419 case SCode.ClassDef.PARTS()
420 algorithm
421 () := match restriction
422 case Restriction.CLASS()
423 algorithm
424 // Components, equations, and algorithms are deprecated in classes.
425 9 assertNoComponents(cdef.elementLst, restriction);
426 9 assertNoEquations(cdef.normalEquationLst, cdef.initialEquationLst,
427 restriction, onlyDeprecated = true);
428 9 assertNoAlgorithms(cdef.normalAlgorithmLst, cdef.initialAlgorithmLst,
429 restriction, onlyDeprecated = true);
430 then
431 ();
432
433 case Restriction.RECORD()
434 algorithm
435 // Records and operator records may only contain public sections.
436 54919 assertNoProtected(cdef.elementLst, restriction);
437 54919 assertNoEquations(cdef.normalEquationLst, cdef.initialEquationLst, restriction);
438 54918 assertNoAlgorithms(cdef.normalAlgorithmLst, cdef.initialAlgorithmLst, restriction);
439 then
440 ();
441
442 case Restriction.TYPE()
443 algorithm
444 // Types may only contain public sections.
445 9650 assertNoProtected(cdef.elementLst, restriction);
446 9649 assertNoEquations(cdef.normalEquationLst, cdef.initialEquationLst, restriction);
447 9648 assertNoAlgorithms(cdef.normalAlgorithmLst, cdef.initialAlgorithmLst, restriction);
448 then
449 ();
450
451 case Restriction.BLOCK()
452 algorithm
453 // TODO: Components in any connector components in a block must be input/output.
454 then
455 ();
456
457 case Restriction.FUNCTION()
458 algorithm
459 // Functions may not contain equations or initial algorithms.
460 20021 assertNoEquations(cdef.normalEquationLst, cdef.initialEquationLst, restriction);
461 20021 assertNoInitialAlgorithms(cdef.initialAlgorithmLst, restriction);
462 // TODO: May only contain components of class type, record, operator record and function.
463 then
464 ();
465
466 case Restriction.CONNECTOR()
467 algorithm
468 // Connnectors may only contain public sections.
469 13510 assertNoProtected(cdef.elementLst, restriction);
470 13509 assertNoEquations(cdef.normalEquationLst, cdef.initialEquationLst, restriction);
471 13508 assertNoAlgorithms(cdef.normalAlgorithmLst, cdef.initialAlgorithmLst, restriction);
472 // TODO: Components may only be connectors, records, or types.
473 then
474 ();
475
476 case Restriction.PACKAGE()
477 algorithm
478 // All components in a package must be constants.
479 10720 assertOnlyConstantComponents(cdef.elementLst, node);
480 // Packages may not contain equations or algorithms.
481 10720 assertNoEquations(cdef.normalEquationLst, cdef.initialEquationLst, restriction);
482 10719 assertNoAlgorithms(cdef.normalAlgorithmLst, cdef.initialAlgorithmLst, restriction);
483 then
484 ();
485
486 case Restriction.OPERATOR()
487 algorithm
488 // TODO: Only function declarations are allowed
489 // Operators may not contain equations or algorithms.
490 132 assertNoEquations(cdef.normalEquationLst, cdef.initialEquationLst, restriction);
491 132 assertNoAlgorithms(cdef.normalAlgorithmLst, cdef.initialAlgorithmLst, restriction);
492 then
493 ();
494
495 else ();
496 end match;
497 then
498 ();
499
500 else ();
501 end match;
502 end checkClass;
503
504 annotation(__OpenModelica_Interface="nf_frontend");
505 end NFRestriction;
506