Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 73.2% 120 / 0 / 164
Functions: -% 0 / 1 / 1
Branches: 71.4% 40 / 0 / 56

OMCompiler/Compiler/NFFrontEnd/NFClass.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 NFClass
37
38 import Attributes = NFAttributes;
39 import BaseModelica;
40 import NFCall.Call;
41 import Component = NFComponent;
42 import ComponentRef = NFComponentRef;
43 import Dimension = NFDimension;
44 import Expression = NFExpression;
45 import NFClassTree.ClassTree;
46 import NFInstNode.InstNode;
47 import NFInstNode;
48 import NFModifier.Modifier;
49 import NFSections.Sections;
50 import NFStatement.Statement;
51 import Record = NFRecord;
52 import Restriction = NFRestriction;
53 import SCode.Element;
54 import Type = NFType;
55
56 protected
57 import Absyn;
58 import DAE;
59 import AbsynUtil;
60 import Binding = NFBinding;
61 import Class = NFClass;
62 import ComplexType = NFComplexType;
63 import IOStream;
64 import SCode;
65 import SCodeUtil;
66 import System;
67 import MetaModelica.Dangerous.listReverseInPlace;
68
69 public
70
71 constant Prefixes DEFAULT_PREFIXES = Prefixes.PREFIXES(
72 SCode.Encapsulated.NOT_ENCAPSULATED(),
73 SCode.Partial.NOT_PARTIAL(),
74 SCode.Final.NOT_FINAL(),
75 Absyn.InnerOuter.NOT_INNER_OUTER(),
76 SCode.Replaceable.NOT_REPLACEABLE()
77 );
78
79 uniontype Prefixes
80 record PREFIXES
81 SCode.Encapsulated encapsulatedPrefix;
82 SCode.Partial partialPrefix;
83 SCode.Final finalPrefix;
84 Absyn.InnerOuter innerOuter;
85 SCode.Replaceable replaceablePrefix;
86 end PREFIXES;
87
88 function isEqual
89 input Prefixes prefs1;
90 input Prefixes prefs2;
91 output Boolean isEqual = valueEq(prefs1, prefs2);
92 end isEqual;
93
94 function isPartial
95 input Prefixes prefs;
96 output Boolean isPartial = SCodeUtil.partialBool(prefs.partialPrefix);
97 end isPartial;
98
99 function isEncapsulated
100 input Prefixes prefs;
101 output Boolean isEncapsulated = SCodeUtil.encapsulatedBool(prefs.encapsulatedPrefix);
102 end isEncapsulated;
103 end Prefixes;
104
105 record NOT_INSTANTIATED end NOT_INSTANTIATED;
106
107 record PARTIAL_CLASS
108 ClassTree elements;
109 Modifier modifier;
110 Modifier ccMod;
111 Prefixes prefixes;
112 end PARTIAL_CLASS;
113
114 record PARTIAL_BUILTIN
115 Type ty;
116 ClassTree elements;
117 Modifier modifier;
118 Prefixes prefixes;
119 Restriction restriction;
120 end PARTIAL_BUILTIN;
121
122 record EXPANDED_CLASS
123 ClassTree elements;
124 Modifier modifier;
125 Modifier ccMod;
126 Prefixes prefixes;
127 Restriction restriction;
128 end EXPANDED_CLASS;
129
130 record EXPANDED_DERIVED
131 InstNode baseClass;
132 Modifier modifier;
133 Modifier ccMod;
134 array<Dimension> dims;
135 Prefixes prefixes;
136 Attributes attributes;
137 Restriction restriction;
138 end EXPANDED_DERIVED;
139
140 record INSTANCED_CLASS
141 Type ty;
142 ClassTree elements;
143 Sections sections;
144 Prefixes prefixes;
145 Restriction restriction;
146 end INSTANCED_CLASS;
147
148 record INSTANCED_BUILTIN
149 Type ty;
150 ClassTree elements;
151 Restriction restriction;
152 end INSTANCED_BUILTIN;
153
154 record TYPED_DERIVED
155 Type ty;
156 InstNode baseClass;
157 Restriction restriction;
158 end TYPED_DERIVED;
159
160 record DAE_TYPE
161 DAE.Type ty;
162 end DAE_TYPE;
163
164 function fromSCode
165 input list<SCode.Element> elements;
166 input Boolean isClassExtends;
167 input InstNode scope;
168 input Prefixes prefixes;
169 output Class cls;
170 protected
171 ClassTree tree;
172 algorithm
173 79606 tree := ClassTree.fromSCode(elements, isClassExtends, scope);
174 79604 cls := PARTIAL_CLASS(tree, Modifier.NOMOD(), Modifier.NOMOD(), prefixes);
175 end fromSCode;
176
177 function initImports
178 input output Class cls;
179 input InstNode parent;
180 algorithm
181 () := match cls
182 case PARTIAL_CLASS()
183 algorithm
184 93243 cls.elements := ClassTree.initImports(cls.elements, parent);
185 then
186 ();
187
188 else ();
189 end match;
190 end initImports;
191
192 function fromEnumeration
193 input list<SCode.Enum> literals;
194 input Type enumType;
195 input Prefixes prefixes;
196 input InstNode enumClass;
197 output Class cls;
198 protected
199 ClassTree tree;
200 algorithm
201 1179 tree := ClassTree.fromEnumeration(literals, enumType, enumClass);
202 1178 cls := PARTIAL_BUILTIN(enumType, tree, Modifier.NOMOD(), prefixes, Restriction.ENUMERATION());
203 end fromEnumeration;
204
205 function makeRecordConstructor
206 input list<InstNode> fields;
207 input InstNode out;
208 output Class cls;
209 protected
210 ClassTree tree;
211 algorithm
212 2789 tree := ClassTree.fromRecordConstructor(fields, out);
213 2789 cls := INSTANCED_CLASS(Type.UNKNOWN(), tree, Sections.EMPTY(),
214 DEFAULT_PREFIXES, Restriction.RECORD_CONSTRUCTOR());
215 end makeRecordConstructor;
216
217 function initExpandedClass
218 input output Class cls;
219 algorithm
220 cls := match cls
221 case PARTIAL_CLASS()
222 71411 then EXPANDED_CLASS(cls.elements, cls.modifier, cls.ccMod, cls.prefixes, Restriction.UNKNOWN());
223 end match;
224 end initExpandedClass;
225
226 function getSections
227 input Class cls;
228 output Sections sections;
229 algorithm
230 sections := match cls
231 70695 case INSTANCED_CLASS() then cls.sections;
232 14 case TYPED_DERIVED() then getSections(InstNode.getClass(cls.baseClass));
233 else Sections.EMPTY();
234 end match;
235 end getSections;
236
237 function setSections
238 input Sections sections;
239 input output Class cls;
240 algorithm
241 cls := match cls
242 case INSTANCED_CLASS()
243 98287 then INSTANCED_CLASS(cls.ty, cls.elements, sections, cls.prefixes, cls.restriction);
244
245 case TYPED_DERIVED()
246 algorithm
247 2 InstNode.classApply(cls.baseClass, setSections, sections);
248 then
249 cls;
250 end match;
251 end setSections;
252
253 function lookupElement
254 input String name;
255 input Class cls;
256 output InstNode node;
257 output Boolean isImport;
258 algorithm
259 6244448 (node, isImport) := ClassTree.lookupElement(name, classTree(cls));
260 end lookupElement;
261
262 function tryLookupElement
263 input String name;
264 input Class cls;
265 output Option<InstNode> node;
266 output Boolean isImport;
267 protected
268 InstNode n;
269 algorithm
270 try
271 58162 (n, isImport) := ClassTree.lookupElement(name, classTree(cls));
272 node := SOME(n);
273 else
274 node := NONE();
275 55387 isImport := false;
276 end try;
277 end tryLookupElement;
278
279 function lookupComponentIndex
280 input String name;
281 input Class cls;
282 output Integer index;
283 algorithm
284 175829 index := ClassTree.lookupComponentIndex(name, classTree(cls));
285 end lookupComponentIndex;
286
287 function nthComponent
288 input Integer index;
289 input Class cls;
290 output InstNode component;
291 algorithm
292 3584 component := ClassTree.nthComponent(index, classTree(cls));
293 end nthComponent;
294
295 function getComponents
296 input Class cls;
297 output array<InstNode> comps = ClassTree.getComponents(classTree(cls));
298 end getComponents;
299
300 function lookupAttributeBinding
301 input String name;
302 input Class cls;
303 output Binding binding;
304 protected
305 InstNode attr_node;
306 algorithm
307 try
308 45652 attr_node := ClassTree.lookupElement(name, classTree(cls));
309 44104 binding := Component.getBinding(InstNode.component(attr_node));
310 else
311 binding := NFBinding.EMPTY_BINDING;
312 end try;
313 end lookupAttributeBinding;
314
315 function lookupAttributeValue
316 input String name;
317 input Class cls;
318 output Option<Expression> value = Binding.typedExp(lookupAttributeBinding(name, cls));
319 end lookupAttributeValue;
320
321 function isOnlyBuiltin
322 input Class cls;
323 output Boolean builtin;
324 algorithm
325 builtin := match cls
326 case PARTIAL_BUILTIN() then true;
327 case INSTANCED_BUILTIN() then true;
328 else false;
329 end match;
330 end isOnlyBuiltin;
331
332 function isBuiltin
333 input Class cls;
334 output Boolean isBuiltin;
335 algorithm
336 isBuiltin := match cls
337 case PARTIAL_BUILTIN() then true;
338 case INSTANCED_BUILTIN() then true;
339 2371 case EXPANDED_DERIVED() then isBuiltin(InstNode.getClass(cls.baseClass));
340 ✗ case TYPED_DERIVED() then isBuiltin(InstNode.getClass(cls.baseClass));
341 else false;
342 end match;
343 end isBuiltin;
344
345 function classTree
346 input Class cls;
347 output ClassTree tree;
348 algorithm
349 tree := match cls
350 143311 case Class.PARTIAL_CLASS() then cls.elements;
351 919130 case Class.PARTIAL_BUILTIN() then cls.elements;
352 2649661 case Class.EXPANDED_CLASS() then cls.elements;
353 92039 case Class.EXPANDED_DERIVED() then classTree(InstNode.getClass(cls.baseClass));
354 4380522 case Class.INSTANCED_CLASS() then cls.elements;
355 4152246 case Class.INSTANCED_BUILTIN() then cls.elements;
356 5581 case Class.TYPED_DERIVED() then classTree(InstNode.getClass(cls.baseClass));
357 else ClassTree.EMPTY_TREE();
358 end match;
359 end classTree;
360
361 function setClassTree
362 input ClassTree tree;
363 input output Class cls;
364 algorithm
365 () := match cls
366 3744 case Class.PARTIAL_CLASS() algorithm cls.elements := tree; then ();
367 170792 case Class.EXPANDED_CLASS() algorithm cls.elements := tree; then ();
368 ✗ case Class.PARTIAL_BUILTIN() algorithm cls.elements := tree; then ();
369 12 case Class.INSTANCED_CLASS() algorithm cls.elements := tree; then ();
370 ✗ case Class.INSTANCED_BUILTIN() algorithm cls.elements := tree; then ();
371 end match;
372 end setClassTree;
373
374 function classTreeApply
375 input output Class cls;
376 input FuncType func;
377
378 partial function FuncType
379 input output ClassTree tree;
380 end FuncType;
381 algorithm
382 () := match cls
383
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 case Class.PARTIAL_CLASS() algorithm cls.elements := func(cls.elements); then ();
384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3976 times.
3976 case Class.EXPANDED_CLASS() algorithm cls.elements := func(cls.elements); then ();
385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8475 times.
8475 case Class.PARTIAL_BUILTIN() algorithm cls.elements := func(cls.elements); then ();
386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 case Class.INSTANCED_CLASS() algorithm cls.elements := func(cls.elements); then ();
387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 case Class.INSTANCED_BUILTIN() algorithm cls.elements := func(cls.elements); then ();
388 else ();
389 end match;
390 end classTreeApply;
391
392 function getModifier
393 input Class cls;
394 output Modifier modifier;
395 algorithm
396 modifier := match cls
397 30586 case PARTIAL_CLASS() then cls.modifier;
398 301388 case EXPANDED_CLASS() then cls.modifier;
399 695737 case EXPANDED_DERIVED() then cls.modifier;
400 862047 case PARTIAL_BUILTIN() then cls.modifier;
401 else Modifier.NOMOD();
402 end match;
403 end getModifier;
404
405 function getCCModifier
406 input Class cls;
407 output Modifier modifier;
408 algorithm
409 modifier := match cls
410 13230 case PARTIAL_CLASS() then cls.ccMod;
411 ✗ case EXPANDED_CLASS() then cls.ccMod;
412 ✗ case EXPANDED_DERIVED() then cls.ccMod;
413 else Modifier.NOMOD();
414 end match;
415 end getCCModifier;
416
417 function setModifier
418 input Modifier modifier;
419 input output Class cls;
420 algorithm
421 () := match cls
422 case PARTIAL_CLASS()
423 algorithm
424 ✗ cls.modifier := modifier;
425 then
426 ();
427 case EXPANDED_CLASS()
428 algorithm
429 ✗ cls.modifier := modifier;
430 then
431 ();
432 case EXPANDED_DERIVED()
433 algorithm
434 ✗ cls.modifier := modifier;
435 then
436 ();
437 case PARTIAL_BUILTIN()
438 algorithm
439 ✗ cls.modifier := modifier;
440 then
441 ();
442 else
443 algorithm
444 ✗ Error.terminate(getInstanceName() + " got non-modifiable class", sourceInfo());
445 ✗ then
446 fail();
447 end match;
448 end setModifier;
449
450 function mergeModifier
451 input Modifier modifier;
452 input output Class cls;
453 algorithm
454 () := match cls
455 case PARTIAL_CLASS()
456 algorithm
457 1782 cls.modifier := Modifier.merge(modifier, cls.modifier);
458 then
459 ();
460 case EXPANDED_CLASS()
461 algorithm
462 ✗ cls.modifier := Modifier.merge(modifier, cls.modifier);
463 then
464 ();
465 case EXPANDED_DERIVED()
466 algorithm
467 4 cls.modifier := Modifier.merge(modifier, cls.modifier);
468 then
469 ();
470 case PARTIAL_BUILTIN()
471 algorithm
472 8 cls.modifier := Modifier.merge(modifier, cls.modifier);
473 then
474 ();
475 else
476 algorithm
477 ✗ Error.terminate(getInstanceName() + " got non-modifiable class", sourceInfo());
478 ✗ then
479 fail();
480 end match;
481 end mergeModifier;
482
483 function isIdentical
484 input Class cls1;
485 input Class cls2;
486 output Boolean identical = false;
487 algorithm
488
1/2
✓ Branch 0 taken 32943 times.
✗ Branch 1 not taken.
32943 if referenceEq(cls1, cls2) then
489 identical := true;
490 else
491 identical := match (cls1, cls2)
492 case (EXPANDED_CLASS(), EXPANDED_CLASS())
493
2/4
✓ Branch 1 taken 2794 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2794 times.
2794 then Prefixes.isEqual(cls1.prefixes, cls2.prefixes) and
494 ClassTree.isIdentical(cls1.elements, cls2.elements);
495
496 case (INSTANCED_BUILTIN(), INSTANCED_BUILTIN())
497 algorithm
498
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8745 times.
8745 if not Type.isEqual(cls1.ty, cls2.ty) then
499 ✗ return;
500 end if;
501 then
502 true;
503
504 else true;
505 end match;
506 end if;
507 end isIdentical;
508
509 function hasDimensions
510 input Class cls;
511 output Boolean hasDims;
512 algorithm
513 hasDims := match cls
514 case EXPANDED_DERIVED()
515
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
4 then arrayLength(cls.dims) > 0 or hasDimensions(InstNode.getClass(cls.baseClass));
516 ✗ case TYPED_DERIVED() then Type.isArray(cls.ty);
517 else false;
518 end match;
519 end hasDimensions;
520
521 function getDimensions
522 input Class cls;
523 output list<Dimension> dims;
524 algorithm
525 dims := match cls
526 ✗ case INSTANCED_CLASS() then Type.arrayDims(cls.ty);
527 ✗ case INSTANCED_BUILTIN() then Type.arrayDims(cls.ty);
528 ✗ case TYPED_DERIVED() then Type.arrayDims(cls.ty);
529 else {};
530 end match;
531 end getDimensions;
532
533 function dimensionCount
534 input Class cls;
535 output Integer count;
536 algorithm
537 count := match cls
538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 case EXPANDED_DERIVED() then arrayLength(cls.dims);
539 9636 case INSTANCED_CLASS() then Type.dimensionCount(cls.ty);
540 546283 case INSTANCED_BUILTIN() then Type.dimensionCount(cls.ty);
541 2106 case TYPED_DERIVED() then Type.dimensionCount(cls.ty);
542 else 0;
543 end match;
544 end dimensionCount;
545
546 function getAttributes
547 input Class cls;
548 output Attributes attr;
549 algorithm
550 attr := match cls
551 ✗ case EXPANDED_DERIVED() then cls.attributes;
552 else NFAttributes.DEFAULT_ATTR;
553 end match;
554 end getAttributes;
555
556 function getTypeAttributes
557 input Class cls;
558 output list<Modifier> attributes = {};
559 protected
560 array<InstNode> comps;
561 Modifier mod;
562 algorithm
563 try
564 300282 comps := ClassTree.getComponents(classTree(cls));
565
566
2/2
✓ Branch 1 taken 3051118 times.
✓ Branch 2 taken 299940 times.
3351058 for c in comps loop
567 3051118 mod := Component.getModifier(InstNode.component(c));
568
569
2/2
✓ Branch 1 taken 553254 times.
✓ Branch 2 taken 2497864 times.
3051118 if not Modifier.isEmpty(mod) then
570 attributes := mod :: attributes;
571 end if;
572 end for;
573 else
574 end try;
575 end getTypeAttributes;
576
577 function getType
578 input Class cls;
579 input InstNode clsNode;
580 output Type ty;
581 algorithm
582 ty := match cls
583 489 case PARTIAL_BUILTIN() then cls.ty;
584 56695 case EXPANDED_DERIVED() then getType(InstNode.getClass(cls.baseClass), cls.baseClass);
585 448487 case INSTANCED_CLASS() then cls.ty;
586 342364 case INSTANCED_BUILTIN() then cls.ty;
587 10 case TYPED_DERIVED() then cls.ty;
588 else Type.UNKNOWN();
589 end match;
590 end getType;
591
592 function setType
593 input Type ty;
594 input output Class cls;
595 algorithm
596 () := match cls
597 case PARTIAL_BUILTIN()
598 algorithm
599 ✗ cls.ty := ty;
600 then
601 ();
602
603 case EXPANDED_DERIVED()
604 algorithm
605 ✗ InstNode.classApply(cls.baseClass, setType, ty);
606 then
607 ();
608
609 case INSTANCED_CLASS()
610 algorithm
611 2829 cls.ty := ty;
612 then
613 ();
614
615 case INSTANCED_BUILTIN()
616 algorithm
617 ✗ cls.ty := ty;
618 then
619 ();
620
621 case TYPED_DERIVED()
622 algorithm
623 ✗ cls.ty := ty;
624 then
625 ();
626
627 else ();
628 end match;
629 end setType;
630
631 function restriction
632 input Class cls;
633 output Restriction res;
634 algorithm
635 res := match cls
636 795 case PARTIAL_BUILTIN() then cls.restriction;
637 1111334 case EXPANDED_CLASS() then cls.restriction;
638 542391 case EXPANDED_DERIVED() then cls.restriction;
639 945182 case INSTANCED_CLASS() then cls.restriction;
640 644198 case INSTANCED_BUILTIN() then cls.restriction;
641 9 case TYPED_DERIVED() then cls.restriction;
642 else Restriction.UNKNOWN();
643 end match;
644 end restriction;
645
646 function setRestriction
647 input Restriction res;
648 input output Class cls;
649 algorithm
650 () := match cls
651 // PARTIAL_BUILTIN is only used for predefined builtin types and not needed here.
652 ✗ case EXPANDED_CLASS() algorithm cls.restriction := res; then ();
653 ✗ case EXPANDED_DERIVED() algorithm cls.restriction := res; then ();
654 12030 case INSTANCED_CLASS() algorithm cls.restriction := res; then ();
655 316110 case INSTANCED_BUILTIN() algorithm cls.restriction := res; then ();
656 ✗ case TYPED_DERIVED() algorithm cls.restriction := res; then ();
657 end match;
658 end setRestriction;
659
660 function isConnectorClass
661 input Class cls;
662 output Boolean isConnector = Restriction.isConnector(restriction(cls));
663 end isConnectorClass;
664
665 function isNonexpandableConnectorClass
666 input Class cls;
667 output Boolean isConnector = Restriction.isNonexpandableConnector(restriction(cls));
668 end isNonexpandableConnectorClass;
669
670 function isExpandableConnectorClass
671 input Class cls;
672 output Boolean isConnector = Restriction.isExpandableConnector(restriction(cls));
673 end isExpandableConnectorClass;
674
675 function isExternalObject
676 input Class cls;
677 output Boolean isExternalObject = Restriction.isExternalObject(restriction(cls));
678 end isExternalObject;
679
680 function isFunction
681 input Class cls;
682 output Boolean isFunction = Restriction.isFunction(restriction(cls));
683 end isFunction;
684
685 function isEnumeration
686 input Class cls;
687 output Boolean isEnum;
688 algorithm
689 isEnum := match cls
690 case PARTIAL_BUILTIN(ty = Type.ENUMERATION()) then true;
691 case INSTANCED_BUILTIN(ty = Type.ENUMERATION()) then true;
692 8 case EXPANDED_DERIVED() then isEnumeration(InstNode.getClass(cls.baseClass));
693 ✗ case TYPED_DERIVED() then isEnumeration(InstNode.getClass(cls.baseClass));
694 else false;
695 end match;
696 end isEnumeration;
697
698 function isExternalFunction
699 input Class cls;
700 output Boolean isExtFunc;
701 algorithm
702 isExtFunc := match cls
703 local
704 String lang;
705
706 ✗ case EXPANDED_DERIVED() then isExternalFunction(InstNode.getClass(cls.baseClass));
707
3/4
✓ Branch 0 taken 58340 times.
✓ Branch 1 taken 1960 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 58340 times.
60300 case INSTANCED_CLASS(sections = Sections.EXTERNAL(language = lang)) then lang <> "builtin";
708 4 case TYPED_DERIVED() then isExternalFunction(InstNode.getClass(cls.baseClass));
709 else false;
710 end match;
711 end isExternalFunction;
712
713 function isOverdetermined
714 input Class cls;
715 output Boolean isOverdetermined;
716 algorithm
717 try
718 78247 lookupElement("equalityConstraint", cls);
719 // set the external flag that signals the presence of expandable connectors in the model
720 17922 System.setHasOverconstrainedConnectors(true);
721 isOverdetermined := true;
722 else
723 isOverdetermined := false;
724 end try;
725 end isOverdetermined;
726
727 function getPrefixes
728 input Class cls;
729 output Prefixes prefs;
730 algorithm
731 prefs := match cls
732 28790 case PARTIAL_CLASS() then cls.prefixes;
733 9824 case PARTIAL_BUILTIN() then cls.prefixes;
734 1052456 case EXPANDED_CLASS() then cls.prefixes;
735 474644 case EXPANDED_DERIVED() then cls.prefixes;
736 2981015 case INSTANCED_CLASS() then cls.prefixes;
737 4 case TYPED_DERIVED() then getPrefixes(InstNode.getClass(cls.baseClass));
738 else DEFAULT_PREFIXES;
739 end match;
740 end getPrefixes;
741
742 function setPrefixes
743 input Prefixes prefs;
744 input output Class cls;
745 algorithm
746 () := match cls
747 case PARTIAL_CLASS()
748 algorithm
749 ✗ cls.prefixes := prefs;
750 then
751 ();
752
753 case PARTIAL_BUILTIN()
754 algorithm
755 3 cls.prefixes := prefs;
756 then
757 ();
758
759 case EXPANDED_CLASS()
760 algorithm
761 ✗ cls.prefixes := prefs;
762 then
763 ();
764
765 case EXPANDED_DERIVED()
766 algorithm
767 2 cls.prefixes := prefs;
768 then
769 ();
770
771 case INSTANCED_CLASS()
772 algorithm
773 ✗ cls.prefixes := prefs;
774 then
775 ();
776 end match;
777 end setPrefixes;
778
779 function isEncapsulated
780 input Class cls;
781 output Boolean isEncapsulated = Prefixes.isEncapsulated(getPrefixes(cls));
782 end isEncapsulated;
783
784 function isPartial
785 input Class cls;
786 output Boolean isPartial = Prefixes.isPartial(getPrefixes(cls));
787 end isPartial;
788
789 function lastBaseClass
790 input output InstNode node;
791 protected
792 Class cls = InstNode.getClass(node);
793 algorithm
794 node := match cls
795 290138 case EXPANDED_DERIVED() then lastBaseClass(cls.baseClass);
796 4 case TYPED_DERIVED() then lastBaseClass(cls.baseClass);
797 else node;
798 end match;
799 end lastBaseClass;
800
801 function getDerivedComments
802 input Class cls;
803 input output list<SCode.Comment> cmts;
804 algorithm
805 cmts := match cls
806 288 case EXPANDED_DERIVED() then InstNode.getComments(cls.baseClass, cmts);
807 ✗ case TYPED_DERIVED() then InstNode.getComments(cls.baseClass, cmts);
808 else
809 algorithm
810
2/2
✓ Branch 3 taken 14608 times.
✓ Branch 4 taken 38641 times.
91890 for ext in ClassTree.getExtends(classTree(cls)) loop
811 14608 cmts := InstNode.getComments(ext, cmts);
812 end for;
813 then
814 cmts;
815
816 end match;
817 end getDerivedComments;
818
819 function constrainingClassPath
820 "Returns the path of the constraining class for a given class, either the
821 declared constraining class or the path of the class itself if there's no
822 declared constraining class."
823 input InstNode clsNode;
824 output Absyn.Path path;
825 protected
826 InstNode cls_node = lastBaseClass(clsNode);
827 Prefixes prefs = getPrefixes(InstNode.getClass(cls_node));
828 algorithm
829 path := match prefs
830 case Prefixes.PREFIXES(replaceablePrefix = SCode.Replaceable.REPLACEABLE(
831 cc = SOME(SCode.ConstrainClass.CONSTRAINCLASS(constrainingClass = path)))) then path;
832 4 else InstNode.enclosingScopePath(cls_node);
833 end match;
834 end constrainingClassPath;
835
836 function hasOperator
837 input String name;
838 input Class cls;
839 output Boolean hasOperator;
840 protected
841 InstNode op_node;
842 algorithm
843
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 9 times.
11 if Restriction.isOperatorRecord(restriction(cls)) then
844 try
845 2 op_node := lookupElement(name, cls);
846 2 hasOperator := SCodeUtil.isOperator(InstNode.definition(op_node));
847 else
848 hasOperator := false;
849 end try;
850 else
851 hasOperator := false;
852 end if;
853 end hasOperator;
854
855 function makeRecordExp
856 input InstNode clsNode;
857 input InstNode scope;
858 input Boolean typed;
859 output Expression exp;
860 protected
861 Class cls;
862 Type ty;
863 InstNode ty_node;
864 NFInstNode.ScopeRef ty_cell;
865 list<Record.Field> fields;
866 array<InstNode> comps;
867 list<Expression> args;
868 algorithm
869 9915 cls := InstNode.getClass(clsNode);
870
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 9915 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9915 times.
9915 ty as Type.COMPLEX(complexTy = ComplexType.RECORD(constructor = ty_cell)) := getType(cls, clsNode);
871 9915 ty_node := InstNode.borrow(ty_cell);
872 9915 comps := ClassTree.getComponents(classTree(cls));
873
874
2/2
✓ Branch 0 taken 831 times.
✓ Branch 1 taken 9084 times.
9915 if typed then
875 // Create a record expression if the instance has been typed.
876
4/4
✓ Branch 0 taken 1817 times.
✓ Branch 1 taken 756 times.
✓ Branch 3 taken 1817 times.
✓ Branch 4 taken 756 times.
5146 args := list(Binding.getExp(Component.getImplicitBinding(InstNode.component(c), scope)) for c in comps);
877 756 exp := Expression.makeRecord(InstNode.fullPath(ty_node), ty, args);
878 else
879 // Create a record constructor call if the instance hasn't been typed.
880 // Creating a record expression would skip type checking and potentially
881 // lead to issues like missing type casts.
882 args := {};
883
2/2
✓ Branch 1 taken 16056 times.
✓ Branch 2 taken 607 times.
16663 for c in comps loop
884 16056 fields := Record.collectRecordField(c, {});
885
886
3/4
✓ Branch 0 taken 16056 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 15918 times.
✓ Branch 5 taken 138 times.
16056 if not listEmpty(fields) and Record.Field.isInput(listHead(fields)) then
887 15918 args := Binding.getExp(Component.getImplicitBinding(InstNode.component(c), scope)) :: args;
888 end if;
889 end for;
890
891 607 args := listReverseInPlace(args);
892 607 exp := Expression.CALL(Call.UNTYPED_CALL(ComponentRef.fromNode(ty_node, ty), args, {}, InstNode.scopeRef(scope)));
893 end if;
894 end makeRecordExp;
895
896 function toFlatStream
897 input Class cls;
898 input InstNode clsNode;
899 input BaseModelica.OutputFormat format;
900 input String indent;
901 input output IOStream.IOStream s;
902 protected
903 String name;
904 algorithm
905 26 name := Util.makeQuotedIdentifier(AbsynUtil.pathString(InstNode.scopePath(clsNode)));
906
907 s := match cls
908 case INSTANCED_CLASS()
909 algorithm
910 26 s := IOStream.append(s, indent);
911 26 s := IOStream.append(s, Restriction.toString(cls.restriction));
912 26 s := IOStream.append(s, " ");
913 26 s := IOStream.append(s, name);
914 26 s := IOStream.append(s, "\n");
915
916
2/2
✓ Branch 2 taken 69 times.
✓ Branch 3 taken 26 times.
121 for comp in ClassTree.getComponents(cls.elements) loop
917 69 s := IOStream.append(s, InstNode.toFlatString(comp, format, indent + " "));
918 69 s := IOStream.append(s, ";\n");
919 end for;
920
921 26 s := IOStream.append(s, indent);
922 26 s := IOStream.append(s, "end ");
923 26 s := IOStream.append(s, name);
924 then
925 s;
926
927 case INSTANCED_BUILTIN()
928 algorithm
929 ✗ s := IOStream.append(s, indent);
930 ✗ s := IOStream.append(s, "INSTANCED_BUILTIN(");
931 ✗ s := IOStream.append(s, name);
932 ✗ s := IOStream.append(s, ")");
933 then
934 s;
935
936 case TYPED_DERIVED()
937 algorithm
938 ✗ s := IOStream.append(s, indent);
939 ✗ s := IOStream.append(s, Restriction.toString(cls.restriction));
940 ✗ s := IOStream.append(s, " ");
941 ✗ s := IOStream.append(s, name);
942 ✗ s := IOStream.append(s, " = ");
943 ✗ s := IOStream.append(s, Util.makeQuotedIdentifier(AbsynUtil.pathString(InstNode.scopePath(cls.baseClass))));
944 then
945 s;
946
947 ✗ else IOStream.append(s, "UNKNOWN_CLASS(" + name + ")");
948 end match;
949 end toFlatStream;
950
951 function toFlatString
952 input Class cls;
953 input InstNode clsNode;
954 input BaseModelica.OutputFormat format = BaseModelica.defaultFormat;
955 input String indent = "";
956 output String str;
957 protected
958 IOStream.IOStream s;
959 algorithm
960 26 s := IOStream.create(getInstanceName(), IOStream.IOStreamType.LIST());
961 26 s := toFlatStream(cls, clsNode, format, indent, s);
962 26 str := IOStream.string(s);
963 26 IOStream.delete(s);
964 end toFlatString;
965
966 annotation(__OpenModelica_Interface="nf_frontend");
967 end NFClass;
968