Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 71.6% 179 / 0 / 250
Functions: -% 0 / 1 / 1
Branches: 63.6% 131 / 0 / 206

OMCompiler/Compiler/NFFrontEnd/NFFlatModel.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 NFFlatModel
37 import Equation = NFEquation;
38 import Algorithm = NFAlgorithm;
39 import Variable = NFVariable;
40 import BaseModelica;
41
42 protected
43 import Absyn;
44 import Binding = NFBinding;
45 import Call = NFCall;
46 import Class = NFClass;
47 import ComplexType = NFComplexType;
48 import Component = NFComponent;
49 import DAE;
50 import DAE.ElementSource;
51 import Dimension = NFDimension;
52 import ErrorExt;
53 import ExpandExp = NFExpandExp;
54 import Expression = NFExpression;
55 import FlatModelicaUtil = NFFlatModelicaUtil;
56 import Flatten = NFFlatten;
57 import NFFlatten.FunctionTree;
58 import FunctionInverse = NFFunctionInverse;
59 import Inline = NFInline;
60 import InstContext = NFInstContext;
61 import IOStream;
62 import Lookup = NFLookup;
63 import MetaModelica.Dangerous.listReverseInPlace;
64 import NFClassTree.ClassTree;
65 import NFComponentRef.ComponentRef;
66 import NFFunction.Function;
67 import NFInstNode.InstNode;
68 import NFPrefixes.Visibility;
69 import NFSubscript.Subscript;
70 import Prefixes = NFPrefixes;
71 import Scalarize = NFScalarize;
72 import SCode;
73 import Statement = NFStatement;
74 import StringUtil;
75 import Type = NFType;
76 import Typing = NFTyping;
77 import UnorderedMap;
78 import Util;
79
80 import FlatModel = NFFlatModel;
81
82 type TypeMap = UnorderedMap<Absyn.Path, Type>;
83
84 public
85 record FLAT_MODEL
86 Absyn.Path name;
87 list<Variable> variables;
88 list<Equation> equations;
89 list<Equation> initialEquations;
90 list<Algorithm> algorithms;
91 list<Algorithm> initialAlgorithms;
92 ElementSource source;
93 end FLAT_MODEL;
94
95 function mapExp
96 input output FlatModel flatModel;
97 input MapFn fn;
98
99 partial function MapFn
100 input output Expression exp;
101 end MapFn;
102 algorithm
103
4/4
✓ Branch 0 taken 378396 times.
✓ Branch 1 taken 1453 times.
✓ Branch 2 taken 378396 times.
✓ Branch 3 taken 1453 times.
379849 flatModel.variables := list(Variable.mapExpShallow(v, fn) for v in flatModel.variables);
104 flatModel.equations := Equation.mapExpList(flatModel.equations, fn);
105 flatModel.initialEquations := Equation.mapExpList(flatModel.initialEquations, fn);
106 flatModel.algorithms := Algorithm.mapExpList(flatModel.algorithms, fn);
107 flatModel.initialAlgorithms := Algorithm.mapExpList(flatModel.initialAlgorithms, fn);
108 end mapExp;
109
110 function mapEquations
111 input output FlatModel flatModel;
112 input MapFn fn;
113
114 partial function MapFn
115 input output Equation eq;
116 end MapFn;
117 algorithm
118
8/8
✓ Branch 0 taken 152998 times.
✓ Branch 1 taken 1218 times.
✓ Branch 2 taken 152998 times.
✓ Branch 3 taken 1218 times.
✓ Branch 5 taken 2253 times.
✓ Branch 6 taken 1218 times.
✓ Branch 7 taken 2253 times.
✓ Branch 8 taken 1218 times.
156469 flatModel.equations := list(Equation.map(eq, fn) for eq in flatModel.equations);
119 flatModel.initialEquations := list(Equation.map(eq, fn) for eq in flatModel.initialEquations);
120 end mapEquations;
121
122 function mapAlgorithms
123 input output FlatModel flatModel;
124 input MapFn fn;
125
126 partial function MapFn
127 input output Algorithm alg;
128 end MapFn;
129 algorithm
130
10/12
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 1218 times.
✓ Branch 2 taken 132 times.
✓ Branch 3 taken 1218 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 132 times.
✓ Branch 8 taken 46 times.
✓ Branch 9 taken 1218 times.
✓ Branch 10 taken 46 times.
✓ Branch 11 taken 1218 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 46 times.
1396 flatModel.algorithms := list(fn(alg) for alg in flatModel.algorithms);
131 flatModel.initialAlgorithms := list(fn(alg) for alg in flatModel.initialAlgorithms);
132 end mapAlgorithms;
133
134 function fullName
135 input FlatModel flatModel;
136 output String name = AbsynUtil.pathString(flatModel.name);
137 end fullName;
138
139 function className
140 input FlatModel flatModel;
141 output String name = AbsynUtil.pathLastIdent(flatModel.name);
142 end className;
143
144 function toString
145 input FlatModel flatModel;
146 input FunctionTree functions;
147 input Boolean printBindingTypes = false;
148 output String str = IOStream.string(toStream(flatModel, functions, printBindingTypes));
149 end toString;
150
151 function printString
152 input FlatModel flatModel;
153 input FunctionTree functions;
154 input Boolean printBindingTypes = false;
155 protected
156 IOStream.IOStream s;
157 algorithm
158 6 s := toStream(flatModel, functions, printBindingTypes);
159 6 IOStream.print(s, IOStream.stdOutput);
160 end printString;
161
162 function toStream
163 input FlatModel flatModel;
164 input FunctionTree functions;
165 input Boolean printBindingTypes = false;
166 output IOStream.IOStream s;
167 algorithm
168 6 s := IOStream.create(getInstanceName(), IOStream.IOStreamType.LIST());
169 6 s := appendStream(flatModel, functions, printBindingTypes, s);
170 end toStream;
171
172 function appendStream
173 input FlatModel flatModel;
174 input FunctionTree functions;
175 input Boolean printBindingTypes = false;
176 input output IOStream.IOStream s;
177 protected
178 String name = className(flatModel);
179 algorithm
180
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 for fn in FunctionTree.listValues(functions) loop
181 ✗ s := Function.toStream(fn, "", s);
182 ✗ s := IOStream.append(s, ";\n\n");
183 end for;
184
185 6 s := IOStream.append(s, "class " + name + "\n");
186
187
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 6 times.
38 for v in flatModel.variables loop
188 32 s := Variable.toStream(v, " ", printBindingTypes, s);
189 32 s := IOStream.append(s, ";\n");
190 end for;
191
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if not listEmpty(flatModel.initialEquations) then
193 ✗ s := IOStream.append(s, "initial equation\n");
194 ✗ s := Equation.toStreamList(flatModel.initialEquations, " ", s);
195 end if;
196
197
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if not listEmpty(flatModel.equations) then
198 6 s := IOStream.append(s, "equation\n");
199 6 s := Equation.toStreamList(flatModel.equations, " ", s);
200 end if;
201
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 for alg in flatModel.initialAlgorithms loop
203 ✗ if not listEmpty(alg.statements) then
204 ✗ s := IOStream.append(s, "initial algorithm\n");
205 ✗ s := Statement.toStreamList(alg.statements, " ", s);
206 end if;
207 end for;
208
209
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 for alg in flatModel.algorithms loop
210
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if not listEmpty(alg.statements) then
211 6 s := IOStream.append(s, "algorithm\n");
212 6 s := Statement.toStreamList(alg.statements, " ", s);
213 end if;
214 end for;
215
216 6 s := IOStream.append(s, "end " + name + ";\n");
217 end appendStream;
218
219 function toFlatString
220 "Returns a string containing the flat Modelica representation of the given model."
221 input FlatModel flatModel;
222 input FunctionTree functions;
223 input Boolean printBindingTypes = false;
224 output String str = IOStream.string(toFlatStream(flatModel, functions, printBindingTypes));
225 end toFlatString;
226
227 function printFlatString
228 "Prints a flat Modelica representation of the given model to standard output."
229 input FlatModel flatModel;
230 input FunctionTree functions;
231 input Boolean printBindingTypes = false;
232 protected
233 IOStream.IOStream s;
234 algorithm
235 ✗ s := toFlatStream(flatModel, functions, printBindingTypes);
236 ✗ IOStream.print(s, IOStream.stdOutput);
237 end printFlatString;
238
239 function toFlatStream
240 "Returns a new IOStream containing the flat Modelica representation of the given model."
241 input FlatModel flatModel;
242 input FunctionTree functions;
243 input Boolean printBindingTypes = false;
244 output IOStream.IOStream s;
245 algorithm
246 32 s := IOStream.create(className(flatModel), IOStream.IOStreamType.LIST());
247 32 s := appendFlatStream(flatModel, functions, printBindingTypes, s);
248 end toFlatStream;
249
250 function appendFlatStream
251 "Appends the flat Modelica representation of the given model to an existing IOStream."
252 input FlatModel flatModel;
253 input FunctionTree functions;
254 input Boolean printBindingTypes = false;
255 input output IOStream.IOStream s;
256 protected
257 FlatModel flat_model = flatModel;
258 String name = Util.makeQuotedIdentifier(className(flatModel));
259 BaseModelica.OutputFormat format;
260 Boolean scalarize;
261 list<Function> funcs = FunctionTree.listValues(functions);
262 algorithm
263 32 format := BaseModelica.formatFromFlags();
264 32 scalarize := Flags.isConfigFlagSet(Flags.BASE_MODELICA_OPTIONS, "scalarize");
265
266
2/8
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 32 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
32 if Flags.getConfigString(Flags.OBFUSCATE) == "protected" or
267 Flags.getConfigString(Flags.OBFUSCATE) == "encrypted" then
268 ✗ flat_model := obfuscate(flat_model);
269 end if;
270
271
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 29 times.
32 if BaseModelica.inlineFunctions() then
272 3 (flat_model, funcs) := inlineFunctions(flat_model);
273 end if;
274
275
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 27 times.
32 if scalarize then
276 5 flat_model.variables := Scalarize.scalarizeVariables(flat_model.variables, forceScalarize = true);
277 flat_model.equations := Equation.splitRecordEquations(flat_model.equations);
278 5 flat_model.equations := Scalarize.scalarizeEquations(flat_model.equations, forceScalarize = true);
279 flat_model.initialEquations := Equation.splitRecordEquations(flat_model.initialEquations);
280
4/8
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 5 times.
5 flat_model.initialEquations := Scalarize.scalarizeEquations(flat_model.initialEquations, forceScalarize = true);
281 flat_model.algorithms := list(Flatten.unrollForStatementsInAlg(a) for a in flat_model.algorithms);
282 flat_model.initialAlgorithms := list(Flatten.unrollForStatementsInAlg(a) for a in flat_model.initialAlgorithms);
283 5 flat_model := mapExp(flat_model, ExpandExp.expandCallArgs);
284 else
285 27 flat_model.variables := reconstructRecordInstances(flat_model.variables);
286 27 flat_model.variables := List.filterOnFalse(flat_model.variables, Variable.isEmptyArray);
287 end if;
288
289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if format.moveBindings then
290 ✗ flat_model := moveBindings(flat_model);
291 end if;
292
293 32 s := IOStream.append(s, "//! base 0.1.0\n");
294 32 s := IOStream.append(s, "package " + name + "\n");
295
296
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 32 times.
60 for fn in funcs loop
297
3/4
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 18 times.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
28 if not (Function.isDefaultRecordConstructor(fn) or Function.isExternalObjectConstructorOrDestructor(fn)) then
298 // Function parameters are not affected by the scalarization mode, so use default format here.
299 10 s := Function.toFlatStream(fn, BaseModelica.defaultFormat, " ", s);
300 10 s := IOStream.append(s, ";\n\n");
301 end if;
302 end for;
303
304
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 32 times.
60 for ty in collectFlatTypes(flat_model, funcs) loop
305 28 s := Type.toFlatDeclarationStream(ty, format, " ", s);
306 28 s := IOStream.append(s, ";\n\n");
307 end for;
308
309 32 s := IOStream.append(s, " model " + name);
310 32 s := FlatModelicaUtil.appendElementSourceCommentString(flat_model.source, s);
311 32 s := IOStream.append(s, "\n");
312
313
2/2
✓ Branch 0 taken 847 times.
✓ Branch 1 taken 32 times.
879 for v in flat_model.variables loop
314 847 s := Variable.toFlatStream(v, format, " ", printBindingTypes, s);
315 847 s := IOStream.append(s, ";\n");
316 end for;
317
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if not listEmpty(flat_model.initialEquations) then
319 ✗ s := IOStream.append(s, " initial equation\n");
320 ✗ s := Equation.toFlatStreamList(flat_model.initialEquations, format, " ", s);
321 end if;
322
323
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 if not listEmpty(flat_model.equations) then
324 24 s := IOStream.append(s, " equation\n");
325 24 s := Equation.toFlatStreamList(flat_model.equations, format, " ", s);
326 end if;
327
328
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 for alg in flat_model.initialAlgorithms loop
329 ✗ if not listEmpty(alg.statements) then
330 ✗ s := IOStream.append(s, " initial algorithm\n");
331 ✗ s := Statement.toFlatStreamList(alg.statements, format, " ", s);
332 end if;
333 end for;
334
335
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 for alg in flat_model.algorithms loop
336 ✗ if not listEmpty(alg.statements) then
337 ✗ s := IOStream.append(s, " algorithm\n");
338 ✗ s := Statement.toFlatStreamList(alg.statements, format, " ", s);
339 end if;
340 end for;
341
342 32 s := FlatModelicaUtil.appendElementSourceCommentAnnotation(flat_model.source,
343 NFFlatModelicaUtil.ElementType.ROOT_CLASS, " ", ";\n", s);
344 32 s := IOStream.append(s, " end " + name + ";\n");
345 32 s := IOStream.append(s, "end " + name + ";\n");
346 end appendFlatStream;
347
348 function inlineFunctions
349 "Tries to inline all function calls in the flat model, and returns the new
350 flat model and a list of functions that couldn't be inlined."
351 input output FlatModel flatModel;
352 output list<Function> remainingFuncs;
353 protected
354 UnorderedSet<Function> funcs;
355 algorithm
356 3 funcs := UnorderedSet.new(Function.nameHash, Function.nameEqual);
357 3 flatModel := mapExp(flatModel, function Expression.map(func = function inlineFunctions_traverser(funcs = funcs)));
358 3 remainingFuncs := UnorderedSet.toList(funcs);
359 end inlineFunctions;
360
361 function inlineFunctions_traverser
362 input Expression exp;
363 input UnorderedSet<Function> funcs;
364 output Expression outExp;
365 protected
366 Function fn;
367 algorithm
368 outExp := match exp
369 case Expression.CALL()
370 algorithm
371 3 fn := Call.typedFunction(exp.call);
372
373
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if Function.isBuiltin(fn) then
374 outExp := exp;
375 else
376 3 outExp := Inline.inlineCallExp(exp, forceInline = true);
377
378
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 2 times.
3 if referenceEq(exp, outExp) then
379 // If the call wasn't inlined, add it to the set of remaining functions.
380 1 collectFunction(fn, funcs);
381 else
382 // Otherwise, collect any calls in the new expression that couldn't be inlined.
383 2 Expression.apply(outExp, function collectFunctions(funcs = funcs));
384 end if;
385 end if;
386 then
387 outExp;
388
389 else exp;
390 end match;
391 end inlineFunctions_traverser;
392
393 function collectFunctions
394 input Expression exp;
395 input UnorderedSet<Function> funcs;
396 algorithm
397 () := match exp
398 case Expression.CALL()
399 algorithm
400 1 collectFunction(Call.typedFunction(exp.call), funcs);
401 then
402 ();
403
404 else ();
405 end match;
406 end collectFunctions;
407
408 function collectFunction
409 input Function fn;
410 input UnorderedSet<Function> funcs;
411 algorithm
412
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2 if not Function.isBuiltin(fn) then
413 1 UnorderedSet.add(fn, funcs);
414
415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 for fn_der in fn.derivatives loop
416 ✗ for der_fn in Function.getCachedFuncs(InstNode.borrow(fn_der.derivativeFn)) loop
417 ✗ UnorderedSet.add(der_fn, funcs);
418 end for;
419 end for;
420
421
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
2 for fn_inv in fn.inverses loop
422 ✗ UnorderedSet.add(FunctionInverse.getFunction(fn_inv), funcs);
423 end for;
424 end if;
425 end collectFunction;
426
427 function collectFlatTypes
428 input FlatModel flatModel;
429 input list<Function> functions;
430 output list<Type> outTypes;
431 protected
432 TypeMap types;
433 algorithm
434 32 types := UnorderedMap.new<Type>(AbsynUtil.pathHash, AbsynUtil.pathEqual);
435 32 List.map1_0(flatModel.variables, collectVariableFlatTypes, types);
436 32 List.map1_0(flatModel.equations, collectEquationFlatTypes, types);
437 32 List.map1_0(flatModel.initialEquations, collectEquationFlatTypes, types);
438 32 List.map1_0(flatModel.algorithms, collectAlgorithmFlatTypes, types);
439 32 List.map1_0(flatModel.initialAlgorithms, collectAlgorithmFlatTypes, types);
440 32 List.map1_0(functions, collectFunctionFlatTypes, types);
441 32 outTypes := UnorderedMap.valueList(types);
442
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 32 times.
60 outTypes := list(typeFlatType(ty) for ty in outTypes);
443 end collectFlatTypes;
444
445 function collectVariableFlatTypes
446 input Variable var;
447 input TypeMap types;
448 algorithm
449 847 collectFlatType(var.ty, types);
450 847 collectBindingFlatTypes(var.binding, types);
451
452
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 847 times.
882 for attr in var.typeAttributes loop
453 35 collectBindingFlatTypes(Util.tuple22(attr), types);
454 end for;
455 end collectVariableFlatTypes;
456
457 function collectFlatType
458 input Type ty;
459 input TypeMap types;
460 algorithm
461 () := match ty
462 case Type.ENUMERATION()
463 guard not Type.isBuiltinEnumeration(ty)
464 algorithm
465 7 UnorderedMap.tryAdd(ty.typePath, ty, types);
466 then
467 ();
468
469 case Type.ARRAY()
470 algorithm
471 852 Dimension.foldExpList(ty.dimensions, collectExpFlatTypes_traverse, types);
472 852 collectFlatType(ty.elementType, types);
473 then
474 ();
475
476 case Type.COMPLEX(complexTy = ComplexType.RECORD())
477 algorithm
478 430 UnorderedMap.tryAdd(InstNode.scopePath(Type.complexNode(ty)), ty, types);
479 then
480 ();
481
482 case Type.COMPLEX(complexTy = ComplexType.EXTERNAL_OBJECT())
483 algorithm
484 ✗ UnorderedMap.tryAdd(InstNode.scopePath(Type.complexNode(ty)), ty, types);
485 then
486 ();
487
488 case Type.FUNCTION(fnType = NFType.FunctionType.FUNCTIONAL_PARAMETER)
489 algorithm
490 ✗ UnorderedMap.tryAdd(InstNode.scopePath(InstNode.fromHandle(ty.fn.node)), ty, types);
491 then
492 ();
493
494 else ();
495 end match;
496 end collectFlatType;
497
498 function collectBindingFlatTypes
499 input Binding binding;
500 input TypeMap types;
501 algorithm
502
2/2
✓ Branch 1 taken 738 times.
✓ Branch 2 taken 234 times.
972 if Binding.isExplicitlyBound(binding) then
503 234 collectExpFlatTypes(Binding.getTypedExp(binding), types);
504 end if;
505 end collectBindingFlatTypes;
506
507 function collectEquationFlatTypes
508 input Equation eq;
509 input TypeMap types;
510 algorithm
511 () := match eq
512 case Equation.EQUALITY()
513 algorithm
514 356 collectExpFlatTypes(eq.lhs, types);
515 356 collectExpFlatTypes(eq.rhs, types);
516 356 collectFlatType(eq.ty, types);
517 then
518 ();
519
520 case Equation.FOR()
521 algorithm
522
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 if isSome(eq.range) then
523 18 collectExpFlatTypes(Util.getOption(eq.range), types);
524 end if;
525
526 18 List.map1_0(eq.body, collectEquationFlatTypes, types);
527 then
528 ();
529
530 case Equation.IF()
531 algorithm
532 1 List.map1_0(eq.branches, collectEqBranchFlatTypes, types);
533 then
534 ();
535
536 case Equation.WHEN()
537 algorithm
538 ✗ List.map1_0(eq.branches, collectEqBranchFlatTypes, types);
539 then
540 ();
541
542 case Equation.ASSERT()
543 algorithm
544 ✗ collectExpFlatTypes(eq.condition, types);
545 ✗ collectExpFlatTypes(eq.message, types);
546 ✗ collectExpFlatTypes(eq.level, types);
547 then
548 ();
549
550 case Equation.TERMINATE()
551 algorithm
552 ✗ collectExpFlatTypes(eq.message, types);
553 then
554 ();
555
556 case Equation.REINIT()
557 algorithm
558 ✗ collectExpFlatTypes(eq.reinitExp, types);
559 then
560 ();
561
562 case Equation.NORETCALL()
563 algorithm
564 ✗ collectExpFlatTypes(eq.exp, types);
565 then
566 ();
567
568 else ();
569 end match;
570 end collectEquationFlatTypes;
571
572 function collectEqBranchFlatTypes
573 input Equation.Branch branch;
574 input TypeMap types;
575 algorithm
576 () := match branch
577 case Equation.Branch.BRANCH()
578 algorithm
579 3 collectExpFlatTypes(branch.condition, types);
580 3 List.map1_0(branch.body, collectEquationFlatTypes, types);
581 then
582 ();
583
584 else ();
585 end match;
586 end collectEqBranchFlatTypes;
587
588 function collectAlgorithmFlatTypes
589 input Algorithm alg;
590 input TypeMap types;
591 algorithm
592 ✗ collectStatementsFlatTypes(alg.statements, types);
593 end collectAlgorithmFlatTypes;
594
595 function collectStatementsFlatTypes
596 input list<Statement> statements;
597 input TypeMap types;
598 algorithm
599
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 27 times.
31 for s in statements loop
600 4 collectStatementFlatTypes(s, types);
601 end for;
602 end collectStatementsFlatTypes;
603
604 function collectStatementFlatTypes
605 input Statement stmt;
606 input TypeMap types;
607 algorithm
608 () := match stmt
609 case Statement.ASSIGNMENT()
610 algorithm
611 4 collectExpFlatTypes(stmt.lhs, types);
612 4 collectExpFlatTypes(stmt.rhs, types);
613 4 collectFlatType(stmt.ty, types);
614 then
615 ();
616
617 case Statement.FOR()
618 algorithm
619 ✗ collectStatementsFlatTypes(stmt.body, types);
620 ✗ collectExpFlatTypes(Util.getOption(stmt.range), types);
621 then
622 ();
623
624 case Statement.IF()
625 algorithm
626 ✗ List.map1_0(stmt.branches, collectStmtBranchFlatTypes, types);
627 then
628 ();
629
630 case Statement.WHEN()
631 algorithm
632 ✗ List.map1_0(stmt.branches, collectStmtBranchFlatTypes, types);
633 then
634 ();
635
636 case Statement.ASSERT()
637 algorithm
638 ✗ collectExpFlatTypes(stmt.condition, types);
639 ✗ collectExpFlatTypes(stmt.message, types);
640 ✗ collectExpFlatTypes(stmt.level, types);
641 then
642 ();
643
644 case Statement.TERMINATE()
645 algorithm
646 ✗ collectExpFlatTypes(stmt.message, types);
647 then
648 ();
649
650 case Statement.REINIT()
651 algorithm
652 ✗ collectExpFlatTypes(stmt.cref, types);
653 ✗ collectExpFlatTypes(stmt.reinitExp, types);
654 then
655 ();
656
657 case Statement.NORETCALL()
658 algorithm
659 ✗ collectExpFlatTypes(stmt.exp, types);
660 then
661 ();
662
663 case Statement.WHILE()
664 algorithm
665 ✗ collectExpFlatTypes(stmt.condition, types);
666 ✗ collectStatementsFlatTypes(stmt.body, types);
667 then
668 ();
669
670 else ();
671 end match;
672 end collectStatementFlatTypes;
673
674 function collectStmtBranchFlatTypes
675 input tuple<Expression, list<Statement>> branch;
676 input TypeMap types;
677 algorithm
678 ✗ collectExpFlatTypes(Util.tuple21(branch), types);
679 ✗ collectStatementsFlatTypes(Util.tuple22(branch), types);
680 end collectStmtBranchFlatTypes;
681
682 function collectExpFlatTypes
683 input Expression exp;
684 input TypeMap types;
685 algorithm
686 975 Expression.fold(exp, collectExpFlatTypes_traverse, types);
687 end collectExpFlatTypes;
688
689 function collectExpFlatTypes_traverse
690 input Expression exp;
691 input output TypeMap types;
692 algorithm
693 3433 collectFlatType(Expression.typeOf(exp), types);
694 end collectExpFlatTypes_traverse;
695
696 function collectFunctionFlatTypes
697 input Function fn;
698 input TypeMap types;
699 algorithm
700 28 ClassTree.applyComponents(Class.classTree(InstNode.getClass(InstNode.fromHandle(fn.node))),
701 function collectComponentFlatTypes(types = types));
702
703
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 27 times.
28 if not Function.isExternal(fn) then
704 27 collectStatementsFlatTypes(Function.getBody(fn), types);
705 end if;
706 end collectFunctionFlatTypes;
707
708 function collectComponentFlatTypes
709 input InstNode component;
710 input TypeMap types;
711 protected
712 Component comp;
713 algorithm
714 90 comp := InstNode.component(component);
715 90 collectFlatType(Component.getType(comp), types);
716 90 collectBindingFlatTypes(Component.getBinding(comp), types);
717 end collectComponentFlatTypes;
718
719 function reconstructRecordInstances
720 input list<Variable> variables;
721 output list<Variable> outVariables = {};
722 protected
723 list<Variable> rest_vars = variables, record_vars;
724 Variable var;
725 ComponentRef parent_cr;
726 Type parent_ty;
727 Integer field_count;
728 algorithm
729
2/2
✓ Branch 0 taken 826 times.
✓ Branch 1 taken 27 times.
853 while not listEmpty(rest_vars) loop
730 826 var :: rest_vars := rest_vars;
731 826 parent_cr := ComponentRef.rest(var.name);
732
733
2/2
✓ Branch 1 taken 789 times.
✓ Branch 2 taken 37 times.
826 if not ComponentRef.isEmpty(parent_cr) then
734 789 parent_ty := ComponentRef.nodeType(parent_cr);
735
736
2/2
✓ Branch 1 taken 97 times.
✓ Branch 2 taken 692 times.
789 if Type.isRecord(parent_ty) then
737 97 field_count := listLength(Type.recordFields(parent_ty));
738 97 (record_vars, rest_vars) := List.split(rest_vars, field_count - 1);
739 record_vars := var :: record_vars;
740 97 var := reconstructRecordInstance(parent_cr, record_vars);
741 end if;
742 end if;
743
744 outVariables := var :: outVariables;
745 end while;
746
747 27 outVariables := listReverseInPlace(outVariables);
748 end reconstructRecordInstances;
749
750 function reconstructRecordInstance
751 "Reconstructs a record instance variable from its individual field variables."
752 input ComponentRef recordName;
753 input list<Variable> variables;
754 output Variable recordVar;
755 protected
756 InstNode record_node;
757 Component record_comp;
758 Type record_ty;
759 list<Expression> field_exps;
760 Expression record_exp;
761 Binding record_binding;
762 algorithm
763 97 record_node := ComponentRef.node(recordName);
764 97 record_comp := InstNode.component(record_node);
765 97 record_ty := ComponentRef.nodeType(recordName);
766
767 // Reconstruct the record instance binding if possible. If any field is
768 // missing a binding we assume that the record instance didn't have a
769 // binding in the first place, or that the binding was moved to an equation
770 // during flattening.
771 field_exps := {};
772
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 20 times.
170 for v in variables loop
773
2/2
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 77 times.
150 if Binding.hasExp(v.binding) then
774 73 field_exps := Binding.getExp(v.binding) :: field_exps;
775 else
776 field_exps := {};
777 break;
778 end if;
779 end for;
780
781
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 77 times.
97 if listEmpty(field_exps) then
782 record_binding := NFBinding.EMPTY_BINDING;
783 else
784 20 field_exps := listReverseInPlace(field_exps);
785 20 record_exp := Expression.makeRecord(InstNode.scopePath(InstNode.classScope(record_node)), record_ty, field_exps);
786 20 record_binding := Binding.makeFlat(record_exp, Component.variability(record_comp), NFBinding.Source.GENERATED);
787 end if;
788
789 97 recordVar := Variable.VARIABLE(recordName, record_ty, record_binding, InstNode.visibility(record_node),
790 Component.getAttributes(record_comp), {}, variables, Component.comment(record_comp), InstNode.info(record_node), NFBackendExtension.DUMMY_BACKEND_INFO);
791 end reconstructRecordInstance;
792
793 function typeFlatType
794 input output Type ty;
795 algorithm
796 () := match ty
797 case Type.COMPLEX(complexTy = ComplexType.RECORD())
798 algorithm
799 26 Typing.typeBindings(Type.complexNode(ty), NFInstContext.CLASS);
800 then
801 ();
802
803 else ();
804 end match;
805 end typeFlatType;
806
807 protected
808 type ObfuscationMap = UnorderedMap<InstNode, String>;
809
810 public
811 function obfuscate
812 input output FlatModel flatModel;
813 protected
814 ObfuscationMap obfuscation_map;
815 Boolean only_encrypted;
816 algorithm
817
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
7 only_encrypted := Flags.getConfigString(Flags.OBFUSCATE) == "encrypted";
818 7 obfuscation_map := UnorderedMap.new<String>(InstNode.hash, InstNode.refEqual);
819
820
2/2
✓ Branch 0 taken 12330 times.
✓ Branch 1 taken 7 times.
12337 for v in flatModel.variables loop
821 12330 addObfuscatedVariable(v, only_encrypted, obfuscation_map);
822 end for;
823
824
4/4
✓ Branch 0 taken 12330 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 12330 times.
✓ Branch 3 taken 7 times.
12344 flatModel.variables := list(obfuscateVariable(v, obfuscation_map) for v in flatModel.variables);
825 7 flatModel := mapEquations(flatModel, function obfuscateEquation(obfuscationMap = obfuscation_map));
826 7 flatModel := mapAlgorithms(flatModel, function obfuscateAlgorithm(obfuscationMap = obfuscation_map));
827 end obfuscate;
828
829 function addObfuscatedVariable
830 input Variable var;
831 input Boolean onlyEncrypted;
832 input ObfuscationMap obfuscationMap;
833 protected
834 list<InstNode> nodes;
835 algorithm
836
3/6
✓ Branch 1 taken 10453 times.
✓ Branch 2 taken 1877 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1877 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12330 if Variable.isProtected(var) and (not onlyEncrypted or Variable.isEncrypted(var)) then
837 1877 nodes := ComponentRef.nodes(var.name);
838 1877 nodes := List.trim(nodes, InstNode.isPublic);
839
840
2/2
✓ Branch 0 taken 1877 times.
✓ Branch 1 taken 1877 times.
3754 for node in nodes loop
841 1877 UnorderedMap.tryAdd(node, "n" + String(UnorderedMap.size(obfuscationMap) + 1), obfuscationMap);
842 end for;
843 end if;
844 end addObfuscatedVariable;
845
846 function obfuscateVariable
847 input output Variable var;
848 input ObfuscationMap obfuscationMap;
849 algorithm
850 12330 var.name := obfuscateCref(var.name, obfuscationMap);
851 12330 var.comment := obfuscateComment(var.comment, ComponentRef.node(var.name),
852 obfuscationMap, stripComment = not Variable.isAccessible(var));
853 12330 var := Variable.mapExpShallow(var, function obfuscateExp(obfuscationMap = obfuscationMap));
854 end obfuscateVariable;
855
856 function obfuscateCref
857 input output ComponentRef cref;
858 input ObfuscationMap obfuscationMap;
859 output Boolean insideRecord = false;
860 protected
861 Option<String> name;
862 ComponentRef rest_cref;
863 algorithm
864 () := match cref
865 case ComponentRef.CREF()
866 algorithm
867 136992 (rest_cref, insideRecord) := obfuscateCref(cref.restCref, obfuscationMap);
868
2/2
✓ Branch 0 taken 132764 times.
✓ Branch 1 taken 4228 times.
136992 cref.restCref := rest_cref;
869
870 // Only obfuscate variables that do not belong to a record instance,
871 // record field names need to be kept to keep them consistent with the
872 // record constructors.
873
2/2
✓ Branch 0 taken 132764 times.
✓ Branch 1 taken 4228 times.
136992 if not insideRecord then
874 132764 name := UnorderedMap.get(ComponentRef.node(cref), obfuscationMap);
875
876
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 132764 times.
✓ Branch 2 taken 6223 times.
✓ Branch 3 taken 126541 times.
132764 if isSome(name) then
877 6223 cref.node := ComponentRef.storeNode(
878 InstNode.rename(Util.getOption(name), ComponentRef.node(cref)));
879 end if;
880 end if;
881
882 136992 insideRecord := InstNode.isRecord(ComponentRef.node(cref));
883
884
4/4
✓ Branch 0 taken 39909 times.
✓ Branch 1 taken 136992 times.
✓ Branch 2 taken 39909 times.
✓ Branch 3 taken 136992 times.
313893 cref.subscripts := list(Subscript.mapShallowExp(s,
885 function obfuscateExp(obfuscationMap = obfuscationMap)) for s in cref.subscripts);
886 then
887 ();
888
889 else ();
890 end match;
891 end obfuscateCref;
892
893 function obfuscateExp
894 input output Expression exp;
895 input ObfuscationMap obfuscationMap;
896 algorithm
897 109930 exp := Expression.map(exp, function obfuscateExp_impl(obfuscationMap = obfuscationMap));
898 end obfuscateExp;
899
900 function obfuscateExpOpt
901 input output Option<Expression> exp;
902 input ObfuscationMap obfuscationMap;
903 algorithm
904 ✗ if isSome(exp) then
905 ✗ exp := SOME(obfuscateExp(Util.getOption(exp), obfuscationMap));
906 end if;
907 end obfuscateExpOpt;
908
909 function obfuscateExp_impl
910 input output Expression exp;
911 input ObfuscationMap obfuscationMap;
912 algorithm
913 () := match exp
914 case Expression.CREF()
915 algorithm
916 39623 exp.cref := obfuscateCref(exp.cref, obfuscationMap);
917 then
918 ();
919
920 else ();
921 end match;
922 end obfuscateExp_impl;
923
924 function obfuscateEquation
925 input output Equation eq;
926 input ObfuscationMap obfuscationMap;
927 algorithm
928 9100 eq := Equation.setSource(obfuscateSource(Equation.source(eq), Equation.scope(eq), obfuscationMap), eq);
929 9100 eq := Equation.mapExpShallow(eq, function obfuscateExp(obfuscationMap = obfuscationMap));
930 end obfuscateEquation;
931
932 function obfuscateAlgorithm
933 input output Algorithm alg;
934 input ObfuscationMap obfuscationMap;
935 algorithm
936 ✗ alg.source := obfuscateSource(alg.source, InstNode.fromCell(alg.scope), obfuscationMap);
937 alg.inputs := list(obfuscateCref(e, obfuscationMap) for e in alg.inputs);
938 alg.outputs := list(obfuscateCref(e, obfuscationMap) for e in alg.outputs);
939 alg.statements := list(Statement.map(s,
940 function obfuscateStatement(scope = InstNode.fromCell(alg.scope), obfuscationMap = obfuscationMap)) for s in alg.statements);
941 end obfuscateAlgorithm;
942
943 function obfuscateStatement
944 input output Statement stmt;
945 input InstNode scope;
946 input ObfuscationMap obfuscationMap;
947 algorithm
948 ✗ stmt := Statement.setSource(obfuscateSource(Statement.source(stmt), scope, obfuscationMap), stmt);
949 ✗ stmt := Statement.mapExpShallow(stmt, function obfuscateExp(obfuscationMap = obfuscationMap));
950 end obfuscateStatement;
951
952 function obfuscateSource
953 input output DAE.ElementSource source;
954 input InstNode scope;
955 input ObfuscationMap obfuscationMap;
956 algorithm
957
4/4
✓ Branch 0 taken 8107 times.
✓ Branch 1 taken 9100 times.
✓ Branch 2 taken 8107 times.
✓ Branch 3 taken 9100 times.
17207 source.comment := list(obfuscateComment(c, scope, obfuscationMap) for c in source.comment);
958 end obfuscateSource;
959
960 function obfuscateCommentOpt
961 input output Option<SCode.Comment> comment;
962 input InstNode scope;
963 input ObfuscationMap obfuscationMap;
964 input Boolean stripComment = true;
965 algorithm
966 ✗ comment := Util.applyOption(comment,
967 function obfuscateComment(scope = scope, obfuscationMap = obfuscationMap, stripComment = stripComment));
968 end obfuscateCommentOpt;
969
970 function obfuscateComment
971 input output SCode.Comment comment;
972 input InstNode scope;
973 input ObfuscationMap obfuscationMap;
974 input Boolean stripComment = true;
975 algorithm
976 20437 comment.annotation_ := obfuscateAnnotationOpt(comment.annotation_, scope, obfuscationMap);
977
978
2/2
✓ Branch 0 taken 12330 times.
✓ Branch 1 taken 8107 times.
20437 if stripComment then
979 8107 comment.comment := NONE();
980 end if;
981 end obfuscateComment;
982
983 function obfuscateAnnotationOpt
984 input output Option<SCode.Annotation> ann;
985 input InstNode scope;
986 input ObfuscationMap obfuscationMap;
987 algorithm
988 20437 ann := Util.applyOption(ann,
989 function obfuscateAnnotation(scope = scope, obfuscationMap = obfuscationMap));
990 end obfuscateAnnotationOpt;
991
992 function obfuscateAnnotation
993 input output SCode.Annotation ann;
994 input InstNode scope;
995 input ObfuscationMap obfuscationMap;
996 algorithm
997 2374 ann.modification := obfuscateAnnotationMod(ann.modification, scope, obfuscationMap);
998 end obfuscateAnnotation;
999
1000 function obfuscateAnnotationMod
1001 input output SCode.Mod mod;
1002 input InstNode scope;
1003 input ObfuscationMap obfuscationMap;
1004 algorithm
1005 () := match mod
1006 case SCode.Mod.MOD()
1007 algorithm
1008
6/6
✓ Branch 1 taken 2234 times.
✓ Branch 2 taken 1285 times.
✓ Branch 3 taken 3519 times.
✓ Branch 4 taken 3659 times.
✓ Branch 5 taken 1285 times.
✓ Branch 6 taken 3659 times.
10837 mod.subModLst := list(obfuscateAnnotationSubMod(s, scope, obfuscationMap)
1009 for s guard isAllowedAnnotation(s) in mod.subModLst);
1010 3659 mod.binding := obfuscateAbsynExpOpt(mod.binding, scope, obfuscationMap);
1011 then
1012 ();
1013
1014 else ();
1015 end match;
1016 end obfuscateAnnotationMod;
1017
1018 function isAllowedAnnotation
1019 input SCode.SubMod mod;
1020 output Boolean allowed;
1021 algorithm
1022 allowed := match mod.ident
1023 case "Icon" then false;
1024 case "Diagram" then false;
1025 case "Dialog" then false;
1026 case "IconMap" then false;
1027 case "DiagramMap" then false;
1028 case "Placement" then false;
1029 case "Text" then false;
1030 case "Line" then false;
1031 case "defaultComponentName" then false;
1032 case "defaultComponentPrefixes" then false;
1033 case "missingInnerMessage" then false;
1034 case "obsolete" then false;
1035 case "unassignedMessage" then false;
1036 case "Protection" then false;
1037 case "Authorization" then false;
1038 1285 else not StringUtil.startsWith(mod.ident, "__");
1039 end match;
1040 end isAllowedAnnotation;
1041
1042 function obfuscateAnnotationSubMod
1043 input output SCode.SubMod mod;
1044 input InstNode scope;
1045 input ObfuscationMap obfuscationMap;
1046 algorithm
1047 1285 mod.mod := obfuscateAnnotationMod(mod.mod, scope, obfuscationMap);
1048 end obfuscateAnnotationSubMod;
1049
1050 function obfuscateAbsynExpOpt
1051 input output Option<Absyn.Exp> exp;
1052 input InstNode scope;
1053 input ObfuscationMap obfuscationMap;
1054 algorithm
1055 3659 exp := Util.applyOption(exp,
1056 function obfuscateAbsynExp(scope = scope, obfuscationMap = obfuscationMap));
1057 end obfuscateAbsynExpOpt;
1058
1059 function obfuscateAbsynExp
1060 input output Absyn.Exp exp;
1061 input InstNode scope;
1062 input ObfuscationMap obfuscationMap;
1063 algorithm
1064 1229 exp := AbsynUtil.traverseExp(exp, function obfuscateAbsynExpTraverse(scope = scope), obfuscationMap);
1065 end obfuscateAbsynExp;
1066
1067 function obfuscateAbsynExpTraverse
1068 input output Absyn.Exp exp;
1069 input InstNode scope;
1070 input output ObfuscationMap obfuscationMap;
1071 algorithm
1072 () := match exp
1073 case Absyn.Exp.CREF()
1074 algorithm
1075 ✗ exp.componentRef := obfuscateAbsynCref(exp.componentRef, scope, obfuscationMap);
1076 then
1077 ();
1078
1079 else ();
1080 end match;
1081 end obfuscateAbsynExpTraverse;
1082
1083 function obfuscateAbsynCref
1084 input output Absyn.ComponentRef cref;
1085 input InstNode scope;
1086 input ObfuscationMap obfuscationMap;
1087 protected
1088 ComponentRef inst_cref;
1089 list<InstNode> nodes;
1090 algorithm
1091 ✗ ErrorExt.setCheckpoint(getInstanceName());
1092 try
1093 ✗ inst_cref := Lookup.lookupCref(cref, scope, NFInstContext.RELAXED);
1094 ✗ nodes := list(ComponentRef.node(c) for c in ComponentRef.toListReverse(inst_cref, includeScope = false));
1095 ✗ cref := obfuscateAbsynCref2(cref, nodes, obfuscationMap);
1096 else
1097 end try;
1098 ✗ ErrorExt.rollBack(getInstanceName());
1099 end obfuscateAbsynCref;
1100
1101 function obfuscateAbsynCref2
1102 input output Absyn.ComponentRef cref;
1103 input list<InstNode> nodes;
1104 input ObfuscationMap obfuscationMap;
1105 protected
1106 InstNode node;
1107 list<InstNode> rest_nodes;
1108 algorithm
1109 () := match (cref, nodes)
1110 case (Absyn.ComponentRef.CREF_FULLYQUALIFIED(), _)
1111 algorithm
1112 ✗ cref.componentRef := obfuscateAbsynCref2(cref.componentRef, nodes, obfuscationMap);
1113 then
1114 ();
1115
1116 case (Absyn.ComponentRef.CREF_QUAL(), node :: rest_nodes)
1117 guard InstNode.name(node) == cref.name
1118 algorithm
1119 ✗ cref.name := UnorderedMap.getOrDefault(node, obfuscationMap, cref.name);
1120 ✗ cref.componentRef := obfuscateAbsynCref2(cref.componentRef, rest_nodes, obfuscationMap);
1121 then
1122 ();
1123
1124 case (Absyn.ComponentRef.CREF_IDENT(), node :: _)
1125 guard InstNode.name(node) == cref.name
1126 algorithm
1127 ✗ cref.name := UnorderedMap.getOrDefault(node, obfuscationMap, cref.name);
1128 then
1129 ();
1130
1131 else ();
1132 end match;
1133 end obfuscateAbsynCref2;
1134
1135 function hasArrayConnections
1136 input FlatModel flatModel;
1137 input Integer minSize = 100;
1138 output Boolean hasArrays = false;
1139 algorithm
1140 ✗ for eq in flatModel.equations loop
1141 ✗ if Equation.contains(eq, Equation.isConnect) and Equation.sizeOf(eq) >= minSize then
1142 hasArrays := true;
1143 ✗ return;
1144 end if;
1145 end for;
1146 end hasArrayConnections;
1147
1148 function removeNonTopLevelDirections
1149 input output FlatModel flatModel;
1150 algorithm
1151 // Keep the declared directions if --useLocalDirection=true has been set.
1152
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1430 times.
1430 if Flags.getConfigBool(Flags.USE_LOCAL_DIRECTION) then
1153 ✗ return;
1154 end if;
1155
1156
4/4
✓ Branch 0 taken 378211 times.
✓ Branch 1 taken 1430 times.
✓ Branch 2 taken 378211 times.
✓ Branch 3 taken 1430 times.
381071 flatModel.variables := list(Variable.removeNonTopLevelDirection(v) for v in flatModel.variables);
1157 end removeNonTopLevelDirections;
1158
1159 function moveBindings
1160 "Moves binding equations of variables to the equation section of the flat model."
1161 input output FlatModel flatModel;
1162 protected
1163 list<Variable> vars = {};
1164 list<Equation> eqs = {};
1165 algorithm
1166 ✗ for var in flatModel.variables loop
1167 ✗ (var, eqs) := Variable.moveBinding(var, eqs);
1168 vars := var :: vars;
1169 end for;
1170
1171 ✗ if not listEmpty(eqs) then
1172 ✗ flatModel.variables := listReverseInPlace(vars);
1173 flatModel.equations := listAppend(listReverseInPlace(eqs), flatModel.equations);
1174 end if;
1175 end moveBindings;
1176
1177 annotation(__OpenModelica_Interface="nf_frontend");
1178 end NFFlatModel;
1179