Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 65.5% 116 / 0 / 177
Functions: -% 0 / 1 / 1
Branches: 58.4% 90 / 0 / 154

OMCompiler/Compiler/NFFrontEnd/NFVariable.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 NFVariable
37 import Attributes = NFAttributes;
38 import Binding = NFBinding;
39 import Class = NFClass;
40 import Component = NFComponent;
41 import ComponentRef = NFComponentRef;
42 import Dimension = NFDimension;
43 import Equation = NFEquation;
44 import Expression = NFExpression;
45 import NFInstNode.InstNode;
46 import NFPrefixes.Visibility;
47 import NFPrefixes.Variability;
48 import NFPrefixes.ConnectorType;
49 import NFPrefixes.Direction;
50 import NFPrefixes.AccessLevel;
51 import Type = NFType;
52 import NFBackendExtension.{BackendInfo, VariableKind, VariableAttributes};
53 import BaseModelica;
54
55 protected
56 import Absyn;
57 import Ceval = NFCeval;
58 import ExpandExp = NFExpandExp;
59 import FlatModelicaUtil = NFFlatModelicaUtil;
60 import Inst = NFInst;
61 import IOStream;
62 import MetaModelica.Dangerous.listReverseInPlace;
63 import SCode;
64 import StringUtil;
65 import Typing = NFTyping;
66 import Util;
67 import Variable = NFVariable;
68
69 public
70 record VARIABLE
71 ComponentRef name;
72 Type ty;
73 Binding binding;
74 Visibility visibility;
75 Attributes attributes;
76 list<tuple<String, Binding>> typeAttributes;
77 list<Variable> children;
78 SCode.Comment comment;
79 SourceInfo info;
80 BackendInfo backendinfo "NFBackendExtension.DUMMY_BACKEND_INFO for all of frontend. Only used in Backend.";
81 end VARIABLE;
82
83 function fromCref
84 "creates a variable from a component reference.
85 Note: does not flatten, do not use for instantiated elements!"
86 input ComponentRef cref;
87 output Variable variable;
88 protected
89 InstNode node, class_node;
90 Component comp;
91 Type ty;
92 Binding binding;
93 Visibility vis;
94 Attributes attr;
95 SCode.Comment cmt;
96 SourceInfo info;
97 BackendInfo binfo = NFBackendExtension.DUMMY_BACKEND_INFO;
98 array<InstNode> child_nodes;
99 Type elem_ty;
100 list<Variable> children = {};
101 algorithm
102 8221 node := ComponentRef.node(cref);
103 8221 comp := InstNode.component(node);
104 8221 ty := ComponentRef.getSubscriptedType(cref);
105 8221 vis := InstNode.visibility(node);
106 8221 attr := Component.getAttributes(comp);
107 8221 cmt := Component.comment(comp);
108 8221 info := InstNode.info(node);
109
110 // kabdelhak: add dummy backend info, will be changed to actual value in
111 // conversion to backend process (except for iterators). NBackendDAE.lower
112
2/2
✓ Branch 1 taken 5553 times.
✓ Branch 2 taken 2668 times.
8221 if ComponentRef.isIterator(cref) then
113 binding := NFBinding.EMPTY_BINDING;
114 5553 binfo.varKind := VariableKind.ITERATOR();
115 else
116 2668 binding := Component.getImplicitBinding(comp, InstNode.instanceParent(node));
117 end if;
118
119 // get the record children if the variable is a record
120
1/2
✓ Branch 1 taken 8221 times.
✗ Branch 2 not taken.
8221 if not Type.isExternalObject(ty) then
121 children := match Type.arrayElementType(ty)
122 case elem_ty as Type.COMPLEX() algorithm
123 ✗ class_node := Type.complexNode(elem_ty);
124 ✗ child_nodes := Class.getComponents(InstNode.getClass(class_node));
125 ✗ children := list(fromCref(ComponentRef.prefixCref(c, InstNode.getType(c), {}, cref)) for c in child_nodes);
126 then children;
127 else {};
128 end match;
129 end if;
130
131 8221 variable := VARIABLE(cref, ty, binding, vis, attr, {}, children, cmt, info, binfo);
132 end fromCref;
133
134 function name
135 input Variable var;
136 output ComponentRef name = var.name;
137 end name;
138
139 function size
140 input Variable var;
141 input Boolean resize = false;
142 output Integer s = Type.sizeOf(var.ty, resize);
143 end size;
144
145 function hash
146 input Variable var;
147 output Integer i = ComponentRef.hash(var.name);
148 end hash;
149
150 function equalName
151 input Variable var1;
152 input Variable var2;
153 output Boolean b = ComponentRef.isEqual(var1.name, var2.name);
154 end equalName;
155
156 function expand
157 "Expands an array variable into its scalar elements."
158 input Variable var;
159 input Boolean backend = false;
160 output list<Variable> vars;
161 protected
162 list<ComponentRef> crefs;
163 Variable v;
164 Binding binding;
165 Variability bind_var;
166 Binding.Source bind_src;
167 Expression bind_exp, exp;
168 list<Expression> expl;
169 Integer crefs_len, expl_len;
170 algorithm
171 ✗ if Type.isArray(var.ty) then
172 // Expand the name.
173 ✗ exp := Expression.fromCref(var.name);
174 ✗ exp := ExpandExp.expandCref(exp, backend);
175 ✗ expl := Expression.arrayScalarElements(exp);
176 ✗ crefs := list(Expression.toCref(e) for e in expl);
177
178 v := var;
179 ✗ v.ty := Type.arrayElementType(v.ty);
180 vars := {};
181 ✗ binding := var.binding;
182
183 // If the variable has a binding we need to expand it too.
184 ✗ if Binding.isBound(binding) then
185 ✗ bind_exp := Binding.getTypedExp(binding);
186 ✗ expl := Expression.arrayScalarElements(ExpandExp.expand(bind_exp));
187
188 ✗ crefs_len := listLength(crefs);
189 ✗ expl_len := listLength(expl);
190
191 // If the binding has fewer dimensions than the variable, 'multiply' the
192 // list of binding expression until they match.
193 ✗ if expl_len < crefs_len then
194 ✗ if intMod(crefs_len, expl_len) <> 0 then
195 ✗ Error.terminate(getInstanceName() + " failed to expand " +
196 ComponentRef.toString(var.name), sourceInfo());
197 end if;
198
199 ✗ expl := List.flatten(List.fill(expl, intDiv(crefs_len, expl_len)));
200 end if;
201
202 ✗ bind_var := Binding.variability(binding);
203 ✗ bind_src := Binding.source(binding);
204
205 ✗ for cr in crefs loop
206 ✗ v.name := cr;
207 ✗ exp :: expl := expl;
208 ✗ v.binding := Binding.makeFlat(exp, bind_var, bind_src);
209 vars := v :: vars;
210 end for;
211 else
212 ✗ for cr in crefs loop
213 ✗ v.name := cr;
214 vars := v :: vars;
215 end for;
216 end if;
217 ✗ vars := listReverseInPlace(vars);
218 else
219 vars := {var};
220 end if;
221 end expand;
222
223 function expandChildren
224 "Expands a variable into itself and its children if its complex."
225 input Variable var;
226 input list<Dimension> arrayDims = {};
227 input Boolean addDimensions = true;
228 output list<Variable> children;
229 protected
230 list<Dimension> newArrayDims;
231 algorithm
232 // add dimensions of surrounding record
233
4/4
✓ Branch 0 taken 6708 times.
✓ Branch 1 taken 165 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 6680 times.
6873 if addDimensions and not listEmpty(arrayDims) then
234 28 var.ty := Type.liftArrayLeftList(var.ty, arrayDims);
235 end if;
236 6873 newArrayDims := Type.arrayDims(var.ty);
237
238 // return all children and the variable itself
239
4/4
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 6873 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 6873 times.
7325 children := var :: List.flatten(list(expandChildren(v, newArrayDims, addDimensions) for v in var.children));
240 end expandChildren;
241
242 function typeOf
243 input Variable var;
244 output Type ty = var.ty;
245 end typeOf;
246
247 function attributes
248 input Variable variable;
249 output Attributes attributes = variable.attributes;
250 end attributes;
251
252 function variability
253 input Variable variable;
254 output Variability variability = variable.attributes.variability;
255 end variability;
256
257 function setVariability
258 input output Variable variable;
259 input Variability variability;
260 protected
261 Attributes attr;
262 algorithm
263 1168 attr := variable.attributes;
264 1168 attr.variability := variability;
265 1168 variable.attributes := attr;
266 end setVariability;
267
268 function visibility
269 input Variable variable;
270 output Visibility visibility = variable.visibility;
271 end visibility;
272
273 function isComplex
274 input Variable var;
275 output Boolean b = Type.isComplex(var.ty);
276 end isComplex;
277
278 function isComplexArray
279 input Variable var;
280 output Boolean b = Type.isComplexArray(var.ty);
281 end isComplexArray;
282
283 function isStructural
284 input Variable variable;
285 output Boolean structural =
286 variable.attributes.variability <= Variability.STRUCTURAL_PARAMETER;
287 end isStructural;
288
289 function isEmptyArray
290 input Variable variable;
291 output Boolean isEmpty = Type.isEmptyArray(variable.ty);
292 end isEmptyArray;
293
294 function isDeleted
295 input Variable variable;
296 output Boolean deleted;
297 protected
298 InstNode node;
299 algorithm
300 ✗ node := ComponentRef.node(variable.name);
301 ✗ deleted := InstNode.isComponent(node) and Component.isDeleted(InstNode.component(node));
302 end isDeleted;
303
304 function isPresent
305 input Variable variable;
306 output Boolean present = not ConnectorType.isPotentiallyPresent(variable.attributes.connectorType);
307 end isPresent;
308
309 function isPotential
310 input Variable variable;
311 output Boolean potential = ConnectorType.isPotential(variable.attributes.connectorType);
312 end isPotential;
313
314 function isFlow
315 input Variable variable;
316 output Boolean potential = ConnectorType.isFlow(variable.attributes.connectorType);
317 end isFlow;
318
319 function isStream
320 input Variable variable;
321 output Boolean potential = ConnectorType.isStream(variable.attributes.connectorType);
322 end isStream;
323
324 function isInput
325 input Variable variable;
326 output Boolean b = variable.attributes.direction == Direction.INPUT;
327 end isInput;
328
329 function isOutput
330 input Variable variable;
331 output Boolean b = variable.attributes.direction == Direction.OUTPUT;
332 end isOutput;
333
334 function isTopLevelInput
335 input Variable variable;
336 output Boolean topInput = ComponentRef.isTopLevel(variable.name) and
337 variable.attributes.direction == Direction.INPUT;
338 end isTopLevelInput;
339
340 function isPublic
341 input Variable variable;
342 output Boolean isPublic = variable.visibility == Visibility.PUBLIC;
343 end isPublic;
344
345 function isProtected
346 input Variable variable;
347 output Boolean isProtected = variable.visibility == Visibility.PROTECTED;
348 end isProtected;
349
350 function isEncrypted
351 input Variable variable;
352 output Boolean isEncrypted = isEncryptedName(variable.name);
353 end isEncrypted;
354
355 function isEncryptedName
356 "Whether any part of the name is declared in an encrypted file."
357 input ComponentRef name;
358 output Boolean isEncrypted = false;
359 protected
360 ComponentRef cr = name;
361 algorithm
362
2/2
✓ Branch 1 taken 230056 times.
✓ Branch 2 taken 85908 times.
315964 while ComponentRef.isCref(cr) loop
363
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 230056 times.
230056 if isEncryptedNode(ComponentRef.node(cr)) then
364 isEncrypted := true;
365 ✗ return;
366 end if;
367
368 230056 cr := ComponentRef.rest(cr);
369 end while;
370 end isEncryptedName;
371
372 function isEncryptedNode
373 input InstNode node;
374 output Boolean isEncrypted;
375 protected
376 SourceInfo info = InstNode.info(node);
377 algorithm
378 603365 isEncrypted := StringUtil.endsWith(info.fileName, ".moc");
379 end isEncryptedNode;
380
381 function isAccessible
382 input Variable variable;
383 output Boolean isAccessible;
384 protected
385 Option<AccessLevel> oaccess;
386 AccessLevel access;
387 algorithm
388 12330 oaccess := InstNode.getAccessLevel(ComponentRef.node(variable.name));
389
390
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12330 times.
✓ Branch 2 taken 12330 times.
✗ Branch 3 not taken.
12330 if isSome(oaccess) then
391 ✗ SOME(access) := oaccess;
392 else
393
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12330 times.
12330 access := if isEncrypted(variable) then AccessLevel.DOCUMENTATION else AccessLevel.PACKAGE_DUPLICATE;
394 end if;
395
396 ✗ if access < AccessLevel.ICON then
397 isAccessible := false;
398 elseif access < AccessLevel.NON_PACKAGE_TEXT then
399 ✗ isAccessible := not isProtected(variable);
400 else
401 isAccessible := true;
402 end if;
403 end isAccessible;
404
405 function isFixed
406 input Variable var;
407 output Boolean fixed;
408 protected
409 Binding binding;
410 algorithm
411 2 fixed := if var.attributes.variability < Variability.DISCRETE then true else false;
412 2 binding := lookupTypeAttribute("fixed", var);
413
414
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if Binding.hasExp(binding) then
415 2 fixed := Expression.isTrue(Binding.getExp(binding));
416 end if;
417 end isFixed;
418
419 function lookupTypeAttribute
420 input String name;
421 input Variable var;
422 output Binding binding;
423 algorithm
424
2/2
✓ Branch 0 taken 60861 times.
✓ Branch 1 taken 26274 times.
87135 for attr in var.typeAttributes loop
425
4/4
✓ Branch 1 taken 34726 times.
✓ Branch 2 taken 26135 times.
✓ Branch 5 taken 32863 times.
✓ Branch 6 taken 1863 times.
60861 if Util.tuple21(attr) == name then
426 32863 binding := Util.tuple22(attr);
427 32863 return;
428 end if;
429 end for;
430
431 binding := NFBinding.EMPTY_BINDING;
432 end lookupTypeAttribute;
433
434 function applyToType
435 input output Variable var;
436 input typeFunc func;
437 partial function typeFunc
438 input output Type ty;
439 end typeFunc;
440 algorithm
441
1/2
✓ Branch 0 taken 8348 times.
✗ Branch 1 not taken.
8348 var.ty := func(var.ty);
442 var.name := ComponentRef.applyToType(var.name, func);
443 end applyToType;
444
445 function propagateAnnotation
446 input String name;
447 input Boolean overwrite;
448 input Boolean evaluate = false;
449 input output Variable var;
450 protected
451 InstNode node;
452 SCode.Mod mod;
453 Absyn.Exp aexp;
454 Expression exp;
455 protected
456 SCode.Annotation anno;
457 InstNode scope;
458 algorithm
459
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 378211 times.
378211 if ComponentRef.isCref(var.name) then
460 378211 node := ComponentRef.node(var.name);
461 // InstNode.getAnnotation is recursive and returns the first annotation found.
462 // if the original is supposed to be overwritten, skip the node itself and look at the parent
463
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 378211 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
378211 if overwrite and InstNode.isComponent(node) then
464 ✗ node := InstNode.parent(node);
465 end if;
466
467 378211 (mod, scope) := InstNode.getAnnotation(name, node);
468
469
2/2
✓ Branch 1 taken 373438 times.
✓ Branch 2 taken 4773 times.
378211 if not SCodeUtil.isEmptyMod(mod) then
470
1/2
✓ Branch 0 taken 4773 times.
✗ Branch 1 not taken.
4773 if evaluate then
471 () := matchcontinue mod
472 case SCode.Mod.MOD(binding = SOME(aexp))
473 algorithm
474 4773 exp := Inst.instExp(aexp, scope, NFInstContext.ANNOTATION, mod.info);
475 4773 exp := Typing.typeExp(exp, NFInstContext.ANNOTATION, mod.info);
476 4773 exp := Ceval.evalExp(exp);
477 9546 mod.binding := SOME(Expression.toAbsyn(exp));
478 then
479 ();
480
481 else ();
482 end matchcontinue;
483 end if;
484
485 9546 anno := SCode.ANNOTATION(modification = SCode.MOD(
486 finalPrefix = SCode.NOT_FINAL(),
487 eachPrefix = SCode.NOT_EACH(),
488 subModLst = {SCode.SubMod.NAMEMOD(name, mod)},
489 binding = NONE(),
490 comment = NONE(),
491 info = sourceInfo()));
492 4773 var.comment := SCodeUtil.appendAnnotationToComment(anno, var.comment, true);
493 end if;
494 end if;
495 end propagateAnnotation;
496
497 function removeNonTopLevelDirection
498 "Removes input/output prefixes from a variable that's not a top-level
499 component, a component in a top-level connector, or a component in a
500 top-level input component."
501 input output Variable var;
502 protected
503 ComponentRef rest_name;
504 InstNode node;
505 Attributes attr;
506 algorithm
507
2/2
✓ Branch 0 taken 290160 times.
✓ Branch 1 taken 88058 times.
378218 if var.attributes.direction == Direction.NONE then
508 290160 return;
509 end if;
510
511 88058 rest_name := ComponentRef.rest(var.name);
512
2/2
✓ Branch 1 taken 115865 times.
✓ Branch 2 taken 387 times.
116252 while not ComponentRef.isEmpty(rest_name) loop
513 115865 node := ComponentRef.node(rest_name);
514
515
4/4
✓ Branch 1 taken 113019 times.
✓ Branch 2 taken 2846 times.
✓ Branch 4 taken 87671 times.
✓ Branch 5 taken 25348 times.
115865 if not (InstNode.isConnector(node) or InstNode.isInput(node)) then
516 87671 attr := var.attributes;
517 87671 attr.direction := Direction.NONE;
518 87671 var.attributes := attr;
519 87671 return;
520 end if;
521
522 28194 rest_name := ComponentRef.rest(rest_name);
523 end while;
524 end removeNonTopLevelDirection;
525
526 partial function ApplyFn
527 input Expression exp;
528 end ApplyFn;
529
530 function applyExp
531 input Variable var;
532 input ApplyFn fn;
533 algorithm
534 ✗ Binding.applyExp(var.binding, fn);
535
536 ✗ for ty_attr in var.typeAttributes loop
537 ✗ Binding.applyExp(Util.tuple22(ty_attr), fn);
538 end for;
539
540 ✗ for c in var.children loop
541 ✗ applyExp(c, fn);
542 end for;
543 end applyExp;
544
545 function applyExpShallow
546 input Variable var;
547 input ApplyFn fn;
548 algorithm
549 241182 Binding.applyExpShallow(var.binding, fn);
550
551
2/2
✓ Branch 0 taken 471577 times.
✓ Branch 1 taken 241182 times.
712759 for ty_attr in var.typeAttributes loop
552 471577 Binding.applyExpShallow(Util.tuple22(ty_attr), fn);
553 end for;
554
555
2/2
✓ Branch 0 taken 445 times.
✓ Branch 1 taken 241182 times.
241627 for c in var.children loop
556 445 applyExpShallow(c, fn);
557 end for;
558 end applyExpShallow;
559
560 partial function MapFn
561 input output Expression exp;
562 end MapFn;
563
564 function mapExp
565 input output Variable var;
566 input MapFn fn;
567 algorithm
568
8/8
✓ Branch 1 taken 29054 times.
✓ Branch 2 taken 21691 times.
✓ Branch 3 taken 29054 times.
✓ Branch 4 taken 21691 times.
✓ Branch 9 taken 1231 times.
✓ Branch 10 taken 21691 times.
✓ Branch 11 taken 1231 times.
✓ Branch 12 taken 21691 times.
51976 var.binding := Binding.mapExp(var.binding, fn);
569 var.typeAttributes := list(
570 (Util.tuple21(a), Binding.mapExp(Util.tuple22(a), fn)) for a in var.typeAttributes);
571 var.children := list(mapExp(v, fn) for v in var.children);
572 var.backendinfo := BackendInfo.map(var.backendinfo, fn);
573 var.ty := Type.applyToDims(var.ty, func = function Dimension.mapExp(func = fn));
574 var.name := ComponentRef.mapTypes(var.name, function Type.applyToDims(func = function Dimension.mapExp(func = fn)));
575 end mapExp;
576
577 function mapExpShallow
578 input output Variable var;
579 input MapFn fn;
580 algorithm
581
8/8
✓ Branch 1 taken 1318825 times.
✓ Branch 2 taken 762826 times.
✓ Branch 3 taken 1318825 times.
✓ Branch 4 taken 762826 times.
✓ Branch 9 taken 445 times.
✓ Branch 10 taken 762826 times.
✓ Branch 11 taken 445 times.
✓ Branch 12 taken 762826 times.
2082096 var.binding := Binding.mapExpShallow(var.binding, fn);
582 var.typeAttributes := list(
583 (Util.tuple21(a), Binding.mapExpShallow(Util.tuple22(a), fn)) for a in var.typeAttributes);
584 var.children := list(mapExpShallow(v, fn) for v in var.children);
585 end mapExpShallow;
586
587 function toString
588 input Variable var;
589 input String indent = "";
590 input Boolean printBindingType = false;
591 output String str;
592 protected
593 IOStream.IOStream s;
594 algorithm
595 1086 s := IOStream.create(getInstanceName(), IOStream.IOStreamType.LIST());
596 1086 s := toStream(var, indent, printBindingType, s);
597 1086 str := IOStream.string(s);
598 1086 IOStream.delete(s);
599 end toString;
600
601 function toStream
602 input Variable var;
603 input String indent = "";
604 input Boolean printBindingType = false;
605 input output IOStream.IOStream s;
606 protected
607 Boolean first;
608 Binding b;
609 algorithm
610 1118 s := IOStream.append(s, indent);
611
612
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1118 times.
1118 if var.visibility == Visibility.PROTECTED then
613 ✗ s := IOStream.append(s, "protected ");
614 end if;
615
616 1118 s := IOStream.append(s, Attributes.toString(var.attributes, var.ty));
617 1118 s := IOStream.append(s, Type.toString(var.ty));
618 1118 s := IOStream.append(s, " ");
619 1118 s := IOStream.append(s, ComponentRef.toString(var.name));
620
621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1118 times.
1118 if not listEmpty(var.typeAttributes) then
622 ✗ s := IOStream.append(s, "(");
623
624 first := true;
625 ✗ for a in var.typeAttributes loop
626 ✗ if first then
627 first := false;
628 else
629 ✗ s := IOStream.append(s, ", ");
630 end if;
631
632 ✗ b := Util.tuple22(a);
633
634 ✗ if Binding.isEach(b) then
635 ✗ s := IOStream.append(s, "each ");
636 end if;
637
638 ✗ s := IOStream.append(s, Util.tuple21(a));
639 ✗ s := IOStream.append(s, " = ");
640 ✗ s := IOStream.append(s, Binding.toString(b));
641 end for;
642
643 ✗ s := IOStream.append(s, ")");
644 end if;
645
646
2/2
✓ Branch 1 taken 1117 times.
✓ Branch 2 taken 1 time.
1118 if Binding.isBound(var.binding) then
647 1 s := IOStream.append(s, " = ");
648
649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if printBindingType then
650 ✗ s := IOStream.append(s, "(");
651 ✗ s := IOStream.append(s, Type.toString(Binding.getType(var.binding)));
652 ✗ s := IOStream.append(s, ") ");
653 end if;
654
655 1 s := IOStream.append(s, Binding.toString(var.binding));
656 end if;
657 end toStream;
658
659 function toFlatStream
660 input Variable var;
661 input BaseModelica.OutputFormat format;
662 input String indent = "";
663 input Boolean printBindingType = false;
664 input output IOStream.IOStream s;
665 protected
666 list<Dimension> dims;
667 algorithm
668 847 s := IOStream.append(s, indent);
669
670 847 s := Attributes.toFlatStream(var.attributes, var.ty, s, ComponentRef.isSimple(var.name));
671 847 s := IOStream.append(s, Type.toFlatString(Type.arrayElementType(var.ty), format));
672 847 s := IOStream.append(s, " ");
673 847 s := IOStream.append(s, ComponentRef.toFlatString(var.name, format));
674
675 847 dims := Type.arrayDims(var.ty);
676
2/2
✓ Branch 0 taken 197 times.
✓ Branch 1 taken 650 times.
847 if not listEmpty(dims) then
677 197 s := IOStream.append(s, Dimension.toFlatStringList(dims, format));
678 end if;
679
680
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 824 times.
847 if not listEmpty(var.typeAttributes) then
681 23 s := Component.typeAttrsToFlatStream(var.typeAttributes, var.ty, format, s);
682 elseif not listEmpty(var.children) then
683
3/4
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 26 times.
✓ Branch 4 taken 89 times.
141 s := toFlatStreamModifier(var.children, format.moveBindings or Binding.isBound(var.binding), printBindingType, format, s);
684 end if;
685
686 847 s := toFlatStreamBinding(var.binding, printBindingType, format, s);
687 847 s := FlatModelicaUtil.appendComment(var.comment, NFFlatModelicaUtil.ElementType.COMPONENT, s);
688 end toFlatStream;
689
690 function toFlatStreamBinding
691 input Binding binding;
692 input Boolean printBindingType;
693 input BaseModelica.OutputFormat format;
694 input output IOStream.IOStream s;
695 algorithm
696
2/2
✓ Branch 1 taken 655 times.
✓ Branch 2 taken 205 times.
860 if Binding.isBound(binding) then
697 205 s := IOStream.append(s, " = ");
698
699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 205 times.
205 if printBindingType then
700 ✗ s := IOStream.append(s, "(");
701 ✗ s := IOStream.append(s, Type.toFlatString(Binding.getType(binding), format));
702 ✗ s := IOStream.append(s, ") ");
703 end if;
704
705 205 s := IOStream.append(s, Binding.toFlatString(binding, format));
706 end if;
707 end toFlatStreamBinding;
708
709 function toFlatStreamModifier
710 input list<Variable> children;
711 input Boolean overwrittenBinding;
712 input Boolean printBindingType;
713 input BaseModelica.OutputFormat format;
714 input output IOStream.IOStream s;
715 protected
716 Boolean empty = true;
717 Boolean overwritten_binding;
718 IOStream.IOStream ss;
719 Binding.Source src;
720 algorithm
721
2/2
✓ Branch 0 taken 394 times.
✓ Branch 1 taken 133 times.
527 for child in children loop
722 394 ss := IOStream.create(getInstanceName(), IOStream.IOStreamType.LIST());
723
724
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 389 times.
394 if not listEmpty(child.typeAttributes) then
725 5 ss := Component.typeAttrsToFlatStream(child.typeAttributes, child.ty, format, ss);
726 elseif not listEmpty(child.children) then
727
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
18 overwritten_binding := overwrittenBinding or Binding.isBound(child.binding);
728 18 ss := toFlatStreamModifier(child.children, overwritten_binding, printBindingType, format, ss);
729 end if;
730
731
2/2
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 96 times.
394 if not overwrittenBinding then
732 298 src := Binding.source(child.binding);
733
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 285 times.
298 if src == NFBinding.Source.MODIFIER or src == NFBinding.Source.GENERATED then
734 13 ss := toFlatStreamBinding(child.binding, printBindingType, format, ss);
735 end if;
736 end if;
737
738
2/2
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 377 times.
394 if not IOStream.empty(ss) then
739
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 4 times.
17 if empty then
740 13 s := IOStream.append(s, "(");
741 empty := false;
742 else
743 4 s := IOStream.append(s, ", ");
744 end if;
745
746 17 s := IOStream.append(s, Util.makeQuotedIdentifier(ComponentRef.firstName(child.name)));
747 17 s := IOStream.appendListStream(ss, s);
748 end if;
749 end for;
750
751
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 13 times.
133 if not empty then
752 13 s := IOStream.append(s, ")");
753 end if;
754 end toFlatStreamModifier;
755
756 function moveBinding
757 "Removes the binding of the variable, if it has one and it has at least
758 discrete variability, and creates an equation from it."
759 input output Variable var;
760 input output list<Equation> equations;
761 algorithm
762 ✗ if variability(var) >= Variability.DISCRETE and Binding.isBound(var.binding) then
763 ✗ equations := Equation.makeEquality(Expression.fromCref(var.name),
764 Binding.getExp(var.binding), var.ty,
765 ElementSource.createElementSource(var.info)) :: equations;
766 ✗ var.binding := NFBinding.EMPTY_BINDING;
767 end if;
768 end moveBinding;
769
770 function getVariableAttributes
771 input Variable var;
772 output VariableAttributes variableAttributes = var.backendinfo.attributes;
773 end getVariableAttributes;
774
775 function getNominal
776 input Variable var;
777 output Option<Expression> nominal = VariableAttributes.getNominal(getVariableAttributes(var));
778 end getNominal;
779
780 function asBinding
781 input Variable var;
782 input Binding.Source source = NFBinding.Source.GENERATED;
783 output Binding binding;
784 algorithm
785 11 binding := Binding.makeFlat(Expression.fromTypedCref(var.name, var.ty), variability(var), source);
786 end asBinding;
787
788 annotation(__OpenModelica_Interface="nf_frontend");
789 end NFVariable;
790