Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 81.2% 151 / 0 / 186
Functions: -% 0 / 1 / 1
Branches: 44.4% 63 / 0 / 142

OMCompiler/Compiler/FrontEnd/InstBinding.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 InstBinding
37 " file: InstBinding.mo
38 package: InstBinding
39 description: Binding instantiation
40
41
42 This module is responsible for instantiation of bindings.
43 "
44
45 public import Absyn;
46 public import AbsynUtil;
47 public import ClassInf;
48 public import DAE;
49 public import FCore;
50 public import FGraph;
51 public import InnerOuter;
52 public import Mod;
53 public import SCode;
54 public import Values;
55
56 protected type Ident = DAE.Ident "an identifier";
57 protected type InstanceHierarchy = InnerOuter.InstHierarchy "an instance hierarchy";
58 protected type InstDims = list<list<DAE.Dimension>>;
59
60 protected import Ceval;
61 protected import ComponentReference;
62 protected import ComponentReferenceBasics;
63 protected import ElementSource;
64 protected import Error;
65 protected import Expression;
66 protected import ExpressionSimplify;
67 protected import InstUtil;
68 protected import List;
69 protected import Flags;
70 protected import Debug;
71 protected import DAEUtil;
72 protected import PrefixUtil;
73 import SCodeUtil;
74 protected import Types;
75 protected import InstSection;
76 protected import ValuesUtil;
77 protected import ExpressionBasics;
78
79 public constant DAE.Type stateSelectType =
80 DAE.T_ENUMERATION(NONE(),Absyn.IDENT(""),{"never","avoid","default","prefer","always"},
81 {
82 DAE.TYPES_VAR("never",DAE.dummyAttrParam,
83 DAE.T_ENUMERATION(SOME(1),Absyn.IDENT(""),{"never","avoid","default","prefer","always"},{},{}),DAE.UNBOUND(),false,NONE()),
84 DAE.TYPES_VAR("avoid",DAE.dummyAttrParam,
85 DAE.T_ENUMERATION(SOME(2),Absyn.IDENT(""),{"never","avoid","default","prefer","always"},{},{}),DAE.UNBOUND(),false,NONE()),
86 DAE.TYPES_VAR("default",DAE.dummyAttrParam,
87 DAE.T_ENUMERATION(SOME(3),Absyn.IDENT(""),{"never","avoid","default","prefer","always"},{},{}),DAE.UNBOUND(),false,NONE()),
88 DAE.TYPES_VAR("prefer",DAE.dummyAttrParam,
89 DAE.T_ENUMERATION(SOME(4),Absyn.IDENT(""),{"never","avoid","default","prefer","always"},{},{}),DAE.UNBOUND(),false,NONE()),
90 DAE.TYPES_VAR("always",DAE.dummyAttrParam,
91 DAE.T_ENUMERATION(SOME(5),Absyn.IDENT(""),{"never","avoid","default","prefer","always"},{},{}),DAE.UNBOUND(),false,NONE())
92 },{});
93
94 public constant DAE.Type uncertaintyType =
95 DAE.T_ENUMERATION(NONE(),Absyn.IDENT(""),{"given","sought","refine","propagate"},
96 {
97 DAE.TYPES_VAR("given",DAE.dummyAttrParam,
98 DAE.T_ENUMERATION(SOME(1),Absyn.IDENT(""),{"given","sought","refine","propagate"},{},{}),DAE.UNBOUND(),false,NONE()),
99 DAE.TYPES_VAR("sought",DAE.dummyAttrParam,
100 DAE.T_ENUMERATION(SOME(2),Absyn.IDENT(""),{"given","sought","refine","propagate"},{},{}),DAE.UNBOUND(),false,NONE()),
101 DAE.TYPES_VAR("refine",DAE.dummyAttrParam,
102 DAE.T_ENUMERATION(SOME(3),Absyn.IDENT(""),{"given","sought","refine","propagate"},{},{}),DAE.UNBOUND(),false,NONE()),
103 DAE.TYPES_VAR("propagate",DAE.dummyAttrParam,
104 DAE.T_ENUMERATION(SOME(4),Absyn.IDENT(""),{"given","sought","refine","propagate"},{},{}),DAE.UNBOUND(),false,NONE())
105 },{});
106
107 public constant DAE.Type distributionType =
108 DAE.T_COMPLEX(ClassInf.RECORD(Absyn.IDENT("Distribution")),
109 {
110 DAE.TYPES_VAR(
111 "name",
112 DAE.ATTR(DAE.NON_CONNECTOR(),SCode.NON_PARALLEL(),SCode.PARAM(),Absyn.BIDIR(),Absyn.NOT_INNER_OUTER(),SCode.PUBLIC()),
113 DAE.T_STRING_DEFAULT,
114 DAE.UNBOUND(), // binding
115 false,
116 NONE()),
117 DAE.TYPES_VAR(
118 "params",
119 DAE.ATTR(DAE.NON_CONNECTOR(),SCode.NON_PARALLEL(),SCode.PARAM(),Absyn.BIDIR(),Absyn.NOT_INNER_OUTER(),SCode.PUBLIC()),
120 DAE.T_ARRAY_REAL_NODIM,
121 DAE.UNBOUND(), // binding
122 false,
123 NONE()),
124 DAE.TYPES_VAR(
125 "paramNames",
126 DAE.ATTR(DAE.NON_CONNECTOR(),SCode.NON_PARALLEL(),SCode.PARAM(),Absyn.BIDIR(),Absyn.NOT_INNER_OUTER(),SCode.PUBLIC()),
127 DAE.T_ARRAY_STRING_NODIM,
128 DAE.UNBOUND(), // binding
129 false,
130 NONE())
131 },
132 NONE(),
133 false);
134
135 protected function instBinding
136 "This function investigates a modification and extracts the
137 <...> modification. E.g. Real x(<...>=1+3) => 1+3
138 It also handles the case Integer T0[2](final <...>={5,6})={9,10} becomes
139 Integer T0[1](<...>=5); Integer T0[2](<...>=6);
140
141 If no modifier is given it also investigates the type to check for binding there.
142 I.e. type A = Real(start=1); A a; will set the start attribute since it's found in the type.
143
144 Arg 1 is the modification
145 Arg 2 are the type variables.
146 Arg 3 is the expected type that the modification should have
147 Arg 4 is the index list for the element: for T0{1,2} is {1,2}"
148 input DAE.Mod inMod;
149 input list<DAE.Var> inVarLst;
150 input DAE.Type inType;
151 input list<Integer> inIntegerLst;
152 input String inString;
153 input Boolean useConstValue "if true use constant value present in TYPED (if present)";
154 output Option<DAE.Exp> outExpExpOption;
155 algorithm
156 outExpExpOption := matchcontinue (inMod,inVarLst,inType,inIntegerLst,inString)
157 local
158 DAE.Mod mod2,mod;
159 DAE.Exp e,e_1;
160 DAE.Type ty2,expected_type,etype;
161 String bind_name;
162 Option<DAE.Exp> result;
163 list<Integer> index_list;
164 DAE.Binding binding;
165 Ident name;
166 Option<Values.Value> optVal;
167 list<DAE.Var> varLst;
168
169 case (mod,_,expected_type,{},bind_name) /* No subscript/index */
170 algorithm
171 12418013 mod2 := Mod.lookupCompModification(mod, bind_name);
172
5/8
✗ Branch 1 not taken.
✓ Branch 2 taken 12418013 times.
✓ Branch 3 taken 12326749 times.
✓ Branch 4 taken 91264 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 91264 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 91264 times.
12418013 SOME(DAE.TYPED(e,optVal,DAE.PROP(ty2,_),_)) := Mod.modEquation(mod2);
173 91264 (e_1,_) := Types.matchType(e, ty2, expected_type, true);
174 91120 e_1 := InstUtil.checkUseConstValue(useConstValue,e_1,optVal);
175 then
176 SOME(e_1);
177
178 case (mod,_,etype,index_list,bind_name) /* Have subscript/index */
179 algorithm
180 12326893 mod2 := Mod.lookupCompModification(mod, bind_name);
181 12326893 result := instBinding2(mod2, etype, index_list, bind_name, useConstValue);
182 then
183 result;
184
185 case (mod,_,_,{},bind_name) /* No modifier for this name. */
186 algorithm
187
1/2
✓ Branch 0 taken 12326893 times.
✗ Branch 1 not taken.
12326893 failure(Mod.lookupCompModification(mod, bind_name));
188 then
189 NONE();
190
191 case (_,DAE.TYPES_VAR(name=name,binding=binding)::_,_,_,bind_name)
192 algorithm
193
4/4
✓ Branch 0 taken 554020 times.
✓ Branch 1 taken 5067053 times.
✓ Branch 3 taken 123151 times.
✓ Branch 4 taken 430869 times.
5621073 true := stringEq(name, bind_name);
194 430869 then
195 DAEUtil.bindingExp(binding);
196
197 case (mod,_::varLst,etype,index_list,bind_name)
198 5190204 then instBinding(mod,varLst,etype,index_list,bind_name,useConstValue);
199
200 case (_,{},_,_,_)
201 then NONE();
202 end matchcontinue;
203 end instBinding;
204
205 protected function instBinding2
206 "This function investigates a modification and extracts the <...>
207 modification if the modification is in array of components.
208 Help-function to instBinding"
209 input DAE.Mod inMod;
210 input DAE.Type inType;
211 input list<Integer> inIntegerLst;
212 input String inString;
213 input Boolean useConstValue "if true, use constant value in TYPED (if present)";
214 output Option<DAE.Exp> outExpExpOption;
215 algorithm
216 outExpExpOption:=
217 match (inMod,inType,inIntegerLst,inString)
218 local
219 DAE.Mod mod2,mod;
220 DAE.Exp e,e_1;
221 DAE.Type ty2,etype;
222 Integer index;
223 String bind_name;
224 Option<DAE.Exp> result;
225 list<Integer> res;
226 Option<Values.Value> optVal;
227 case (mod,etype,(index :: {}),_) /* Only one element in the index-list */
228 algorithm
229 ✗ mod2 := Mod.lookupIdxModification(mod, DAE.ICONST(index));
230 ✗ SOME(DAE.TYPED(e,optVal,DAE.PROP(ty2,_),_)) := Mod.modEquation(mod2);
231 ✗ (e_1,_) := Types.matchType(e, ty2, etype, true);
232 ✗ e_1 := InstUtil.checkUseConstValue(useConstValue,e_1,optVal);
233 then
234 SOME(e_1);
235 case (mod,etype,(index :: res),bind_name) /* Several elements in the index-list */
236 algorithm
237 result := matchcontinue()
238 case ()
239 algorithm
240 ✗ mod2 := Mod.lookupIdxModification(mod, DAE.ICONST(index));
241 ✗ result := instBinding2(mod2, etype, res, bind_name,useConstValue);
242 then result;
243 else NONE();
244 end matchcontinue;
245 then
246 result;
247 end match;
248 end instBinding2;
249
250 public function instStartBindingExp
251 "This function investigates a modification and extracts the
252 start modification. E.g. Real x(start=1+3) => 1+3
253 It also handles the case Integer T0{2}(final start={5,6})={9,10} becomes
254 Integer T0{1}(start=5); Integer T0{2}(start=6);
255
256 Arg 1 is the start modification
257 Arg 2 is the expected type that the modification should have
258 Arg 3 is variability of the element"
259 input DAE.Mod inMod;
260 input DAE.Type inExpectedType;
261 input SCode.Variability inVariability;
262 output DAE.StartValue outStartValue;
263 algorithm
264
2/2
✓ Branch 1 taken 423500 times.
✓ Branch 2 taken 103066 times.
526566 if SCodeUtil.isConstant(inVariability) then
265 outStartValue := NONE();
266 else
267 // When instantiating arrays, the array type is passed.
268 // But binding is performed on the element type.
269 423500 outStartValue := instBinding(inMod, {},
270 Types.arrayElementType(inExpectedType), {}, "start", false);
271 end if;
272 end instStartBindingExp;
273
274 protected function instStartOrigin
275 "This function investigates if the start value comes from the modification or the type"
276 input DAE.Mod inMod;
277 input list<DAE.Var> inVarLst;
278 input String inString;
279 output Option<DAE.StartOrigin> outStartOrigin;
280 algorithm
281 outStartOrigin := matchcontinue (inMod,inVarLst,inString)
282 local
283 DAE.Mod mod2,mod;
284 String bind_name;
285 Ident name;
286 list<DAE.Var> varLst;
287
288 case (mod,_,bind_name)
289 algorithm
290 1022389 mod2 := Mod.lookupCompModification(mod, bind_name);
291
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1022389 times.
✓ Branch 3 taken 1002682 times.
✓ Branch 4 taken 19707 times.
1022389 SOME(_) := Mod.modEquation(mod2);
292 then
293 SOME(DAE.StartOrigin.BINDING_ORIGIN());
294
295 case (_,DAE.TYPES_VAR(name=name)::_,bind_name)
296 algorithm
297
4/4
✓ Branch 0 taken 19072 times.
✓ Branch 1 taken 357346 times.
✓ Branch 3 taken 18818 times.
✓ Branch 4 taken 254 times.
376418 true := stringEq(name, bind_name);
298 then
299 SOME(DAE.StartOrigin.TYPE_ORIGIN());
300
301 case (mod,_::varLst,bind_name)
302 357600 then instStartOrigin(mod,varLst,bind_name);
303
304 case (_,{},_)
305 then NONE();
306 end matchcontinue;
307 end instStartOrigin;
308
309 public function instDaeVariableAttributes
310 "this function extracts the attributes from the modification
311 It returns a DAE.VariableAttributes option because
312 somtimes a varible does not contain the variable-attr."
313 input FCore.Cache inCache;
314 input FCore.Graph inEnv;
315 input DAE.Mod inMod;
316 input DAE.Type inType;
317 input list<Integer> inIntegerLst;
318 output FCore.Cache outCache;
319 output Option<DAE.VariableAttributes> outDAEVariableAttributesOption;
320 algorithm
321 (outCache,outDAEVariableAttributesOption) :=
322 matchcontinue (inCache, inMod, inType, inIntegerLst)
323 local
324 Option<DAE.Exp> quantity_str,unit_str,displayunit_str,nominal_val,fixed_val,exp_bind_select,exp_bind_uncertainty,exp_bind_min,exp_bind_max,exp_bind_start,min_val,max_val,start_val;
325 Option<DAE.StartOrigin> startOrigin;
326 Option<DAE.StateSelect> stateSelect_value;
327 Option<DAE.Uncertainty> uncertainty_value;
328 Option<DAE.Distribution> distribution_value;
329 DAE.Mod mod;
330 list<Integer> index_list;
331 DAE.Type enumtype;
332 FCore.Cache cache;
333 DAE.Type tp;
334 list<DAE.Var> varLst;
335
336 // Real
337 case (cache, mod, DAE.T_REAL(varLst = varLst), index_list)
338 algorithm
339 448678 quantity_str := instBinding(mod, varLst, DAE.T_STRING_DEFAULT,index_list, "quantity",false);
340 448678 unit_str := instBinding(mod, varLst, DAE.T_STRING_DEFAULT, index_list, "unit",false);
341 448678 displayunit_str := instBinding(mod, varLst,DAE.T_STRING_DEFAULT, index_list, "displayUnit",false);
342 448678 min_val := instBinding(mod, varLst, DAE.T_REAL_DEFAULT,index_list, "min",false);
343 448678 max_val := instBinding(mod, varLst, DAE.T_REAL_DEFAULT,index_list, "max",false);
344 448678 start_val := instBinding(mod, varLst, DAE.T_REAL_DEFAULT,index_list, "start",false);
345 448678 fixed_val := instBinding( mod, varLst, DAE.T_BOOL_DEFAULT,index_list, "fixed",true);
346 448678 nominal_val := instBinding(mod, varLst, DAE.T_REAL_DEFAULT,index_list, "nominal",false);
347
348 448678 exp_bind_select := instEnumerationBinding(mod, varLst, index_list, "stateSelect",stateSelectType,true);
349 448678 stateSelect_value := InstUtil.getStateSelectFromExpOption(exp_bind_select);
350
351 448678 exp_bind_uncertainty := instEnumerationBinding(mod, varLst, index_list, "uncertain",uncertaintyType,true);
352 448678 uncertainty_value := getUncertainFromExpOption(exp_bind_uncertainty);
353 448678 distribution_value := instDistributionBinding(mod, varLst, index_list, "distribution", false);
354 448678 startOrigin := instStartOrigin(mod, varLst, "start");
355
356 //TODO: check for protected attribute (here and below matches)
357 448678 then
358 (cache,SOME(
359 DAE.VAR_ATTR_REAL(quantity_str,unit_str,displayunit_str,min_val,max_val,
360 start_val,fixed_val,nominal_val,stateSelect_value,uncertainty_value,distribution_value,NONE(),NONE(),NONE(),startOrigin)));
361
362 // Integer
363 case (cache, mod, DAE.T_INTEGER(varLst = varLst), index_list)
364 algorithm
365 44782 quantity_str := instBinding(mod, varLst, DAE.T_STRING_DEFAULT, index_list, "quantity",false);
366 44782 min_val := instBinding(mod, varLst, DAE.T_INTEGER_DEFAULT, index_list, "min",false);
367 44782 max_val := instBinding(mod, varLst, DAE.T_INTEGER_DEFAULT, index_list, "max",false);
368 44782 start_val := instBinding(mod, varLst, DAE.T_INTEGER_DEFAULT, index_list, "start",false);
369 44782 fixed_val := instBinding(mod, varLst, DAE.T_BOOL_DEFAULT,index_list, "fixed",true);
370 44782 exp_bind_uncertainty := instEnumerationBinding(mod, varLst, index_list, "uncertain",uncertaintyType,true);
371 44782 uncertainty_value := getUncertainFromExpOption(exp_bind_uncertainty);
372 44782 distribution_value := instDistributionBinding(mod, varLst, index_list, "distribution", false);
373
374 44782 startOrigin := instStartOrigin(mod, varLst, "start");
375 44782 then
376 (cache,SOME(DAE.VAR_ATTR_INT(quantity_str,min_val,max_val,start_val,fixed_val,uncertainty_value,distribution_value,NONE(),NONE(),NONE(),startOrigin)));
377
378 // Boolean
379 case (cache, mod, tp as DAE.T_BOOL(varLst = varLst), index_list)
380 algorithm
381 67079 quantity_str := instBinding( mod, varLst, DAE.T_STRING_DEFAULT, index_list, "quantity",false);
382 67079 start_val := instBinding(mod, varLst, tp, index_list, "start",false);
383 67079 fixed_val := instBinding(mod, varLst, tp, index_list, "fixed",true);
384 67079 startOrigin := instStartOrigin(mod, varLst, "start");
385 67079 then
386 (cache,SOME(DAE.VAR_ATTR_BOOL(quantity_str,start_val,fixed_val,NONE(),NONE(),NONE(),startOrigin)));
387
388 // BTH Clock
389 case (cache, _, DAE.T_CLOCK(), _)
390 then
391 (cache,SOME(DAE.VAR_ATTR_CLOCK(NONE(),NONE())));
392
393 // String
394 case (cache, mod, tp as DAE.T_STRING(varLst = varLst), index_list)
395 algorithm
396 77015 quantity_str := instBinding(mod, varLst, tp, index_list, "quantity",false);
397 77015 start_val := instBinding(mod, varLst, tp, index_list, "start",false);
398 77015 fixed_val := instBinding(mod, varLst, DAE.T_BOOL_DEFAULT, index_list, "fixed",true);
399 77015 startOrigin := instStartOrigin(mod, varLst, "start");
400 77015 then
401 (cache,SOME(DAE.VAR_ATTR_STRING(quantity_str,start_val,fixed_val,NONE(),NONE(),NONE(),startOrigin)));
402
403 // Enumeration
404 case (cache, mod, enumtype as DAE.T_ENUMERATION(attributeLst = varLst), index_list)
405 algorithm
406 27235 quantity_str := instBinding(mod, varLst, DAE.T_STRING_DEFAULT,index_list, "quantity",false);
407 27235 exp_bind_min := instBinding(mod, varLst, enumtype, index_list, "min",false);
408 27235 exp_bind_max := instBinding(mod, varLst, enumtype, index_list, "max",false);
409 27235 exp_bind_start := instBinding(mod, varLst, enumtype, index_list, "start",false);
410 27235 fixed_val := instBinding(mod, varLst, DAE.T_BOOL_DEFAULT, index_list, "fixed",true);
411 27235 startOrigin := instStartOrigin(mod, varLst, "start");
412 27235 then
413 (cache,SOME(DAE.VAR_ATTR_ENUMERATION(quantity_str,exp_bind_min,exp_bind_max,exp_bind_start,fixed_val,NONE(),NONE(),NONE(),startOrigin)));
414
415 // not a basic type?
416 case (cache, _, _, _)
417 then (cache,NONE());
418 end matchcontinue;
419 end instDaeVariableAttributes;
420
421 protected function instEnumerationBinding
422 "author: LP
423 instantiates a enumeration binding and retrieves the value."
424 input DAE.Mod inMod;
425 input list<DAE.Var> varLst;
426 input list<Integer> inIndices;
427 input String inName;
428 input DAE.Type expected_type;
429 input Boolean useConstValue "if true, use constant value in TYPED (if present)";
430 output Option<DAE.Exp> outBinding;
431 algorithm
432 try
433 942138 outBinding := instBinding(inMod, varLst, expected_type, inIndices, inName, useConstValue);
434 else
435 ✗ Error.addMessage(Error.TYPE_ERROR, {inName, "enumeration type"});
436 ✗ fail();
437 end try;
438 end instEnumerationBinding;
439
440 protected function instDistributionBinding
441 "
442 Author:Peter Aronsson, 2012
443
444 Instantiates a distribution binding and retrieves the value.
445 "
446 input DAE.Mod inMod;
447 input list<DAE.Var> varLst;
448 input list<Integer> inIntegerLst;
449 input String inString;
450 input Boolean useConstValue "if true, use constant value in TYPED (if present)";
451 output Option<DAE.Distribution> out;
452 algorithm
453 out := matchcontinue (inMod,inIntegerLst,inString)
454 local
455 DAE.Mod mod;
456 DAE.Exp name,params,paramNames;
457 list<Integer> index_list;
458 String bind_name;
459 DAE.Type ty;
460 Integer paramDim;
461 DAE.ComponentRef cr,crName,crParams;
462 Absyn.Path path;
463
464 //Record constructor
465 case (mod, index_list, bind_name)
466 algorithm
467
2/14
✗ Branch 1 not taken.
✓ Branch 2 taken 493460 times.
✓ Branch 3 taken 493460 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
493460 SOME(DAE.CALL(path = path, expLst = {name,params, paramNames})) := instBinding(mod, varLst, distributionType, index_list, bind_name, useConstValue);
468 ✗ true := AbsynUtil.pathEqual(path, Absyn.IDENT("Distribution"));
469 ✗ then
470 SOME(DAE.DISTRIBUTION(name, params, paramNames));
471
472 case (mod, index_list, bind_name)
473 algorithm
474
2/14
✗ Branch 1 not taken.
✓ Branch 2 taken 493460 times.
✓ Branch 3 taken 493460 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
493460 SOME(DAE.RECORD(path = path, exps = {name,params, paramNames})) := instBinding(mod, varLst, distributionType, index_list, bind_name, useConstValue);
475 ✗ true := AbsynUtil.pathEqual(path, Absyn.IDENT("Distribution"));
476 ✗ then
477 SOME(DAE.DISTRIBUTION(name, params, paramNames));
478
479 // Cref
480 case (mod, index_list, bind_name)
481 algorithm
482
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 493460 times.
✓ Branch 3 taken 493460 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
493460 SOME(DAE.CREF(cr,ty)) := instBinding(mod, varLst, distributionType, index_list, bind_name, useConstValue);
483 ✗ true := Types.isRecord(ty);
484 ✗ DAE.T_COMPLEX(varLst = _::DAE.TYPES_VAR(ty=DAE.T_ARRAY(dims={DAE.DIM_INTEGER(paramDim)}))::_) := ty;
485
486 ✗ crName := ComponentReference.crefPrependIdent(cr,"name",{},DAE.T_STRING_DEFAULT);
487 ✗ crParams := ComponentReference.crefPrependIdent(cr,"params",{},DAE.T_ARRAY(DAE.T_REAL_DEFAULT,{DAE.DIM_INTEGER(paramDim)}));
488 ✗ name := Expression.makeCrefExp(crName,DAE.T_STRING_DEFAULT);
489 ✗ params := Expression.makeCrefExp(crParams,DAE.T_ARRAY(DAE.T_REAL_DEFAULT,{DAE.DIM_INTEGER(paramDim)}));
490 ✗ paramNames := Expression.makeCrefExp(crParams,DAE.T_ARRAY(DAE.T_STRING_DEFAULT,{DAE.DIM_INTEGER(paramDim)}));
491 ✗ then
492 SOME(DAE.DISTRIBUTION(name, params, paramNames));
493
494
495
496 else NONE();
497
498 end matchcontinue;
499 end instDistributionBinding;
500
501 protected function getUncertainFromExpOption
502 "
503 Author: Daniel Hedberg 2011-01
504
505 Extracts the uncertainty value, as defined in DAE, from a DAE.Exp.
506 "
507 input Option<DAE.Exp> expOption;
508 output Option<DAE.Uncertainty> out;
509 algorithm
510 out := match expOption
511 case SOME(DAE.ENUM_LITERAL(name = Absyn.QUALIFIED(name = "Uncertainty", path = Absyn.IDENT("given")))) then SOME(DAE.GIVEN());
512 case SOME(DAE.ENUM_LITERAL(name = Absyn.QUALIFIED(name = "Uncertainty", path = Absyn.IDENT("sought")))) then SOME(DAE.SOUGHT());
513 case SOME(DAE.ENUM_LITERAL(name = Absyn.QUALIFIED(name = "Uncertainty", path = Absyn.IDENT("refine")))) then SOME(DAE.REFINE());
514 case SOME(DAE.ENUM_LITERAL(name = Absyn.QUALIFIED(name = "Uncertainty", path = Absyn.IDENT("propagate")))) then SOME(DAE.PROPAGATE());
515 else NONE();
516 end match;
517 end getUncertainFromExpOption;
518
519 public function instModEquation
520 "This function adds the equation in the declaration
521 of a variable, if such an equation exists."
522 input DAE.ComponentRef inComponentRef;
523 input DAE.Type inType;
524 input DAE.Mod inMod;
525 input DAE.ElementSource inSource "the origin of the element";
526 input Boolean inImpl;
527 output DAE.DAElist outDae;
528 algorithm
529 outDae:= matchcontinue (inType,inMod)
530 local
531 DAE.Type t;
532 DAE.DAElist dae;
533 DAE.Exp e,lhs;
534 DAE.Properties prop2;
535 Absyn.Exp aexp1,aexp2;
536 SCode.Equation scode;
537 Absyn.ComponentRef acr;
538 SourceInfo info;
539 DAE.ElementSource source;
540
541 // Record constructors are different
542 // If it's a constant binding, all fields will already be bound correctly. Don't return a DAE.
543 case (DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_)),
544 DAE.MOD(binding = SOME(DAE.TYPED(_,SOME(_),DAE.PROP(_,DAE.C_CONST()),_))))
545 then DAE.emptyDae;
546
547 // Special case if the dimensions of the expression is 0.
548 // If this is true, and it is instantiated normally, matching properties
549 // will result in error messages (Real[0] is not Real), so we handle it here.
550 case (_, DAE.MOD(binding = SOME(DAE.TYPED(properties = prop2))))
551 algorithm
552
1/10
✓ Branch 1 taken 38400 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
38400 DAE.T_ARRAY(dims = {DAE.DIM_INTEGER(0)}) := Types.getPropType(prop2);
553 then
554 DAE.emptyDae;
555
556 // Regular cases
557 case (_, DAE.MOD(binding = SOME(DAE.TYPED(e,_,prop2,aexp2)), info = info))
558 algorithm
559 38400 t := Types.simplifyType(inType);
560 38400 lhs := Expression.makeCrefExp(inComponentRef, t);
561 38400 acr := ComponentReference.unelabCref(inComponentRef);
562 38400 aexp1 := Absyn.CREF(acr);
563 38400 scode := SCode.EQ_EQUALS(aexp1,aexp2,SCode.noComment,info);
564 38400 source := ElementSource.addSymbolicTransformation(inSource,DAE.FLATTEN(scode,NONE()));
565 38400 dae := InstSection.instEqEquation(lhs, DAE.PROP(inType,DAE.C_VAR()), e, prop2, source, SCode.NON_INITIAL(), inImpl, extraInfo=info);
566 then
567 dae;
568
569 case (_, DAE.MOD(binding = NONE())) then DAE.emptyDae;
570 case (_, DAE.NOMOD()) then DAE.emptyDae;
571 case (_, DAE.REDECL()) then DAE.emptyDae;
572
573 else
574 algorithm
575 ✗ true := Flags.isSet(Flags.FAILTRACE);
576 ✗ Debug.trace("- InstBinding.instModEquation failed\n type: ");
577 ✗ Debug.trace(TypesDump.printTypeStr(inType));
578 ✗ Debug.trace("\n cref: ");
579 ✗ Debug.trace(ComponentReferenceBasics.printComponentRefStr(inComponentRef));
580 ✗ Debug.trace("\n mod:");
581 ✗ Debug.traceln(Mod.printModStr(inMod));
582 ✗ then
583 fail();
584 end matchcontinue;
585 end instModEquation;
586
587 public function makeBinding
588 "This function looks at the equation part of a modification, and
589 if there is a declaration equation builds a DAE.Binding for it."
590 input FCore.Cache inCache;
591 input FCore.Graph inEnv;
592 input SCode.Attributes inAttributes;
593 input DAE.Mod inMod;
594 input DAE.Type inType;
595 input DAE.Prefix inPrefix;
596 input String componentName;
597 input SourceInfo inInfo;
598 output FCore.Cache outCache;
599 output DAE.Binding outBinding;
600 algorithm
601 (outCache,outBinding) := matchcontinue (inCache,inAttributes,inMod,inType)
602 local
603 DAE.Type tp,e_tp;
604 DAE.Exp e_1,e,e_val_exp;
605 Option<Values.Value> e_val;
606 DAE.Const c;
607 String e_tp_str,tp_str,e_str,e_str_1,str;
608 FCore.Cache cache;
609 DAE.Properties prop;
610 DAE.Binding binding;
611 DAE.Mod startValueModification;
612 list<DAE.Var> complex_vars;
613 Absyn.Path tpath;
614 list<DAE.SubMod> sub_mods;
615 SourceInfo info;
616 Values.Value v;
617
618 // A record might have bindings from the class, use those if there is no modifier!
619 case (cache, _, DAE.NOMOD(), _)
620 algorithm
621
4/4
✓ Branch 1 taken 319356 times.
✓ Branch 2 taken 12956 times.
✓ Branch 3 taken 6823 times.
✓ Branch 4 taken 6133 times.
332312 DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path = tpath),
622 varLst = complex_vars) := Types.arrayElementType(inType);
623
2/2
✓ Branch 1 taken 4644 times.
✓ Branch 2 taken 1489 times.
6133 true := Types.allHaveBindings(complex_vars);
624 1489 binding := makeRecordBinding(cache, inEnv, tpath, inType, complex_vars, {}, inInfo);
625 1489 then
626 (cache, binding);
627
628 330823 case (cache,_,DAE.NOMOD(),_) then (cache,DAE.UNBOUND());
629
630 case (_, _, DAE.REDECL(), _)
631 60 then makeBinding(inCache, inEnv, inAttributes, inMod.mod, inType,
632 inPrefix, componentName, inInfo);
633
634 // adrpo: if the binding is missing for a parameter and
635 // the parameter has a start value modification,
636 // use that to create the binding as if we have
637 // a modification from outside it will be re-written.
638 // this fixes:
639 // Modelica.Electrical.Machines.Examples.SMEE_Generator
640 // (BUG: #1156 at https://openmodelica.org:8443/cb/issue/1156)
641 // and maybe a lot others.
642 case (cache,SCode.ATTR(variability = SCode.PARAM()),DAE.MOD(binding = NONE()),tp)
643 algorithm
644
2/2
✓ Branch 1 taken 124 times.
✓ Branch 2 taken 105 times.
229 true := Types.getFixedVarAttributeParameterOrConstant(tp);
645 // this always succeeds but return NOMOD if there is no (start = x)
646 105 startValueModification := Mod.lookupCompModification(inMod, "start");
647 // make sure is NOT a DAE.NOMOD!
648
2/2
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 75 times.
105 false := Mod.isEmptyMod(startValueModification);
649 75 (cache,binding) := makeBinding(cache,inEnv,inAttributes,startValueModification,inType,inPrefix,componentName,inInfo);
650 75 binding := DAEUtil.setBindingSource(binding, DAE.BINDING_FROM_START_VALUE());
651
652 // lochel: I moved the warning to the back end for now
653 // s = componentName;
654 // pre_str = PrefixUtil.printPrefixStr2(inPrefix);
655 // s = pre_str + s;
656 // str = DAEUtil.printBindingExpStr(binding);
657 // Error.addSourceMessage(Error.UNBOUND_PARAMETER_WITH_START_VALUE_WARNING, {s,str}, inInfo);
658 75 then
659 (cache,binding);
660
661 // A record might have bindings for each component instead of a single
662 // binding for the whole record, in which case we need to assemble them into
663 // a binding.
664 case (cache, _, DAE.MOD(subModLst = sub_mods as _ :: _), _)
665 algorithm
666
4/4
✓ Branch 1 taken 26943 times.
✓ Branch 2 taken 5354 times.
✓ Branch 3 taken 2786 times.
✓ Branch 4 taken 2568 times.
32297 DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path = tpath),
667 varLst = complex_vars) := Types.arrayElementType(inType);
668 2568 binding := makeRecordBinding(cache, inEnv, tpath, inType, complex_vars, sub_mods, inInfo);
669 2562 then
670 (cache, binding);
671
672 24063 case (cache,_,DAE.MOD(binding = NONE()),_) then (cache,DAE.UNBOUND());
673 /* adrpo: CHECK! do we need this here? numerical values
674 case (cache,env,_,DAE.MOD(binding = SOME(DAE.TYPED(e,_,DAE.PROP(e_tp,_)))),tp,_,_)
675 algorithm
676 (e_1,_) = Types.matchType(e, e_tp, tp);
677 (cache,v,_) = Ceval.ceval(cache,env, e_1, false,NONE(), NONE(), Absyn.NO_MSG(),0);
678 then
679 (cache,DAE.VALBOUND(v, DAE.BINDING_FROM_DEFAULT_VALUE()));
680 */
681
682 case (cache,_,DAE.MOD(binding = SOME(DAE.TYPED(e,SOME(v),prop,_))),e_tp) /* default */
683 algorithm
684 215571 c := Types.propAllConst(prop);
685 215571 tp := Types.getPropType(prop);
686
2/2
✓ Branch 1 taken 180168 times.
✓ Branch 2 taken 35403 times.
215571 false := Types.equivtypes(tp,e_tp);
687 35403 e_val_exp := ValuesUtil.valueExp(v, SOME(e));
688 // Handle bindings of the type Boolean b[Boolean]={true,false}, enumerations, and similar
689 // tp = Types.traverseType(tp, 1, Types.makeKnownDimensionsInteger);
690 // e_tp = Types.traverseType(e_tp, 1, Types.makeKnownDimensionsInteger);
691 35403 (e_1, _) := Types.matchType(e, tp, e_tp, false);
692 17207 (e_1,_) := ExpressionSimplify.simplify(e_1);
693 17207 (e_val_exp, _) := Types.matchType(e_val_exp, tp, e_tp, false);
694 17207 (e_val_exp,_) := ExpressionSimplify.simplify(e_val_exp);
695 17207 v := Ceval.cevalSimple(e_val_exp);
696 e_val := SOME(v);
697 17207 then
698 (cache,DAE.EQBOUND(e_1,e_val,c,DAE.BINDING_FROM_DEFAULT_VALUE()));
699
700 case (cache,_,DAE.MOD(binding = SOME(DAE.TYPED(e,e_val,prop,_))),e_tp) /* default */
701 algorithm
702 208319 c := Types.propAllConst(prop);
703 208319 tp := Types.getPropType(prop);
704 // Handle bindings of the type Boolean b[Boolean]={true,false}, enumerations, and similar
705 // tp = Types.traverseType(tp, 1, Types.makeKnownDimensionsInteger);
706 // e_tp = Types.traverseType(e_tp, 1, Types.makeKnownDimensionsInteger);
707 208319 (e_1, _) := Types.matchType(e, tp, e_tp, false);
708 190123 (e_1,_) := ExpressionSimplify.simplify(e_1);
709 190123 then
710 (cache,DAE.EQBOUND(e_1,e_val,c,DAE.BINDING_FROM_DEFAULT_VALUE()));
711
712 case (_,_,DAE.MOD(binding = SOME(DAE.TYPED(e,_,prop,_)), info = info),tp)
713 algorithm
714 18196 e_tp := Types.getPropType(prop);
715
2/2
✓ Branch 0 taken 18196 times.
✓ Branch 1 taken 18196 times.
36392 failure(Types.matchType(e, e_tp, tp, false));
716 18196 e_tp_str := TypesDump.unparseTypeNoAttr(e_tp);
717 18196 tp_str := TypesDump.unparseTypeNoAttr(tp);
718 18196 e_str := ExpressionBasics.printExpStr(e);
719 18196 e_str_1 := stringAppend("=", e_str);
720 18196 str := PrefixUtil.printPrefixStrIgnoreNoPre(inPrefix) + "." + componentName;
721 18196 Types.typeErrorSanityCheck(e_tp_str, tp_str, info);
722 18196 Error.addSourceMessage(Error.MODIFIER_TYPE_MISMATCH_ERROR, {str,tp_str,e_str_1,e_tp_str}, info);
723 18196 then
724 fail();
725
726 else
727 algorithm
728
2/2
✓ Branch 1 taken 18182 times.
✓ Branch 2 taken 14 times.
18196 true := Flags.isSet(Flags.FAILTRACE);
729 14 Debug.traceln("- Inst.makeBinding failed on component:" + PrefixUtil.printPrefixStr(inPrefix) + "." + componentName);
730 14 then
731 fail();
732 end matchcontinue;
733 end makeBinding;
734
735 public function makeRecordBinding
736 "Creates a binding for a record given a list of submodifiers. This is the case
737 when a record is given a binding by modifiers, ex:
738
739 record R
740 Real x; Real y;
741 end R;
742
743 constant R r(x = 2.0, y = 3.0);
744
745 This is translated to:
746 constant R r = R(2.0, 3.0);
747
748 This is needed when we assign a record to another record.
749 "
750 input FCore.Cache inCache;
751 input FCore.Graph inEnv;
752 input Absyn.Path inRecordName;
753 input DAE.Type inRecordType;
754 input list<DAE.Var> inRecordVars;
755 input list<DAE.SubMod> inMods;
756 input SourceInfo inInfo;
757 output DAE.Binding outBinding;
758 protected
759 list<DAE.Exp> accum_exps = {};
760 list<Values.Value> accum_vals = {};
761 list<String> accum_names = {};
762 list<DAE.SubMod> mods = inMods;
763 Option<DAE.SubMod> opt_mod;
764 String name = "", scope, ty_str;
765 DAE.Type ty, ety;
766 DAE.Binding binding;
767 list<DAE.Dimension> dims;
768 DAE.Exp exp;
769 Values.Value val;
770 algorithm
771 4057 dims := TypesDump.getDimensions(inRecordType);
772
773 try
774
2/2
✓ Branch 0 taken 33026 times.
✓ Branch 1 taken 4051 times.
37077 for var in inRecordVars loop
775 33026 DAE.TYPES_VAR(name = name, ty = ty, binding = binding) := var;
776
777 // Try to find a submod with the same name as the variable.
778 33026 (mods, opt_mod) := List.deleteMemberOnTrue(name, mods, InstUtil.isSubModNamed);
779
780
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 33026 times.
✓ Branch 2 taken 7461 times.
✓ Branch 3 taken 25565 times.
33026 if isSome(opt_mod) then
781 // Found a submod, use its binding.
782 25565 ty := Types.liftArrayListDims(ty, dims);
783 25565 (exp, val) := makeRecordBinding3(opt_mod, ty, inInfo);
784 elseif DAEUtil.isBound(binding) then
785 // Couldn't find a submod, but variable has a binding already.
786
4/6
✗ Branch 0 not taken.
✓ Branch 1 taken 7456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7456 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 7453 times.
7456 DAE.EQBOUND(exp = exp, evaluatedExp = SOME(val)) := binding;
787 else
788 // Couldn't find a submod, and the variable doesn't have a binding.
789 5 ety := Types.simplifyType(ty);
790 5 ty := Types.liftArrayListDims(ty, dims);
791 5 scope := FGraph.printGraphPathStr(inEnv);
792 5 ty_str := TypesDump.printTypeStr(ty);
793 5 exp := DAE.EMPTY(scope, DAE.CREF_IDENT(name, ety, {}), ety, ty_str);
794 5 val := Values.EMPTY(scope, name, Types.typeToValue(ty), ty_str);
795 end if;
796
797 33020 accum_exps := exp :: accum_exps;
798 33020 accum_vals := val :: accum_vals;
799 accum_names := name :: accum_names;
800 end for;
801
802 // Assemble the binding for the record.
803 4051 ety := Types.simplifyType(Types.arrayElementType(inRecordType));
804 4051 exp := DAE.CALL(inRecordName, listReverse(accum_exps),
805 DAE.CALL_ATTR(ety, false, false, false, false, DAE.NORM_INLINE(), DAE.NO_TAIL(), DAE.NoReturn.RETURNS));
806 4051 val := Values.RECORD(inRecordName, listReverse(accum_vals), listReverse(accum_names), -1);
807 4051 (exp, val) := InstUtil.liftRecordBinding(inRecordType, exp, val);
808 4051 outBinding := DAE.EQBOUND(exp, SOME(val), DAE.C_CONST(), DAE.BINDING_FROM_RECORD_SUBMODS());
809 else
810
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if Flags.isSet(Flags.FAILTRACE) then
811 ✗ Debug.traceln("- Inst.makeRecordBinding2 failed for " +
812 AbsynUtil.pathString(inRecordName) + "." + name + "\n");
813 end if;
814 6 fail();
815 end try;
816 end makeRecordBinding;
817
818 protected function makeRecordBinding3
819 "Helper function to makeRecordBinding2. Fetches the binding expression and
820 value from an optional submod."
821 input Option<DAE.SubMod> inSubMod;
822 input DAE.Type inType;
823 input SourceInfo inInfo;
824 output DAE.Exp outExp;
825 output Values.Value outValue;
826 algorithm
827 (outExp, outValue) := matchcontinue inSubMod
828 local
829 DAE.Exp exp;
830 Values.Value val;
831 DAE.Type ty;
832 DAE.Ident ident;
833 String binding_str, expected_type_str, given_type_str;
834
835 // Array type and each prefix => return the expression and value.
836 case SOME(DAE.NAMEMOD(mod = DAE.MOD(eachPrefix = SCode.EACH(), binding =
837 SOME(DAE.TYPED(modifierAsExp = exp, modifierAsValue = SOME(val))))))
838 then (exp, val);
839
840 // Scalar type and no each prefix => return the expression and value.
841 case SOME(DAE.NAMEMOD(mod = DAE.MOD(eachPrefix = SCode.NOT_EACH(), binding =
842 SOME(DAE.TYPED(modifierAsExp = exp, modifierAsValue = SOME(val), properties = DAE.PROP(type_ = ty))))))
843 algorithm
844 25275 (exp, ty) := Types.matchType(exp, ty, inType, true);
845 then
846 (exp, val);
847
848 // Scalar type and no each prefix => bindings given by expressions myRecord(v1 = inV1, v2 = inV2)
849 case SOME(DAE.NAMEMOD(mod = DAE.MOD(eachPrefix = SCode.NOT_EACH(), binding =
850 SOME(DAE.TYPED(modifierAsExp = exp, modifierAsValue = NONE(), properties = DAE.PROP(type_ = ty))))))
851 algorithm
852 32 (exp, ty) := Types.matchType(exp, ty, inType, true);
853 then
854 (exp, Values.OPTION(NONE()));
855
856 case SOME(DAE.NAMEMOD(ident = ident, mod = DAE.MOD(binding =
857 SOME(DAE.TYPED(modifierAsExp = exp, properties = DAE.PROP(type_ = ty))))))
858 algorithm
859 ✗ binding_str := ExpressionBasics.printExpStr(exp);
860 ✗ expected_type_str := TypesDump.unparseTypeNoAttr(inType);
861 ✗ given_type_str := TypesDump.unparseTypeNoAttr(ty);
862 ✗ Types.typeErrorSanityCheck(given_type_str, expected_type_str, inInfo);
863 ✗ Error.addSourceMessage(Error.VARIABLE_BINDING_TYPE_MISMATCH,
864 {ident, binding_str, expected_type_str, given_type_str}, inInfo);
865 ✗ then
866 fail();
867
868 end matchcontinue;
869 end makeRecordBinding3;
870
871 public function makeVariableBinding
872 "Returns a variable's bound expression."
873 input DAE.Type inType;
874 input DAE.Mod inMod;
875 input DAE.Const inConst;
876 input DAE.Prefix inPrefix;
877 input String inName;
878 output Option<DAE.Exp> outBinding;
879 protected
880 Option<DAE.EqMod> oeq_mod = Mod.modEquation(inMod);
881 DAE.Exp e, e2;
882 DAE.Properties p;
883 SourceInfo info;
884 DAE.Const c;
885 String e_str, et_str, bt_str;
886 algorithm
887 // No modifier => no binding.
888
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 542966 times.
✓ Branch 2 taken 250132 times.
✓ Branch 3 taken 292834 times.
542966 if isNone(oeq_mod) then
889 outBinding := NONE();
890 250132 return;
891 end if;
892
893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 292834 times.
292834 SOME(DAE.TYPED(modifierAsExp = e, properties = p)) := oeq_mod;
894
895
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 292800 times.
292834 if Types.isExternalObject(inType) then
896 // For external objects the binding contains the constructor call. Return it as it is.
897 outBinding := SOME(e);
898 elseif Types.isEmptyArray(Types.getPropType(p)) then
899 // An empty array has unknown type, skip type matching.
900 outBinding := NONE();
901 else
902 292795 info := Mod.getModInfo(inMod);
903
904 // For normal variables, make sure the types match.
905 try
906
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 292789 times.
292795 (e2, DAE.PROP(constFlag = c)) :=
907 Types.matchProp(e, p, DAE.PROP(inType, inConst), true);
908 else
909 // The types of the variable and binding are incompatible, print an error.
910 6 e_str := ExpressionBasics.printExpStr(e);
911 6 et_str := TypesDump.unparseTypeNoAttr(inType);
912 6 bt_str := TypesDump.unparseTypeNoAttr(Types.getPropType(p));
913 6 Types.typeErrorSanityCheck(et_str, bt_str, info);
914 6 Error.addSourceMessageAndFail(Error.VARIABLE_BINDING_TYPE_MISMATCH,
915 {inName, e_str, et_str, bt_str}, info);
916 end try;
917
918 // Check that the variability is compatible too.
919 292789 InstUtil.checkHigherVariability(inConst, c, inPrefix, inName, e, info);
920 outBinding := SOME(e2);
921 end if;
922 end makeVariableBinding;
923
924 annotation(__OpenModelica_Interface="frontend");
925 end InstBinding;
926