Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 87.9% 145 / 0 / 165
Functions: -% 0 / 1 / 1
Branches: 81.5% 75 / 0 / 92

OMCompiler/Compiler/NFFrontEnd/NFComponent.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 NFComponent
37
38 import BaseModelica;
39 import Binding = NFBinding;
40 import Class = NFClass;
41 import NFClassTree.ClassTree;
42 import Dimension = NFDimension;
43 import NFInstNode.InstNode;
44 import NFModifier.Modifier;
45 import SCode.Element;
46 import SCode;
47 import Type = NFType;
48 import Expression = NFExpression;
49 import NFPrefixes.*;
50 import Attributes = NFAttributes;
51
52 protected
53 import Prefixes = NFPrefixes;
54 import SCodeUtil;
55 import Restriction = NFRestriction;
56 import Component = NFComponent;
57 import IOStream;
58 import NFFunction.Function;
59
60 public
61 type ComponentState = enumeration(
62 PartiallyInstantiated "Component instance has been created",
63 FullyInstantiated "All component expressions have been instantiated",
64 Typed "The component's type has been determined",
65 TypeChecked "The component's binding has been typed and type checked"
66 );
67
68 record COMPONENT_DEF
69 SCode.Element definition;
70 Modifier modifier;
71 end COMPONENT_DEF;
72
73 record COMPONENT
74 InstNode classInst;
75 Type ty;
76 Binding binding;
77 Binding condition;
78 Attributes attributes;
79 SCode.Comment comment;
80 ComponentState state;
81 SourceInfo info;
82 end COMPONENT;
83
84 record ITERATOR
85 Type ty;
86 Variability variability;
87 SourceInfo info;
88 end ITERATOR;
89
90 record ENUM_LITERAL
91 Expression literal;
92 SCode.Comment comment;
93 end ENUM_LITERAL;
94
95 record TYPE_ATTRIBUTE
96 Type ty;
97 Modifier modifier;
98 end TYPE_ATTRIBUTE;
99
100 record INVALID_COMPONENT
101 Component component;
102 String errors;
103 end INVALID_COMPONENT;
104
105 record WILD "needed for new crefs in the backend" end WILD;
106
107 function new
108 input SCode.Element definition;
109 output Component component;
110 algorithm
111 269741 component := COMPONENT_DEF(definition, Modifier.NOMOD());
112 end new;
113
114 function newEnum
115 input Type enumType;
116 input String literalName;
117 input SCode.Comment comment;
118 input Integer literalIndex;
119 output Component component;
120 algorithm
121 4468 component := ENUM_LITERAL(Expression.ENUM_LITERAL(enumType, literalName, literalIndex), comment);
122 end newEnum;
123
124 function newIterator
125 input Type iterType;
126 input SourceInfo info;
127 output Component component;
128 algorithm
129 6389 component := ITERATOR(iterType, Variability.IMPLICITLY_DISCRETE, info);
130 end newIterator;
131
132 function definition
133 input Component component;
134 output SCode.Element definition;
135 algorithm
136 ✗ COMPONENT_DEF(definition = definition) := component;
137 end definition;
138
139 function isDefinition
140 input Component component;
141 output Boolean isDefinition;
142 algorithm
143 isDefinition := match component
144 case COMPONENT_DEF() then true;
145 else false;
146 end match;
147 end isDefinition;
148
149 function info
150 "This function shouldn't be used! Use InstNode.info instead, so that e.g.
151 enumeration literals can be handled correctly."
152 input Component component;
153 output SourceInfo info;
154 algorithm
155 info := match component
156 39 case COMPONENT_DEF() then SCodeUtil.elementInfo(component.definition);
157 665577 case COMPONENT() then component.info;
158 3242 case ITERATOR() then component.info;
159 ✗ case TYPE_ATTRIBUTE() then Modifier.info(component.modifier);
160 // Fail for enumeration literals, InstNode.info handles that case instead.
161 end match;
162 end info;
163
164 function classInstance
165 input Component component;
166 output InstNode classInst;
167 algorithm
168 classInst := match component
169 4494809 case COMPONENT() then component.classInst;
170 1 case ITERATOR(ty = Type.COMPLEX()) then Type.complexNode(component.ty);
171 3562 case ITERATOR() then InstNode.ITERATOR_NODE(Expression.EMPTY(component.ty));
172 else InstNode.EMPTY_NODE();
173 end match;
174 end classInstance;
175
176 function setClassInstance
177 input InstNode classInst;
178 input output Component component;
179 algorithm
180 () := match component
181 case COMPONENT()
182 algorithm
183 1648968 component.classInst := classInst;
184 then
185 ();
186
187 end match;
188 end setClassInstance;
189
190 function getModifier
191 input Component component;
192 output Modifier modifier;
193 algorithm
194 modifier := match component
195 5557 case COMPONENT_DEF() then component.modifier;
196 2973339 case TYPE_ATTRIBUTE() then component.modifier;
197 else Modifier.NOMOD();
198 end match;
199 end getModifier;
200
201 function setModifier
202 input Modifier modifier;
203 input output Component component;
204 algorithm
205 () := match component
206 case COMPONENT_DEF()
207 algorithm
208 ✗ component.modifier := modifier;
209 then
210 ();
211 case TYPE_ATTRIBUTE()
212 algorithm
213 ✗ component.modifier := modifier;
214 then
215 ();
216 end match;
217 end setModifier;
218
219 function mergeModifier
220 input Modifier modifier;
221 input output Component component;
222 algorithm
223 component := match component
224 case COMPONENT_DEF()
225 algorithm
226 449244 component.modifier := Modifier.merge(modifier, component.modifier);
227 then
228 component;
229
230 case TYPE_ATTRIBUTE()
231 1378677 then TYPE_ATTRIBUTE(component.ty, Modifier.merge(modifier, component.modifier));
232 end match;
233 end mergeModifier;
234
235 function getType
236 input Component component;
237 output Type ty;
238 protected
239 Type t;
240 algorithm
241 ty := match component
242 case COMPONENT(ty = t as Type.UNTYPED())
243 677709 then Type.liftArrayLeftList(InstNode.getType(component.classInst), arrayList(t.dimensions));
244 1944105 case COMPONENT() then component.ty;
245 5452 case ITERATOR() then component.ty;
246 ✗ case TYPE_ATTRIBUTE() then component.ty;
247 ✗ case INVALID_COMPONENT() then getType(component.component);
248 else Type.UNKNOWN();
249 end match;
250 end getType;
251
252 function setType
253 input Type ty;
254 input output Component component;
255 algorithm
256 component := match component
257 case COMPONENT()
258 algorithm
259 956559 component.ty := ty;
260 then
261 component;
262
263 case ITERATOR()
264 algorithm
265 ✗ component.ty := ty;
266 then
267 component;
268
269 end match;
270 end setType;
271
272 function isTyped
273 input Component component;
274 output Boolean isTyped;
275 algorithm
276 isTyped := match component
277 9246 case COMPONENT() then component.state >= ComponentState.Typed;
278 case ITERATOR(ty = Type.UNKNOWN()) then false;
279 case ITERATOR() then true;
280 case TYPE_ATTRIBUTE() then true;
281 else false;
282 end match;
283 end isTyped;
284
285 function unliftType
286 input output Component component;
287 algorithm
288 () := match component
289 local
290 Type ty;
291
292 case COMPONENT(ty = Type.ARRAY(elementType = ty))
293 algorithm
294 ✗ component.ty := ty;
295 then
296 ();
297
298 case ITERATOR(ty = Type.ARRAY(elementType = ty))
299 algorithm
300 ✗ component.ty := ty;
301 then
302 ();
303
304 else ();
305 end match;
306 end unliftType;
307
308 function getAttributes
309 input Component component;
310 output Attributes attr;
311 algorithm
312 attr := match component
313 201909 case COMPONENT() then component.attributes;
314 else NFAttributes.DEFAULT_ATTR;
315 end match;
316 end getAttributes;
317
318 function setAttributes
319 input Attributes attr;
320 input output Component component;
321 algorithm
322 () := match component
323 case COMPONENT()
324 algorithm
325 101790 component.attributes := attr;
326 then
327 ();
328 end match;
329 end setAttributes;
330
331 function setComment
332 input SCode.Comment comment;
333 input output Component component;
334 algorithm
335 () := match component
336 case COMPONENT()
337 algorithm
338 66 component.comment := comment;
339 then
340 ();
341 end match;
342 end setComment;
343
344 function getBinding
345 input Component component;
346 output Binding b;
347 algorithm
348 b := match component
349 2779593 case COMPONENT() then component.binding;
350 12503728 case TYPE_ATTRIBUTE() then Modifier.binding(component.modifier);
351 case WILD() then Binding.WILD();
352 else NFBinding.EMPTY_BINDING;
353 end match;
354 end getBinding;
355
356 function getImplicitBinding
357 "Returns the component's binding. If the component does not have a binding
358 and is a record instance it will try to create a binding from the
359 component's children."
360 input Component component;
361 input InstNode scope;
362 output Binding binding;
363 protected
364 InstNode cls_node;
365 Expression record_exp;
366 algorithm
367 100835 binding := getBinding(component);
368
369
2/2
✓ Branch 1 taken 66940 times.
✓ Branch 2 taken 33895 times.
100835 if Binding.isUnbound(binding) then
370 66940 cls_node := classInstance(component);
371
372
2/2
✓ Branch 1 taken 57715 times.
✓ Branch 2 taken 9225 times.
66940 if InstNode.isRecord(cls_node) then
373 try
374
2/2
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 9084 times.
9225 if isTyped(component) then
375 141 record_exp := Class.makeRecordExp(cls_node, scope, typed = true);
376 66 binding := Binding.makeTyped(record_exp, NFBinding.EachType.NOT_EACH,
377 NFBinding.Source.GENERATED, info(component));
378 else
379 9084 record_exp := Class.makeRecordExp(cls_node, scope, typed = false);
380 607 binding := Binding.makeUntyped(record_exp, scope, NFBinding.EachType.NOT_EACH,
381 NFBinding.Source.GENERATED, info(component));
382 end if;
383 else
384 end try;
385 end if;
386 end if;
387 end getImplicitBinding;
388
389 function getTypeAttributeBinding
390 input Component component;
391 input String attrName;
392 output Binding binding;
393 protected
394 InstNode start_node;
395 Component start_comp;
396 algorithm
397 try
398 25227 start_node := Class.lookupElement(attrName, InstNode.getClass(classInstance(component)));
399 25216 start_comp := InstNode.component(start_node);
400
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25216 times.
25216 true := Component.isTypeAttribute(start_comp);
401 25216 binding := Component.getBinding(start_comp);
402 else
403 binding := NFBinding.EMPTY_BINDING;
404 end try;
405 end getTypeAttributeBinding;
406
407 function setBinding
408 input Binding binding;
409 input output Component component;
410 algorithm
411 () := match component
412 case COMPONENT()
413 algorithm
414 49098 component.binding := binding;
415 then
416 ();
417
418 case TYPE_ATTRIBUTE()
419 algorithm
420 41847 component.modifier := Modifier.setBinding(binding, component.modifier);
421 then
422 ();
423 end match;
424 end setBinding;
425
426 function hasBinding
427 input Component component;
428 input InstNode parent = InstNode.EMPTY_NODE();
429 output Boolean b;
430 protected
431 Class cls;
432
433 function has_missing_binding
434 input InstNode component;
435 output Boolean noBinding;
436 algorithm
437
3/4
✓ Branch 1 taken 1384 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 548 times.
✓ Branch 6 taken 836 times.
1384 noBinding := InstNode.isComponent(component) and not hasBinding(InstNode.component(component));
438 end has_missing_binding;
439
440 algorithm
441
2/2
✓ Branch 2 taken 16747 times.
✓ Branch 3 taken 37445 times.
54192 if Binding.isBound(getBinding(component)) then
442 // Simple case, component has normal binding equation.
443 b := true;
444 16747 return;
445 end if;
446
447 // Complex case, component might be a record instance where each field has
448 // its own binding equation.
449 37445 cls := InstNode.getClass(classInstance(component));
450
451
2/2
✓ Branch 2 taken 37017 times.
✓ Branch 3 taken 428 times.
37445 if not Restriction.isRecord(Class.restriction(cls)) then
452 // Not record.
453 b := false;
454 37017 return;
455 end if;
456
457 // Check if any child of this component is missing a binding.
458
3/4
✗ Branch 2 not taken.
✓ Branch 3 taken 428 times.
✓ Branch 8 taken 418 times.
✓ Branch 9 taken 10 times.
428 if isSome(ClassTree.findComponent(Class.classTree(cls), has_missing_binding)) then
459 b := false;
460 end if;
461
462 b := true;
463 end hasBinding;
464
465 function getCondition
466 input Component component;
467 output Binding cond;
468 algorithm
469 cond := match component
470 1948179 case COMPONENT() then component.condition;
471 else NFBinding.EMPTY_BINDING;
472 end match;
473 end getCondition;
474
475 function hasCondition
476 input Component component;
477 output Boolean b;
478 algorithm
479 1954092 b := Binding.isBound(getCondition(component));
480 end hasCondition;
481
482 function direction
483 input Component component;
484 output Direction direction;
485 algorithm
486 direction := match component
487 case COMPONENT(attributes = Attributes.ATTRIBUTES(direction = direction)) then direction;
488 else Direction.NONE;
489 end match;
490 end direction;
491
492 function isInput
493 input Component component;
494 output Boolean isInput = direction(component) == Direction.INPUT;
495 end isInput;
496
497 function setDirection
498 input Direction direction;
499 input output Component component;
500 protected
501 Attributes attr;
502 algorithm
503 () := match component
504 case COMPONENT(attributes = attr)
505 algorithm
506 24587 attr.direction := direction;
507 24587 component.attributes := attr;
508 then
509 ();
510
511 else ();
512 end match;
513 end setDirection;
514
515 function isOutput
516 input Component component;
517 output Boolean isOutput = direction(component) == Direction.OUTPUT;
518 end isOutput;
519
520 function parallelism
521 input Component component;
522 output Parallelism parallelism;
523 algorithm
524 parallelism := match component
525 case COMPONENT(attributes = Attributes.ATTRIBUTES(parallelism = parallelism)) then parallelism;
526 else Parallelism.NON_PARALLEL;
527 end match;
528 end parallelism;
529
530 function variability
531 input Component component;
532 output Variability variability;
533 algorithm
534 variability := match component
535 case COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability;
536 29906 case ITERATOR() then component.variability;
537 case ENUM_LITERAL() then Variability.CONSTANT;
538 ✗ case INVALID_COMPONENT() then variability(component.component);
539 else Variability.CONTINUOUS;
540 end match;
541 end variability;
542
543 function setVariability
544 input Variability variability;
545 input output Component component;
546 algorithm
547 () := match component
548 local
549 Attributes attr;
550
551 case COMPONENT(attributes = attr)
552 algorithm
553 58259 attr.variability := variability;
554 58259 component.attributes := attr;
555 then
556 ();
557
558 else ();
559 end match;
560 end setVariability;
561
562 function isConst
563 input Component component;
564 output Boolean isConst = variability(component) == Variability.CONSTANT;
565 end isConst;
566
567 function isParameter
568 input Component component;
569 output Boolean b = variability(component) == Variability.PARAMETER;
570 end isParameter;
571
572 function isStructuralParameter
573 input Component component;
574 output Boolean b = variability(component) == Variability.STRUCTURAL_PARAMETER;
575 end isStructuralParameter;
576
577 function isVar
578 input Component component;
579 output Boolean isVar = variability(component) == Variability.CONTINUOUS;
580 end isVar;
581
582 function isRedeclare
583 input Component component;
584 output Boolean isRedeclare;
585 algorithm
586 isRedeclare := match component
587 255578 case COMPONENT_DEF() then SCodeUtil.isElementRedeclare(component.definition);
588 else false;
589 end match;
590 end isRedeclare;
591
592 function isFinal
593 input Component component;
594 output Boolean isFinal;
595 algorithm
596 isFinal := match component
597 case COMPONENT_DEF()
598 ✗ then SCodeUtil.finalBool(SCodeUtil.prefixesFinal(SCodeUtil.elementPrefixes(component.definition)));
599 case COMPONENT(attributes = Attributes.ATTRIBUTES(isFinal = isFinal)) then isFinal;
600 else false;
601 end match;
602 end isFinal;
603
604 function setFinal
605 input output Component component;
606 input Boolean isFinal;
607 protected
608 Attributes attr;
609 algorithm
610 () := match component
611 case COMPONENT(attributes = attr)
612 algorithm
613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33767 times.
33767 attr.isFinal := isFinal;
614 33767 component.attributes := attr;
615 then
616 ();
617
618 else ();
619 end match;
620 end setFinal;
621
622 function isResizable
623 input Component component;
624 output Boolean b;
625 algorithm
626 b := match component
627 case COMPONENT(attributes = Attributes.ATTRIBUTES(isResizable = b)) then b;
628 else false;
629 end match;
630 end isResizable;
631
632 function innerOuter
633 input Component component;
634 output InnerOuter io;
635 algorithm
636 io := match component
637 case COMPONENT(attributes = Attributes.ATTRIBUTES(innerOuter = io)) then io;
638 case COMPONENT_DEF()
639 2363902 then Prefixes.innerOuterFromSCode(SCodeUtil.prefixesInnerOuter(
640 SCodeUtil.elementPrefixes(component.definition)));
641 else InnerOuter.NOT_INNER_OUTER;
642 end match;
643 end innerOuter;
644
645 function isInnerOuter
646 input Component component;
647 output Boolean isInnerOuter;
648 algorithm
649 ✗ isInnerOuter := innerOuter(component) <> InnerOuter.NOT_INNER_OUTER;
650 end isInnerOuter;
651
652 function isInner
653 input Component component;
654 output Boolean isInner;
655 protected
656 InnerOuter io = innerOuter(component);
657 algorithm
658 2365 isInner := io == InnerOuter.INNER or io == InnerOuter.INNER_OUTER;
659 end isInner;
660
661 function isOuter
662 input Component component;
663 output Boolean isOuter;
664 protected
665 InnerOuter io = innerOuter(component);
666 algorithm
667 952976 isOuter := io == InnerOuter.OUTER or io == InnerOuter.INNER_OUTER;
668 end isOuter;
669
670 function isOnlyOuter
671 input Component component;
672 output Boolean isOuter = innerOuter(component) == InnerOuter.OUTER;
673 end isOnlyOuter;
674
675 function connectorType
676 input Component component;
677 output ConnectorType.Type cty;
678 algorithm
679 cty := match component
680 case COMPONENT(attributes = Attributes.ATTRIBUTES(connectorType = cty)) then cty;
681 else ConnectorType.NON_CONNECTOR;
682 end match;
683 end connectorType;
684
685 function setConnectorType
686 input ConnectorType.Type cty;
687 input output Component component;
688 algorithm
689 () := match component
690 local
691 Attributes attr;
692
693 case COMPONENT(attributes = attr)
694 algorithm
695 72 attr.connectorType := cty;
696 72 component.attributes := attr;
697 then
698 ();
699
700 else ();
701 end match;
702 end setConnectorType;
703
704 function isFlow
705 input Component component;
706 output Boolean isFlow = ConnectorType.isFlow(connectorType(component));
707 end isFlow;
708
709 function isConnector
710 input Component component;
711 output Boolean isConnector = ConnectorType.isConnectorType(connectorType(component));
712 end isConnector;
713
714 function isExpandableConnector
715 input Component component;
716 output Boolean isConnector = ConnectorType.isExpandable(connectorType(component));
717 end isExpandableConnector;
718
719 function isExternalObject
720 input Component component;
721 output Boolean isEO;
722 algorithm
723 isEO := match component
724 40676 case COMPONENT(ty = Type.UNTYPED()) then Class.isExternalObject(InstNode.getClass(component.classInst));
725 1949 case COMPONENT() then Type.isExternalObject(component.ty);
726 else false;
727 end match;
728 end isExternalObject;
729
730 function isIdentical
731 input Component comp1;
732 input Component comp2;
733 output Boolean identical = false;
734 algorithm
735
2/2
✓ Branch 0 taken 32729 times.
✓ Branch 1 taken 42 times.
32771 if referenceEq(comp1, comp2) then
736 identical := true;
737 else
738 identical := match (comp1, comp2)
739 case (COMPONENT(), COMPONENT())
740 algorithm
741
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 32672 times.
32672 if not Class.isIdentical(InstNode.getClass(comp1.classInst),
742 InstNode.getClass(comp2.classInst)) then
743 ✗ return;
744 end if;
745
746
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32672 times.
32672 if not Binding.isEqual(comp1.binding, comp2.binding) then
747 ✗ return;
748 end if;
749 then
750 true;
751
752 else true;
753 end match;
754 end if;
755 end isIdentical;
756
757 function toString
758 input String name;
759 input Component component;
760 output String str;
761 algorithm
762 str := match component
763 local
764 SCode.Element def;
765
766 case COMPONENT_DEF(definition = def as SCode.Element.COMPONENT())
767 ✗ then SCodeDump.unparseElementStr(def);
768
769 case COMPONENT()
770 ✗ then Attributes.toString(component.attributes, component.ty) +
771 Type.toString(component.ty) + " " + name +
772 Binding.toString(component.binding, " = ");
773
774 case TYPE_ATTRIBUTE()
775 92 then name + Modifier.toString(component.modifier, printName = false);
776 end match;
777 end toString;
778
779 function toFlatStream
780 input String name;
781 input Component component;
782 input BaseModelica.OutputFormat format;
783 input String indent;
784 input output IOStream.IOStream s;
785 protected
786 list<tuple<String, Binding>> ty_attrs;
787 list<Dimension> dims;
788 algorithm
789 () := match component
790 case COMPONENT()
791 algorithm
792 108 s := IOStream.append(s, indent);
793 108 s := Attributes.toFlatStream(component.attributes, component.ty, s);
794 108 s := IOStream.append(s, Type.toFlatString(Type.arrayElementType(component.ty), format));
795 108 s := IOStream.append(s, " ");
796 108 s := IOStream.append(s, Util.makeQuotedIdentifier(name));
797
798 108 dims := Type.arrayDims(component.ty);
799
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 82 times.
108 if not listEmpty(dims) then
800 26 s := IOStream.append(s, Dimension.toFlatStringList(dims, format));
801 end if;
802
803
4/4
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 108 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 108 times.
110 ty_attrs := list((Modifier.name(a), Modifier.binding(a)) for a in
804 Class.getTypeAttributes(InstNode.getClass(component.classInst)));
805 108 s := typeAttrsToFlatStream(ty_attrs, component.ty, format, s);
806
807 108 s := IOStream.append(s, Binding.toFlatString(component.binding, format, " = "));
808 then
809 ();
810
811 case TYPE_ATTRIBUTE()
812 algorithm
813 ✗ s := IOStream.append(s, name);
814 ✗ s := IOStream.append(s, Modifier.toFlatString(component.modifier, format, printName = false));
815 then
816 ();
817 end match;
818 end toFlatStream;
819
820 function typeAttrsToFlatStream
821 input list<tuple<String, Binding>> typeAttrs;
822 input Type componentType;
823 input BaseModelica.OutputFormat format;
824 input output IOStream.IOStream s;
825 protected
826 Integer var_dims, binding_dims;
827 list<tuple<String, Binding>> ty_attrs = typeAttrs;
828 String name;
829 Binding binding;
830 Expression bind_exp;
831 algorithm
832
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 30 times.
136 if listEmpty(ty_attrs) then
833 106 return;
834 end if;
835
836 30 s := IOStream.append(s, "(");
837 30 var_dims := Type.dimensionCount(componentType);
838
839 12 while true loop
840 42 (name, binding) := listHead(ty_attrs);
841 42 bind_exp := Expression.expandSplitIndices(Binding.getExp(binding));
842 42 binding_dims := Type.dimensionCount(Expression.typeOf(bind_exp));
843
844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if var_dims > binding_dims then
845 ✗ s := IOStream.append(s, "each ");
846 end if;
847
848 42 s := IOStream.append(s, name);
849 42 s := IOStream.append(s, " = ");
850 42 s := IOStream.append(s, Expression.toFlatString(bind_exp, format));
851
852
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 38 times.
42 if format.showConfidence then
853 4 s := IOStream.append(s, " /* confidence = ");
854 4 s := IOStream.append(s, String(Binding.actualConfidence(binding)));
855 4 s := IOStream.append(s, "*/");
856 end if;
857
858 42 ty_attrs := listRest(ty_attrs);
859
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 30 times.
42 if listEmpty(ty_attrs) then
860 break;
861 else
862 12 s := IOStream.append(s, ", ");
863 end if;
864 end while;
865
866 30 s := IOStream.append(s, ")");
867 end typeAttrsToFlatStream;
868
869 function toFlatString
870 input String name;
871 input Component component;
872 input BaseModelica.OutputFormat format;
873 input String indent = "";
874 output String str;
875 protected
876 IOStream.IOStream s;
877 algorithm
878 108 s := IOStream.create(name, IOStream.IOStreamType.LIST());
879 108 s := toFlatStream(name, component, format, indent, s);
880 108 str := IOStream.string(s);
881 108 IOStream.delete(s);
882 end toFlatString;
883
884 function dimensionCount
885 input Component component;
886 output Integer count;
887 algorithm
888 count := match component
889 722597 case COMPONENT() then Type.dimensionCount(component.ty);
890 else 0;
891 end match;
892 end dimensionCount;
893
894 function comment
895 input Component component;
896 output SCode.Comment comment;
897 algorithm
898 comment := match component
899 ✗ case COMPONENT_DEF() then Util.getOption(SCodeUtil.getElementComment(component.definition));
900 1817938 case COMPONENT() then component.comment;
901 3 case ENUM_LITERAL() then component.comment;
902 else SCode.noComment;
903 end match;
904 end comment;
905
906 function getEvaluateAnnotation
907 input Component component;
908 output Option<Boolean> evaluate;
909 algorithm
910 282775 evaluate := SCodeUtil.getEvaluateAnnotation(comment(component));
911 end getEvaluateAnnotation;
912
913 function isFixed
914 input Component component;
915 output Boolean fixed;
916 protected
917 Binding binding;
918 algorithm
919 // for parameters the default is fixed = true
920
4/4
✓ Branch 1 taken 79 times.
✓ Branch 2 taken 44101 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 58 times.
44180 fixed := isParameter(component) or isStructuralParameter(component);
921
922 44180 binding := Class.lookupAttributeBinding("fixed", InstNode.getClass(classInstance(component)));
923
924 // no fixed attribute present
925
2/2
✓ Branch 1 taken 43561 times.
✓ Branch 2 taken 619 times.
44180 if Binding.isUnbound(binding) then
926 43561 return;
927 end if;
928
929
2/2
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 596 times.
619 if Binding.hasExp(binding) then
930
2/4
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
23 fixed := fixed and Expression.isTrue(Binding.getExp(binding));
931 else
932 fixed := match binding
933 case Binding.RAW_BINDING(bindingExp = Absyn.Exp.BOOL(true))
934 then true;
935 else false;
936 end match;
937 end if;
938 end isFixed;
939
940 function getUnitAttribute
941 input Component component;
942 input String defaultUnit = "";
943 output String unitString;
944 protected
945 Binding binding;
946 Expression unit;
947 algorithm
948 1468 binding := Class.lookupAttributeBinding("unit", InstNode.getClass(classInstance(component)));
949
950
2/2
✓ Branch 1 taken 1095 times.
✓ Branch 2 taken 373 times.
1468 if Binding.isUnbound(binding) then
951 unitString := defaultUnit;
952 1095 return;
953 end if;
954
955 373 unit := Binding.getExp(binding);
956
957 unitString := match unit
958 164 case Expression.STRING() then unit.value;
959 else defaultUnit;
960 end match;
961 end getUnitAttribute;
962
963 function isDeleted
964 input Component component;
965 output Boolean isDeleted;
966 algorithm
967 isDeleted := match component
968 local
969 Binding condition;
970
971 case COMPONENT(condition = condition)
972
4/4
✓ Branch 1 taken 18448 times.
✓ Branch 2 taken 1194116 times.
✓ Branch 5 taken 11084 times.
✓ Branch 6 taken 7364 times.
1212564 then Binding.isTyped(condition) and Expression.isFalse(Binding.getTypedExp(condition));
973
974 else false;
975 end match;
976 end isDeleted;
977
978 function isInvalid
979 input Component component;
980 output Boolean invalid;
981 algorithm
982 invalid := match component
983 case INVALID_COMPONENT() then true;
984 else false;
985 end match;
986 end isInvalid;
987
988 function isIterator
989 input Component component;
990 output Boolean iterator;
991 algorithm
992 iterator := match component
993 case ITERATOR() then true;
994 else false;
995 end match;
996 end isIterator;
997
998 function isTypeAttribute
999 input Component component;
1000 output Boolean isAttribute;
1001 algorithm
1002 isAttribute := match component
1003 case TYPE_ATTRIBUTE() then true;
1004 else false;
1005 end match;
1006 end isTypeAttribute;
1007
1008 function countConnectorVars
1009 "Returns the number of potential (neither constant, parameter, input, nor
1010 output), flow, and stream variables in the given connector."
1011 input Component component;
1012 input Boolean isRoot = true;
1013 output Integer potentials = 0;
1014 output Integer flows = 0;
1015 output Integer streams = 0;
1016 output Boolean knownSize = true;
1017 protected
1018 Type ty;
1019 ConnectorType.Type cty;
1020 Class cls;
1021 Option<InstNode> eq_node_opt;
1022 InstNode eq_node;
1023 Integer comp_size = 0, p, f, s;
1024 Function fn;
1025 Boolean known_size;
1026 algorithm
1027 58162 cls := InstNode.getClass(classInstance(component));
1028 58162 eq_node_opt := Class.tryLookupElement("equalityConstraint", cls);
1029
1030
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 58162 times.
✓ Branch 2 taken 2775 times.
✓ Branch 3 taken 55387 times.
✓ Branch 7 taken 2775 times.
✗ Branch 8 not taken.
58162 if isSome(eq_node_opt) and
1031 SCodeUtil.isFunction(InstNode.definition(Util.getOption(eq_node_opt))) then
1032 // If the type contains an equalityConstraint function then the size is
1033 // determined by the return type of it.
1034
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2775 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2775 times.
2775 SOME(eq_node) := eq_node_opt;
1035 2775 Function.instFunctionNode(eq_node, NFInstContext.NO_CONTEXT, info(component));
1036 2775 fn := listHead(Function.typeNodeCache(eq_node));
1037 2775 ty := Function.returnType(fn);
1038
1039
1/2
✓ Branch 1 taken 2775 times.
✗ Branch 2 not taken.
2775 if Type.hasKnownSize(ty) then
1040 2775 comp_size := Type.sizeOf(ty);
1041 else
1042 comp_size := 0;
1043 knownSize := false;
1044 end if;
1045 else
1046 55387 ty := getType(component);
1047
1048 // Ignore dimensions for the root connector, i.e. an array of connectors
1049 // is treated as a scalar when balance checking it.
1050
2/2
✓ Branch 0 taken 36391 times.
✓ Branch 1 taken 18996 times.
55387 if isRoot then
1051 comp_size := 1;
1052 elseif Type.hasKnownSize(ty) then
1053 36390 comp_size := Dimension.sizesProduct(Type.arrayDims(ty), false);
1054 else
1055 comp_size := 0;
1056 knownSize := false;
1057 end if;
1058
1059 55387 ty := Type.arrayElementType(ty);
1060
2/2
✓ Branch 1 taken 15342 times.
✓ Branch 2 taken 40045 times.
55387 if Type.isComplex(ty) then
1061 // For complex types we only count elements in records, not in e.g. connectors.
1062 // (unless it's the connector that we're trying to count the variables in).
1063
4/4
✓ Branch 1 taken 14098 times.
✓ Branch 2 taken 1244 times.
✓ Branch 3 taken 12857 times.
✓ Branch 4 taken 1241 times.
15342 if Type.isRecord(ty) or isRoot then
1064
2/2
✓ Branch 3 taken 39166 times.
✓ Branch 4 taken 14101 times.
67368 for c in ClassTree.getComponents(Class.classTree(cls)) loop
1065 39166 (p, f, s, known_size) := countConnectorVars(InstNode.component(c), false);
1066 39166 potentials := potentials + p * comp_size;
1067 39166 flows := flows + f * comp_size;
1068 39166 streams := streams + s * comp_size;
1069
3/4
✓ Branch 0 taken 39165 times.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 39165 times.
39166 knownSize := known_size and knownSize;
1070 end for;
1071 end if;
1072
1073 // Complex elements are not counted themselves.
1074 comp_size := 0;
1075 end if;
1076 end if;
1077
1078
2/2
✓ Branch 0 taken 16084 times.
✓ Branch 1 taken 42078 times.
58162 if comp_size > 0 then
1079 42078 cty := connectorType(component);
1080
1081
2/2
✓ Branch 1 taken 14662 times.
✓ Branch 2 taken 27416 times.
42078 if ConnectorType.isFlow(cty) then
1082 14662 flows := flows + comp_size;
1083 elseif ConnectorType.isStream(cty) then
1084 454 streams := streams + comp_size;
1085 elseif variability(component) >= Variability.DISCRETE and
1086 direction(component) == Direction.NONE then
1087 16642 potentials := potentials + comp_size;
1088 end if;
1089 end if;
1090 end countConnectorVars;
1091
1092 annotation(__OpenModelica_Interface="nf_frontend");
1093 end NFComponent;
1094