Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 96.6% 143 / 0 / 148
Functions: -% 0 / 1 / 1
Branches: 93.8% 120 / 0 / 128

OMCompiler/Compiler/NFFrontEnd/NFEvalConstants.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package NFEvalConstants
37
38 import FlatModel = NFFlatModel;
39 import Equation = NFEquation;
40 import Statement = NFStatement;
41 import Expression = NFExpression;
42 import Type = NFType;
43 import ComponentRef = NFComponentRef;
44 import NFFlatten.FunctionTree;
45 import Class = NFClass;
46 import NFInstNode.InstNode;
47 import NFInstNode;
48 import NFFunction.Function;
49 import Sections = NFSections;
50 import Binding = NFBinding;
51 import Variable = NFVariable;
52 import Algorithm = NFAlgorithm;
53 import NFEquation.Branch;
54 import Dimension = NFDimension;
55 import InstContext = NFInstContext;
56 import Component = NFComponent;
57 import NFClassTree.ClassTree;
58
59 protected
60 import MetaModelica.Dangerous.*;
61 import ExecStat.execStat;
62 import NFPrefixes.Variability;
63 import Ceval = NFCeval;
64 import Package = NFPackage;
65 import SimplifyExp = NFSimplifyExp;
66 import ErrorExt;
67 import Record = NFRecord;
68 import Flatten = NFFlatten;
69
70 public
71
72 uniontype EvalSettings
73 record SETTINGS
74 Boolean scalarize;
75 end SETTINGS;
76 end EvalSettings;
77
78 function evaluate
79 input output FlatModel flatModel;
80 input InstContext.Type context;
81 protected
82 EvalSettings settings;
83 algorithm
84
2/2
✓ Branch 1 taken 219 times.
✓ Branch 2 taken 1364 times.
1802 settings := EvalSettings.SETTINGS(
85 Flags.isSet(Flags.NF_SCALARIZE)
86 );
87
88
4/4
✓ Branch 0 taken 240734 times.
✓ Branch 1 taken 1577 times.
✓ Branch 2 taken 240734 times.
✓ Branch 3 taken 1577 times.
242311 flatModel.variables := list(evaluateVariable(v, context, settings) for v in flatModel.variables);
89 flatModel.equations := evaluateEquations(flatModel.equations);
90 flatModel.initialEquations := evaluateEquations(flatModel.initialEquations);
91 flatModel.algorithms := evaluateAlgorithms(flatModel.algorithms);
92 flatModel.initialAlgorithms := evaluateAlgorithms(flatModel.initialAlgorithms);
93
94 1576 execStat(getInstanceName());
95 end evaluate;
96
97 function evaluateVariable
98 input output Variable var;
99 input InstContext.Type context;
100 input EvalSettings settings;
101 protected
102 Binding binding;
103 Boolean structural;
104 Variability variability;
105 algorithm
106 241179 variability := Variable.variability(var);
107
4/4
✓ Branch 0 taken 41645 times.
✓ Branch 1 taken 199534 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 41643 times.
241179 structural := variability <= Variability.STRUCTURAL_PARAMETER and
108 not Type.isExternalObject(var.ty);
109 241179 binding := evaluateBinding(var.binding, var.name, structural, variability, context);
110
111
2/2
✓ Branch 0 taken 42636 times.
✓ Branch 1 taken 198537 times.
241173 if not referenceEq(binding, var.binding) then
112 42636 var.binding := binding;
113 end if;
114
115
8/8
✓ Branch 0 taken 471577 times.
✓ Branch 1 taken 241173 times.
✓ Branch 2 taken 471577 times.
✓ Branch 3 taken 241173 times.
✓ Branch 5 taken 445 times.
✓ Branch 6 taken 241173 times.
✓ Branch 7 taken 445 times.
✓ Branch 8 taken 241173 times.
713195 var.typeAttributes := list(evaluateTypeAttribute(a, var.name, context) for a in var.typeAttributes);
116 var.children := list(evaluateVariable(v, context, settings) for v in var.children);
117 end evaluateVariable;
118
119 function evaluateBinding
120 input output Binding binding;
121 input ComponentRef prefix;
122 input Boolean structural;
123 input Variability variability;
124 input InstContext.Type context;
125 protected
126 Expression exp, eexp;
127 SourceInfo info;
128 algorithm
129
2/2
✓ Branch 1 taken 109998 times.
✓ Branch 2 taken 602758 times.
712756 if Binding.isBound(binding) then
130 602758 exp := Binding.getTypedExp(binding);
131
132
2/2
✓ Branch 0 taken 48036 times.
✓ Branch 1 taken 554722 times.
602758 if structural then
133 48036 info := Binding.getInfo(binding);
134 48036 eexp := evaluateExp(exp, info);
135 48035 eexp := SimplifyExp.simplify(eexp);
136
137
4/4
✓ Branch 1 taken 649 times.
✓ Branch 2 taken 47386 times.
✓ Branch 4 taken 180 times.
✓ Branch 5 taken 469 times.
48035 if not (Expression.isLiteral(eexp) or Expression.isKnownSizeFill(eexp)) then
138 // Any structural parameter that hasn't already been evaluated in earlier stages,
139 // such as parameters with Evaluate=true annotations, are probably not critical to evaluate.
140
3/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 149 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 31 times.
180 if variability > Variability.CONSTANT or InstContext.inRelaxed(context) then
141 149 eexp := Ceval.tryEvalExp(eexp);
142 else
143 31 eexp := Ceval.evalExp(eexp, Ceval.EvalTarget.new(info, context));
144 end if;
145 end if;
146
147 48030 eexp := Flatten.flattenExp(eexp, Flatten.PREFIX(InstNode.EMPTY_NODE(), prefix), info);
148 else
149 554722 eexp := evaluateExp(exp, Binding.getInfo(binding));
150 end if;
151
152
2/2
✓ Branch 0 taken 468233 times.
✓ Branch 1 taken 134519 times.
602752 if not referenceEq(exp, eexp) then
153 134519 binding := Binding.setTypedExp(eexp, binding);
154 end if;
155 end if;
156 end evaluateBinding;
157
158 function evaluateTypeAttribute
159 input output tuple<String, Binding> attribute;
160 input ComponentRef prefix;
161 input InstContext.Type context;
162 protected
163 String name;
164 Binding binding, sbinding;
165 Boolean structural;
166 algorithm
167 471577 (name, binding) := attribute;
168
8/8
✓ Branch 0 taken 63917 times.
✓ Branch 1 taken 407660 times.
✓ Branch 3 taken 61087 times.
✓ Branch 4 taken 2830 times.
✓ Branch 5 taken 26712 times.
✓ Branch 6 taken 442035 times.
✓ Branch 8 taken 3567 times.
✓ Branch 9 taken 23145 times.
471577 structural := name == "fixed" or name == "stateSelect";
169 471577 sbinding := evaluateBinding(binding, prefix, structural, Variability.PARAMETER, context);
170
171
2/2
✓ Branch 0 taken 379694 times.
✓ Branch 1 taken 91883 times.
471577 if not referenceEq(binding, sbinding) then
172 91883 attribute := (name, sbinding);
173 end if;
174 end evaluateTypeAttribute;
175
176 function evaluateExp
177 input Expression exp;
178 input SourceInfo info;
179 output Expression outExp;
180 algorithm
181 903290 outExp := evaluateExpTraverser(exp, info);
182 end evaluateExp;
183
184 function evaluateExpTraverser
185 input Expression exp;
186 input SourceInfo info;
187 input Boolean changed = false;
188 output Expression outExp;
189 output Boolean outChanged = changed;
190 protected
191 Expression e;
192 ComponentRef cref;
193 Type ty, ty2;
194 Variability var;
195 algorithm
196 (outExp, outChanged) := match exp
197 case Expression.CREF()
198 algorithm
199
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 511684 times.
511684 (outExp as Expression.CREF(cref = cref, ty = ty), outChanged) :=
200 Expression.mapFoldShallow(exp,
201 function evaluateExpTraverser(info = info), false);
202
203 511684 var := ComponentRef.nodeVariability(cref);
204
205
4/4
✓ Branch 0 taken 66618 times.
✓ Branch 1 taken 445066 times.
✓ Branch 3 taken 66616 times.
✓ Branch 4 taken 2 times.
511684 if var <= Variability.STRUCTURAL_PARAMETER and not Type.isExternalObject(ty) then
206 // Evaluate all constants and structural parameters.
207
2/2
✓ Branch 0 taken 34270 times.
✓ Branch 1 taken 32346 times.
66616 if var > Variability.CONSTANT then
208 34270 ErrorExt.setCheckpoint(getInstanceName());
209 try
210 34270 e := Ceval.evalCref(cref, outExp, NFCeval.noTarget, evalSubscripts = false);
211 34270 e := Flatten.flattenExp(e, Flatten.Prefix.PREFIX(InstNode.EMPTY_NODE(), cref), info);
212 outExp := e;
213 outChanged := true;
214 else
215 end try;
216 34270 ErrorExt.rollBack(getInstanceName());
217 else
218 32346 outExp := Ceval.evalCref(cref, outExp, Ceval.EvalTarget.new(info), evalSubscripts = false);
219 32344 outExp := Flatten.flattenExp(outExp, Flatten.Prefix.PREFIX(InstNode.EMPTY_NODE(), cref), info);
220 outChanged := true;
221 end if;
222 elseif outChanged then
223 3798 ty := ComponentRef.getSubscriptedType(cref);
224 end if;
225
226 511682 ty2 := evaluateType(ty, info);
227
2/2
✓ Branch 0 taken 66301 times.
✓ Branch 1 taken 445381 times.
511682 if not referenceEq(ty, ty2) then
228 66301 outExp := Expression.setType(ty2, outExp);
229 end if;
230 511682 then
231 (outExp, outChanged);
232
233 16730 case Expression.ARRAY(literal = true) then (exp, false);
234 8365 case Expression.IF() then evaluateIfExp(exp, info);
235
236 // Only evaluate the index for size expressions.
237 case Expression.SIZE()
238 algorithm
239
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 if isSome(exp.dimIndex) then
240 1 SOME(e) := exp.dimIndex;
241 1 (e, outChanged) := Expression.mapFoldShallow(e,
242 function evaluateExpTraverser(info = info), false);
243
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if outChanged then
245 ✗ exp.dimIndex := SOME(e);
246 end if;
247 end if;
248 1 then
249 (exp, outChanged);
250
251 case Expression.RANGE()
252 algorithm
253 2675 (outExp, outChanged) := Expression.mapFoldShallow(exp,
254 function evaluateExpTraverser(info = info), false);
255
256 // If anything in a range is evaluated its better to just retype it
257 // rather than evaluating the type, since it's usually faster and gives
258 // better results in some cases.
259
2/2
✓ Branch 0 taken 574 times.
✓ Branch 1 taken 2101 times.
2675 if outChanged then
260 574 outExp := Expression.retype(outExp);
261 end if;
262 2675 then
263 (outExp, outChanged);
264
265 else
266 algorithm
267 1389738 (outExp, outChanged) := Expression.mapFoldShallow(exp,
268 function evaluateExpTraverser(info = info), false);
269
270 1389737 ty := Expression.typeOf(outExp);
271 1389737 ty2 := evaluateType(ty, info);
272
2/2
✓ Branch 0 taken 159817 times.
✓ Branch 1 taken 1229920 times.
1389737 then
273 (if referenceEq(ty, ty2) then outExp else Expression.setType(ty2, outExp), outChanged);
274 end match;
275
276
2/2
✓ Branch 0 taken 1020780 times.
✓ Branch 1 taken 908410 times.
1929190 outChanged := changed or outChanged;
277 end evaluateExpTraverser;
278
279 function evaluateType
280 input output Type ty;
281 input SourceInfo info;
282 algorithm
283 ty := match ty
284 case Type.ARRAY()
285 algorithm
286
4/4
✓ Branch 0 taken 269372 times.
✓ Branch 1 taken 226118 times.
✓ Branch 2 taken 269372 times.
✓ Branch 3 taken 226118 times.
721608 ty.dimensions := list(evaluateDimension(d, info) for d in ty.dimensions);
287 then
288 ty;
289
290 case Type.CONDITIONAL_ARRAY()
291 ✗ then Type.simplifyConditionalArray(ty);
292
293 else ty;
294 end match;
295 end evaluateType;
296
297 function evaluateDimension
298 input Dimension dim;
299 input SourceInfo info;
300 output Dimension outDim;
301 algorithm
302 outDim := match dim
303 local
304 Expression e;
305
306 case Dimension.EXP()
307 algorithm
308 243 e := evaluateExp(dim.exp, info);
309
1/2
✓ Branch 0 taken 243 times.
✗ Branch 1 not taken.
243 then
310 if referenceEq(e, dim.exp) then dim else Dimension.fromExp(e, dim.var);
311
312 else dim;
313 end match;
314 end evaluateDimension;
315
316 function evaluateIfExp
317 "Evaluates constants in an if-expression. This is done by first checking if
318 the condition can be evaluated, in which case branch selection is done to
319 avoid issues that can arise when evaluating constants in branches that are
320 expected to be discarded."
321 input Expression exp;
322 input SourceInfo info;
323 output Expression outExp;
324 output Boolean outChanged;
325 protected
326 Type ty;
327 Expression cond, tb, fb;
328 Boolean c1, c2;
329 algorithm
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8365 times.
8365 Expression.IF(ty, cond, tb, fb) := exp;
331 8365 (cond, outChanged) := evaluateExpTraverser(cond, info);
332
333 // Simplify the condition in case it can be reduced to a literal value.
334 8365 cond := SimplifyExp.simplify(cond);
335
336 (outExp, outChanged) := match cond
337 // Only evaluate constants in and return one of the branches if the
338 // condition is a literal boolean value.
339 case Expression.BOOLEAN()
340 algorithm
341
2/2
✓ Branch 0 taken 3655 times.
✓ Branch 1 taken 1467 times.
8777 outExp := evaluateExpTraverser(if cond.value then tb else fb, info);
342 then
343 (outExp, true);
344
345 // Otherwise evaluate constants in both branches and return the whole
346 // if-expression.
347 else
348 algorithm
349 3243 (tb, c1) := evaluateExpTraverser(tb, info);
350 3243 (fb, c2) := evaluateExpTraverser(fb, info);
351
6/6
✓ Branch 1 taken 2894 times.
✓ Branch 2 taken 349 times.
✓ Branch 3 taken 2785 times.
✓ Branch 4 taken 109 times.
✓ Branch 5 taken 2470 times.
✓ Branch 6 taken 315 times.
3243 then
352 (Expression.IF(ty, cond, tb, fb), outChanged or c1 or c2);
353
354 end match;
355 end evaluateIfExp;
356
357 function evaluateEquations
358 input list<Equation> eql;
359 output list<Equation> outEql = list(evaluateEquation(e) for e in eql);
360 end evaluateEquations;
361
362 function evaluateEquation
363 input output Equation eq;
364 protected
365 SourceInfo info = Equation.info(eq);
366 algorithm
367 eq := match eq
368 local
369 Expression e1, e2, e3;
370 Type ty;
371
372 case Equation.EQUALITY()
373 algorithm
374 140706 ty := Type.mapDims(eq.ty, function evaluateDimension(info = info));
375 140706 e1 := evaluateExp(eq.lhs, info);
376 140706 e2 := evaluateExp(eq.rhs, info);
377 140705 then
378 Equation.EQUALITY(e1, e2, ty, eq.scope, eq.source, eq.scalarizeMode);
379
380 case Equation.FOR()
381 algorithm
382 712 eq.range := Util.applyOption(eq.range, function evaluateExp(info = info));
383 356 eq.body := evaluateEquations(eq.body);
384 then
385 eq;
386
387 case Equation.IF()
388 algorithm
389
4/4
✓ Branch 0 taken 2599 times.
✓ Branch 1 taken 1463 times.
✓ Branch 2 taken 2599 times.
✓ Branch 3 taken 1463 times.
5525 eq.branches := list(evaluateEqBranch(b, info) for b in eq.branches);
390 then
391 eq;
392
393 case Equation.WHEN()
394 algorithm
395
4/4
✓ Branch 0 taken 363 times.
✓ Branch 1 taken 322 times.
✓ Branch 2 taken 363 times.
✓ Branch 3 taken 322 times.
1007 eq.branches := list(evaluateEqBranch(b, info) for b in eq.branches);
396 then
397 eq;
398
399 case Equation.ASSERT()
400 algorithm
401 4577 e1 := evaluateExp(eq.condition, info);
402 4577 e2 := evaluateExp(eq.message, info);
403 4577 e3 := evaluateExp(eq.level, info);
404 4577 then
405 Equation.ASSERT(e1, e2, e3, eq.scope, eq.source);
406
407 case Equation.TERMINATE()
408 algorithm
409 6 eq.message := evaluateExp(eq.message, info);
410 then
411 eq;
412
413 case Equation.REINIT()
414 algorithm
415 28 eq.reinitExp := evaluateExp(eq.reinitExp, info);
416 then
417 eq;
418
419 case Equation.NORETCALL()
420 algorithm
421 70 eq.exp := evaluateExp(eq.exp, info);
422 then
423 eq;
424
425 else eq;
426 end match;
427 end evaluateEquation;
428
429 function evaluateEqBranch
430 input Branch branch;
431 input SourceInfo info;
432 output Branch outBranch;
433 algorithm
434 outBranch := match branch
435 local
436 Expression condition;
437 list<Equation> body;
438
439 case Branch.BRANCH(condition = condition, body = body)
440 algorithm
441 2957 condition := evaluateExp(condition, info);
442 2957 body := evaluateEquations(body);
443 2957 then
444 Branch.BRANCH(condition, branch.conditionVar, body);
445
446 else branch;
447 end match;
448 end evaluateEqBranch;
449
450 function evaluateAlgorithms
451 input list<Algorithm> algs;
452 output list<Algorithm> outAlgs = list(evaluateAlgorithm(a) for a in algs);
453 end evaluateAlgorithms;
454
455 function evaluateAlgorithm
456 input output Algorithm alg;
457 algorithm
458 197 alg.statements := evaluateStatements(alg.statements);
459 end evaluateAlgorithm;
460
461 function evaluateStatements
462 input list<Statement> stmts;
463 output list<Statement> outStmts = list(evaluateStatement(s) for s in stmts);
464 end evaluateStatements;
465
466 function evaluateStatement
467 input output Statement stmt;
468 protected
469 SourceInfo info = Statement.info(stmt);
470 algorithm
471 stmt := match stmt
472 local
473 Expression e1, e2, e3;
474 Type ty;
475
476 case Statement.ASSIGNMENT()
477 algorithm
478 539 ty := Type.mapDims(stmt.ty, function evaluateDimension(info = info));
479 539 e1 := evaluateExp(stmt.lhs, info);
480 539 e2 := evaluateExp(stmt.rhs, info);
481 539 then
482 Statement.ASSIGNMENT(e1, e2, ty, stmt.source);
483
484 case Statement.FOR()
485 algorithm
486 188 stmt.range := Util.applyOption(stmt.range, function evaluateExp(info = info));
487 94 stmt.body := evaluateStatements(stmt.body);
488 then
489 stmt;
490
491 case Statement.IF()
492 algorithm
493
4/4
✓ Branch 0 taken 237 times.
✓ Branch 1 taken 176 times.
✓ Branch 2 taken 237 times.
✓ Branch 3 taken 176 times.
589 stmt.branches := list(evaluateStmtBranch(b, info) for b in stmt.branches);
494 then
495 stmt;
496
497 case Statement.WHEN()
498 algorithm
499
4/4
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 82 times.
✓ Branch 2 taken 118 times.
✓ Branch 3 taken 82 times.
282 stmt.branches := list(evaluateStmtBranch(b, info) for b in stmt.branches);
500 then
501 stmt;
502
503 case Statement.ASSERT()
504 algorithm
505 57 e1 := evaluateExp(stmt.condition, info);
506 57 e2 := evaluateExp(stmt.message, info);
507 57 e3 := evaluateExp(stmt.level, info);
508 57 then
509 Statement.ASSERT(e1, e2, e3, stmt.source);
510
511 case Statement.TERMINATE()
512 algorithm
513 1 stmt.message := evaluateExp(stmt.message, info);
514 then
515 stmt;
516
517 case Statement.REINIT()
518 algorithm
519 4 stmt.reinitExp := evaluateExp(stmt.reinitExp, info);
520 then
521 stmt;
522
523 case Statement.NORETCALL()
524 algorithm
525 24 stmt.exp := evaluateExp(stmt.exp, info);
526 then
527 stmt;
528
529 case Statement.WHILE()
530 algorithm
531 ✗ stmt.condition := evaluateExp(stmt.condition, info);
532 ✗ stmt.body := evaluateStatements(stmt.body);
533 then
534 stmt;
535
536 else stmt;
537 end match;
538 end evaluateStatement;
539
540 function evaluateStmtBranch
541 input tuple<Expression, list<Statement>> branch;
542 input SourceInfo info;
543 output tuple<Expression, list<Statement>> outBranch;
544 protected
545 Expression cond;
546 list<Statement> body;
547 algorithm
548 355 (cond, body) := branch;
549 355 cond := evaluateExp(cond, info);
550 355 body := evaluateStatements(body);
551 355 outBranch := (cond, body);
552 end evaluateStmtBranch;
553
554 function evaluateFunction
555 input output Function func;
556 protected
557 Boolean is_con;
558 algorithm
559
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 12185 times.
12185 if not Function.isEvaluated(func) then
560 12185 Function.markEvaluated(func);
561 12185 is_con := Function.isDefaultRecordConstructor(func);
562
563
2/2
✓ Branch 0 taken 10610 times.
✓ Branch 1 taken 1575 times.
22795 func := Function.mapExp(func,
564 function evaluateFuncExp(fnNode = InstNode.fromHandle(func.node), evaluateAll = is_con),
565 function evaluateFuncExp(fnNode = InstNode.fromHandle(func.node), evaluateAll = true));
566
567
2/2
✓ Branch 0 taken 1575 times.
✓ Branch 1 taken 10610 times.
12185 if is_con then
568 1575 Record.checkLocalFieldOrder(func.locals, InstNode.fromHandle(func.node), InstNode.info(InstNode.fromHandle(func.node)));
569 end if;
570
571
2/2
✓ Branch 0 taken 800 times.
✓ Branch 1 taken 12185 times.
12985 for fn_der in func.derivatives loop
572
2/2
✓ Branch 2 taken 800 times.
✓ Branch 3 taken 800 times.
1600 for der_fn in Function.getCachedFuncs(InstNode.borrow(fn_der.derivativeFn)) loop
573 800 evaluateFunction(der_fn);
574 end for;
575 end for;
576 end if;
577 end evaluateFunction;
578
579 function evaluateFuncExp
580 input Expression exp;
581 input InstNode fnNode;
582 input Boolean evaluateAll;
583 output Expression outExp;
584 algorithm
585 494332 outExp := evaluateFuncExpTraverser(exp, fnNode, evaluateAll, false);
586 end evaluateFuncExp;
587
588 function evaluateFuncExpTraverser
589 input Expression exp;
590 input InstNode fnNode;
591 input Boolean evaluateAll;
592 input Boolean changed;
593 output Expression outExp;
594 output Boolean outChanged;
595 protected
596 Expression e;
597 algorithm
598
2/2
✓ Branch 0 taken 1673129 times.
✓ Branch 1 taken 280866 times.
3627124 (e, outChanged) := Expression.mapFoldShallow(exp,
599 function evaluateFuncExpTraverser(fnNode = fnNode, evaluateAll = evaluateAll), false);
600
601 outExp := match e
602 case Expression.CREF()
603 algorithm
604
4/4
✓ Branch 0 taken 654018 times.
✓ Branch 1 taken 12061 times.
✓ Branch 3 taken 12830 times.
✓ Branch 4 taken 641188 times.
666079 if evaluateAll or not isLocalFunctionVariable(e.cref, fnNode) then
605 24891 ErrorExt.setCheckpoint(getInstanceName());
606 try
607 24891 outExp := Ceval.evalCref(e.cref, e, NFCeval.noTarget, evalSubscripts = false);
608 else
609 ✗ outExp := e;
610 end try;
611 24891 ErrorExt.rollBack(getInstanceName());
612 outChanged := true;
613 elseif outChanged then
614 // If the cref's subscripts changed, recalculate its type.
615 1202 outExp := Expression.CREF(ComponentRef.getSubscriptedType(e.cref), e.cref);
616 else
617 outExp := e;
618 end if;
619 then
620 outExp;
621
622
2/2
✓ Branch 0 taken 22180 times.
✓ Branch 1 taken 1265736 times.
1287916 else if outChanged then Expression.retype(e) else e;
623 end match;
624
625
2/2
✓ Branch 0 taken 1459663 times.
✓ Branch 1 taken 494332 times.
1953995 outChanged := changed or outChanged;
626 end evaluateFuncExpTraverser;
627
628 function isLocalFunctionVariable
629 input ComponentRef cref;
630 input InstNode fnNode;
631 output Boolean res;
632 protected
633 InstNode node;
634 list<Function> fnl;
635 Function fn;
636 algorithm
637
2/2
✓ Branch 1 taken 642766 times.
✓ Branch 2 taken 11252 times.
654018 if ComponentRef.isPackageConstant(cref) then
638 res := false;
639 elseif ComponentRef.nodeVariability(cref) <= Variability.PARAMETER and ComponentRef.isCref(cref) then
640 6131 node := InstNode.instanceParent(ComponentRef.node(ComponentRef.last(cref)));
641
642
2/2
✓ Branch 1 taken 4816 times.
✓ Branch 2 taken 1315 times.
6131 if InstNode.isClass(node) then
643 4816 fnl := Function.getCachedFuncs(node);
644
645
2/2
✓ Branch 0 taken 4553 times.
✓ Branch 1 taken 263 times.
4816 if listEmpty(fnl) then
646 res := false;
647 else
648 4553 fn := listHead(fnl);
649 4553 res := InstNode.refEqual(fnNode, InstNode.fromHandle(fn.node));
650 end if;
651 else
652 res := false;
653 end if;
654 else
655 res := true;
656 end if;
657 end isLocalFunctionVariable;
658
659 function evaluateRecordDeclaration
660 input InstNode recordNode;
661 algorithm
662 26 ClassTree.applyComponents(Class.classTree(InstNode.getClass(recordNode)),
663 function evaluateRecordDeclarationField(recordNode = recordNode));
664 end evaluateRecordDeclaration;
665
666 function evaluateRecordDeclarationField
667 input InstNode fieldNode;
668 input InstNode recordNode;
669 protected
670 Component comp;
671 Binding binding;
672 InstNode cls_inst;
673 algorithm
674 1272 comp := InstNode.component(fieldNode);
675 1272 binding := Component.getBinding(comp);
676
677
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1268 times.
1272 if Binding.isBound(binding) then
678 4 binding := Binding.mapExp(binding, function evaluateFuncExp(fnNode = fieldNode, evaluateAll = false));
679 4 comp := Component.setBinding(binding, comp);
680 end if;
681
682 1272 cls_inst := Component.classInstance(comp);
683
2/2
✓ Branch 1 taken 123 times.
✓ Branch 2 taken 1149 times.
1272 if not InstNode.isEmpty(cls_inst) then
684 123 ClassTree.applyComponents(Class.classTree(InstNode.getClass(cls_inst)),
685 function evaluateRecordDeclarationField(recordNode = recordNode));
686 end if;
687
688 1272 InstNode.updateComponent(comp, fieldNode);
689 end evaluateRecordDeclarationField;
690
691 annotation(__OpenModelica_Interface="nf_frontend");
692 end NFEvalConstants;
693