Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 75.3% 497 / 0 / 660
Functions: -% 0 / 1 / 1
Branches: 61.6% 170 / 0 / 276

OMCompiler/Compiler/FrontEnd/Lookup.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 Lookup
37 " file: Lookup.mo
38 package: Lookup
39 description: Scoping rules
40
41
42 This module is responsible for the lookup mechanism in Modelica.
43 It is responsible for looking up classes, variables, etc. in the
44 environment Env by following the lookup rules.
45 The most important functions are:
46 lookupClass - to find a class
47 lookupType - to find types (e.g. functions, types, etc.)
48 lookupVar - to find a variable in the instance hierarchy."
49
50 public import Absyn;
51 public import AbsynUtil;
52 public import ClassInf;
53 public import DAE;
54 public import FCore;
55 public import HashTableStringToPath;
56 public import InstTypes;
57 public import SCode;
58 public import Util;
59 public import Types;
60
61 protected import BaseHashTable;
62 protected import Builtin;
63 protected import ComponentReference;
64 protected import ComponentReferenceBasics;
65 protected import Config;
66 protected import DAE.Connect;
67 protected import ConnectionGraph;
68 protected import Debug;
69 protected import Error;
70 protected import Expression;
71 protected import Flags;
72 protected import FGraph;
73 protected import FNode;
74 protected import Inst;
75 protected import InstExtends;
76 protected import InstFunction;
77 protected import InstUtil;
78 protected import InnerOuter;
79 protected import List;
80 protected import Mod;
81 protected import Mutable;
82 protected import PrefixUtil;
83 import SCodeUtil;
84 protected import Static;
85 protected import UnitAbsyn;
86 protected import SCodeDump;
87 protected import ErrorExt;
88 protected import ValuesUtil;
89 protected import Values;
90 protected import ExpressionBasics;
91 protected import ClassInfUtil;
92
93 /* - Lookup functions
94
95 These functions look up class and variable names in the environment.
96 The names are supplied as a path, and if the path is qualified, a
97 variable named as the first part of the path is searched for, and the
98 name is looked for in it.
99
100 */
101
102 public function lookupType
103 " This function finds a specified type in the environment.
104 If it finds a function instead, this will be implicitly instantiated
105 and lookup will start over.
106 "
107 input FCore.Cache inCache;
108 input FCore.Graph inEnv "environment to search in";
109 input Absyn.Path inPath "type to look for";
110 input Option<SourceInfo> msg "Messaage flag, SOME() outputs lookup error messages";
111 output FCore.Cache cache;
112 output DAE.Type t "the found type";
113 output FCore.Graph env "The environment the type was found in";
114 algorithm
115 (cache,t,env) := match inPath
116
117 case Absyn.IDENT()
118 algorithm
119 15857 (cache, t, env) := lookupTypeIdent(inCache,inEnv,inPath.name,msg);
120 then (cache, t, env);
121
122 else
123 algorithm
124 47553 (cache, t, env) := lookupTypeQual(inCache,inEnv,inPath,msg);
125 then (cache, t, env);
126 end match;
127 end lookupType;
128
129 protected function lookupTypeQual
130 " This function finds a specified type in the environment.
131 If it finds a function instead, this will be implicitly instantiated
132 and lookup will start over.
133 "
134 input FCore.Cache inCache;
135 input FCore.Graph inEnv "environment to search in";
136 input Absyn.Path inPath "type to look for";
137 input Option<SourceInfo> msg "Messaage flag, SOME() outputs lookup error messages";
138 output FCore.Cache outCache;
139 output DAE.Type outType "the found type";
140 output FCore.Graph outEnv "The environment the type was found in";
141 algorithm
142 (outCache,outType,outEnv):=
143 matchcontinue (inCache,inEnv,inPath,msg)
144 local
145 DAE.Type t;
146 FCore.Graph env_1,env,env_2;
147 Absyn.Path path;
148 SCode.Element c;
149 String classname,scope;
150 FCore.Cache cache;
151 SourceInfo info;
152
153 // Special handling for Connections.isRoot
154 case (cache,env,Absyn.QUALIFIED("Connections", Absyn.IDENT("isRoot")),_)
155 algorithm
156 ✗ t := DAE.T_FUNCTION({DAE.FUNCARG("x", DAE.T_ANYTYPE_DEFAULT, DAE.C_VAR(), DAE.NON_PARALLEL(), NONE())}, DAE.T_BOOL_DEFAULT, DAE.FUNCTION_ATTRIBUTES_DEFAULT, inPath);
157 ✗ then
158 (cache, t, env);
159
160 // Special handling for Connections.uniqueRootIndices
161 case (cache,env,Absyn.QUALIFIED("Connections", Absyn.IDENT("uniqueRootIndices")),_)
162 algorithm
163 ✗ t := DAE.T_FUNCTION({
164 DAE.FUNCARG("roots", DAE.T_ARRAY(DAE.T_ANYTYPE_DEFAULT, {DAE.DIM_UNKNOWN()}), DAE.C_VAR(), DAE.NON_PARALLEL(), NONE()),
165 DAE.FUNCARG("nodes", DAE.T_ARRAY(DAE.T_ANYTYPE_DEFAULT, {DAE.DIM_UNKNOWN()}), DAE.C_VAR(), DAE.NON_PARALLEL(), NONE()),
166 DAE.FUNCARG("message", DAE.T_STRING_DEFAULT, DAE.C_VAR(), DAE.NON_PARALLEL(), NONE())},
167 DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT, {DAE.DIM_UNKNOWN()}),
168 DAE.FUNCTION_ATTRIBUTES_DEFAULT, inPath);
169 ✗ then
170 (cache, t, env);
171
172 // Special classes (function, record, metarecord, external object)
173 case (cache,env,path,_)
174 algorithm
175 47553 (cache,c,env_1) := lookupClass(cache,env,path);
176 47226 (cache,t,env_2) := lookupType2(cache,env_1,c);
177 then
178 (cache,t,env_2);
179
180 // Error for type not found
181 case (_,env,path,SOME(info))
182 algorithm
183 ✗ classname := AbsynUtil.pathString(path);
184 ✗ classname := stringAppend(classname," (its type) ");
185 ✗ scope := FGraph.printGraphPathStr(env);
186 ✗ Error.addSourceMessage(Error.LOOKUP_ERROR, {classname,scope}, info);
187 ✗ then
188 fail();
189 end matchcontinue;
190 end lookupTypeQual;
191
192 public function lookupTypeIdent
193 " This function finds a specified type in the environment.
194 If it finds a function instead, this will be implicitly instantiated
195 and lookup will start over.
196 "
197 input FCore.Cache inCache;
198 input FCore.Graph inEnv "environment to search in";
199 input String ident "type to look for";
200 input Option<SourceInfo> msg "Messaage flag, SOME() outputs lookup error messages";
201 output FCore.Cache outCache;
202 output DAE.Type outType "the found type";
203 output FCore.Graph outEnv "The environment the type was found in";
204 algorithm
205 (outCache,outType,outEnv):=
206 matchcontinue (inCache,inEnv,ident,msg)
207 local
208 DAE.Type t;
209 FCore.Graph env_1,env,env_2;
210 SCode.Element c;
211 String classname,scope;
212 FCore.Cache cache;
213 SourceInfo info;
214
215 // Special handling for MultiBody 3.x rooted() operator
216 case (cache,env,"rooted",_)
217 algorithm
218 t := DAE.T_FUNCTION({DAE.FUNCARG("x", DAE.T_ANYTYPE_DEFAULT, DAE.C_VAR(), DAE.NON_PARALLEL(), NONE())}, DAE.T_BOOL_DEFAULT, DAE.FUNCTION_ATTRIBUTES_DEFAULT, Absyn.IDENT("rooted"));
219 ✗ then
220 (cache, t, env);
221
222 // For simple names
223 case (cache,env,_,_)
224 algorithm
225 31236 (cache,t,env_1) := lookupTypeInEnv(cache,env,ident);
226 then
227 (cache,t,env_1);
228
229 // Special classes (function, record, metarecord, external object)
230 case (cache,env,_,_)
231 algorithm
232 28675 (cache,c,env_1) := lookupClassIdent(cache,env,ident);
233 12096 (cache,t,env_2) := lookupType2(cache,env_1,c);
234 then
235 (cache,t,env_2);
236
237 // Error for type not found
238 case (_,env,_,SOME(info))
239 algorithm
240 ✗ classname := stringAppend(ident," (its type) ");
241 ✗ scope := FGraph.printGraphPathStr(env);
242 ✗ Error.addSourceMessage(Error.LOOKUP_ERROR, {classname,scope}, info);
243 ✗ then
244 fail();
245 end matchcontinue;
246 end lookupTypeIdent;
247
248 protected function lookupType2
249 " This function handles the case when we looked up a class, but need to
250 check if it is function, record, metarecord, etc.
251 "
252 input FCore.Cache inCache;
253 input FCore.Graph inEnv "environment to search in";
254 input SCode.Element inClass "the class lookupType found";
255 output FCore.Cache outCache;
256 output DAE.Type outType "the found type";
257 output FCore.Graph outEnv "The environment the type was found in";
258 algorithm
259 (outCache,outType,outEnv) := matchcontinue (inCache,inEnv,inClass)
260 local
261 DAE.Type t;
262 FCore.Graph env_1,env_2,env_3;
263 Absyn.Path path;
264 SCode.Element c;
265 String id;
266 FCore.Cache cache;
267 SCode.Restriction r;
268 list<DAE.Var> types;
269 list<String> names;
270 ClassInf.State ci_state;
271 SCode.Encapsulated encflag;
272 DAE.Mod mod;
273
274 // Record constructors
275 case (cache,env_1,c as SCode.CLASS(restriction=SCode.R_RECORD(_)))
276 algorithm
277 5 (cache,env_1,t) := buildRecordType(cache,env_1,c);
278 5 then
279 (cache,t,env_1);
280
281 // lookup of an enumeration type
282 case (cache,env_1,c as SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=r as SCode.R_ENUMERATION()))
283 algorithm
284 122 env_2 := FGraph.openScope(env_1, encflag, id, SOME(FCore.CLASS_SCOPE()));
285 122 ci_state := ClassInfUtil.start(r, FGraph.getGraphName(env_2));
286 // fprintln(Flags.INST_TRACE, "LOOKUP TYPE ICD: " + FGraph.printGraphPathStr(env_1) + " path:" + AbsynUtil.pathString(path));
287 122 mod := Mod.getClassModifier(env_1, id);
288 122 (cache,env_3,_,_,_,_,_,types,_,_,_,_) :=
289 Inst.instClassIn(
290 cache,env_2,InnerOuter.emptyInstHierarchy,UnitAbsyn.noStore,
291 mod, DAE.NOPRE(),
292 ci_state, c, SCode.PUBLIC(), {}, false, InstTypes.INNER_CALL(),
293 ConnectionGraph.EMPTY, Connect.emptySet, NONE());
294 // build names
295 122 (_,names) := SCodeUtil.getClassComponents(c);
296 122 Types.checkEnumDuplicateLiterals(names, c.info);
297 // generate the enumeration type
298 122 path := FGraph.getGraphName(env_3);
299 122 t := DAE.T_ENUMERATION(NONE(), path, names, types, {});
300 122 env_3 := FGraph.mkTypeNode(env_3, id, t);
301 122 then
302 (cache,t,env_3);
303
304 // Real Type
305 case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="Real")))))
306 algorithm
307 t := DAE.T_REAL_DEFAULT;
308 ✗ then
309 (cache,t,env_1);
310
311 // Integer Type
312 case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="Integer")))))
313 algorithm
314 t := DAE.T_INTEGER_DEFAULT;
315 ✗ then
316 (cache,t,env_1);
317
318 // Boolean Type
319 case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="Boolean")))))
320 algorithm
321 t := DAE.T_BOOL_DEFAULT;
322 ✗ then
323 (cache,t,env_1);
324
325 // String Type
326 case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="String")))))
327 algorithm
328 t := DAE.T_STRING_DEFAULT;
329 ✗ then
330 (cache,t,env_1);
331
332 // Metamodelica extension, Uniontypes
333 case (cache,env_1,c as SCode.CLASS(restriction=SCode.R_METARECORD()))
334 algorithm
335 48727 (cache,env_2,t) := buildMetaRecordType(cache,env_1,c);
336 48705 then
337 (cache,t,env_2);
338
339 // Classes that are external objects. Implicitly instantiate to get type
340 case (cache,env_1,c)
341 algorithm
342 // fprintln(Flags.INST_TRACE, "LOOKUP TYPE ICD: " + FGraph.printGraphPathStr(env_1) + " path:" + AbsynUtil.pathString(path));
343
2/2
✓ Branch 1 taken 10477 times.
✓ Branch 2 taken 13 times.
10490 true := SCodeUtil.classIsExternalObject(c);
344 13 (cache,env_1,_,_,_,_,_,_,_,_) := Inst.instClass(
345 cache,env_1,InnerOuter.emptyInstHierarchy, UnitAbsyn.noStore,
346 DAE.NOMOD(), DAE.NOPRE(), c,
347 {}, false, InstTypes.TOP_CALL(), ConnectionGraph.EMPTY, Connect.emptySet);
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 SCode.CLASS(name=id) := c;
349 13 (env_1, _) := FGraph.stripLastScopeRef(env_1);
350 13 (cache,t,env_2) := lookupTypeInEnv(cache,env_1,id);
351 then
352 (cache,t,env_2);
353
354 // If we find a class definition that is a function or external function
355 // with the same name then we implicitly instantiate that function, look
356 // up the type.
357 case (cache,env_1,c as SCode.CLASS(name = id,restriction=SCode.R_FUNCTION(_)))
358 algorithm
359 // fprintln(Flags.INST_TRACE, "LOOKUP TYPE ICD: " + FGraph.printGraphPathStr(env_1) + " path:" + AbsynUtil.pathString(path));
360 10455 (cache,env_2,_) :=
361 InstFunction.implicitFunctionTypeInstantiation(cache,env_1,InnerOuter.emptyInstHierarchy,c);
362 9156 (cache,t,env_3) := lookupTypeInEnv(cache,env_2,id);
363 then
364 (cache,t,env_3);
365 end matchcontinue;
366 end lookupType2;
367
368 public function lookupMetarecordsRecursive
369 "Takes a list of paths to Uniontypes. Use this list to create a list of T_METARECORD.
370 The function is guarded against recursive definitions by accumulating all paths it
371 starts to traverse."
372 input FCore.Cache inCache;
373 input FCore.Graph inEnv;
374 input list<Absyn.Path> inUniontypePaths;
375 output FCore.Cache outCache;
376 output list<DAE.Type> outMetarecordTypes;
377 algorithm
378 148 (outCache,_,outMetarecordTypes) := lookupMetarecordsRecursive2(inCache, inEnv, inUniontypePaths, HashTableStringToPath.emptyHashTable(), {});
379 end lookupMetarecordsRecursive;
380
381 protected function lookupMetarecordsRecursive2
382 "Takes a list of paths to Uniontypes. Use this list to create a list of T_METARECORD.
383 The function is guarded against recursive definitions by accumulating all paths it
384 starts to traverse."
385 input FCore.Cache inCache;
386 input FCore.Graph inEnv;
387 input list<Absyn.Path> inUniontypePaths;
388 input HashTableStringToPath.HashTable inHt;
389 input list<DAE.Type> inAcc;
390 output FCore.Cache outCache = inCache;
391 output HashTableStringToPath.HashTable outHt = inHt;
392 output list<DAE.Type> outMetarecordTypes = inAcc;
393 algorithm
394
2/2
✓ Branch 0 taken 475881 times.
✓ Branch 1 taken 17507 times.
493388 for first in inUniontypePaths loop
395 475881 (outCache, outHt, outMetarecordTypes) :=
396 lookupMetarecordsRecursive3(outCache, inEnv, first, AbsynUtil.pathString(first), outHt, outMetarecordTypes);
397 end for;
398 end lookupMetarecordsRecursive2;
399
400 protected function lookupMetarecordsRecursive3
401 "Takes a list of paths to Uniontypes. Use this list to create a list of T_METARECORD.
402 The function is guarded against recursive definitions by accumulating all paths it
403 starts to traverse."
404 input FCore.Cache inCache;
405 input FCore.Graph inEnv;
406 input Absyn.Path path;
407 input String str;
408 input HashTableStringToPath.HashTable inHt;
409 input list<DAE.Type> inAcc;
410 output FCore.Cache outCache;
411 output HashTableStringToPath.HashTable outHt;
412 output list<DAE.Type> outMetarecordTypes;
413 algorithm
414 (outCache,outHt,outMetarecordTypes) := match (inCache, inEnv, inHt, inAcc)
415 local
416 FCore.Cache cache;
417 FCore.Graph env;
418 list<Absyn.Path> uniontypePaths;
419 list<DAE.Type> uniontypeTypes;
420 DAE.Type ty;
421 list<DAE.Type> acc;
422 HashTableStringToPath.HashTable ht;
423
424 case (cache, _, ht, acc) guard BaseHashTable.hasKey(str, ht)
425 458522 then (cache, ht, acc);
426 case (cache, env, ht, acc)
427 algorithm
428 17359 ht := BaseHashTable.add((str,path),ht);
429 17359 (cache, ty, _) := lookupType(cache, env, path, SOME(Absyn.dummyInfo));
430 17359 acc := ty::acc;
431 17359 uniontypeTypes := Types.getAllInnerTypesOfType(ty, Types.uniontypeFilter);
432 17359 uniontypePaths := List.flatten(List.map(uniontypeTypes, Types.getUniontypePaths));
433 17359 (cache, ht, acc) := lookupMetarecordsRecursive2(cache, env, uniontypePaths, ht, acc);
434 then (cache,ht,acc);
435 end match;
436 end lookupMetarecordsRecursive3;
437
438 public function lookupClass "Tries to find a specified class in an environment"
439 input FCore.Cache inCache;
440 input FCore.Graph inEnv "Where to look";
441 input Absyn.Path inPath "Path of the class to look for";
442 input Option<SourceInfo> inInfo = NONE();
443 output FCore.Cache outCache;
444 output SCode.Element outClass;
445 output FCore.Graph outEnv;
446 algorithm
447 (outCache,outClass,outEnv) := matchcontinue inPath
448 local
449 Absyn.Path id;
450 String name;
451 FGraph.Graph cenv;
452
453 /*
454 case (_,_,_,_)
455 algorithm
456 print("CL: " + AbsynUtil.pathString(inPath) + " env: " + FGraph.printGraphPathStr(inEnv) + " msg: " + boolString(msg) + "\n");
457 then
458 fail();*/
459
460 // see if the first path ident is a component
461 // we might have a component reference, i.e. world.gravityAcceleration
462 case Absyn.QUALIFIED(name, id)
463 algorithm
464 264240 ErrorExt.setCheckpoint("functionViaComponentRef2");
465 264240 (outCache,_,_,_,_,_,_,cenv,_) := lookupVarIdent(inCache, inEnv, name, {});
466 12053 (outCache, outClass, outEnv) := lookupClass(outCache, cenv, id);
467 1226 ErrorExt.rollBack("functionViaComponentRef2");
468 1226 then
469 (outCache,outClass,outEnv);
470
471 case Absyn.QUALIFIED(_, _)
472 algorithm
473 263014 ErrorExt.rollBack("functionViaComponentRef2");
474 263014 then
475 fail();
476
477 // normal case
478 case _
479 algorithm
480 1972668 (outCache,outClass,outEnv,_) := lookupClass1(inCache, inEnv, inPath, {}, Mutable.create(false), inInfo);
481 // print("CLRET: " + SCodeUtil.elementName(outClass) + " outenv: " + FGraph.printGraphPathStr(outEnv) + "\n");
482 1835425 then
483 (outCache,outClass,outEnv);
484 end matchcontinue;
485 // print("Lookup C2: " + " outenv: " + FGraph.printGraphPathStr(outEnv) + "\n");
486 end lookupClass;
487
488 public function lookupClassIdent "Like lookupClass, but takes a String as ident for input (avoids Absyn.IDENT() creation)"
489 input FCore.Cache inCache;
490 input FCore.Graph inEnv "Where to look";
491 input String ident;
492 input Option<SourceInfo> inInfo = NONE();
493 output FCore.Cache outCache;
494 output SCode.Element outClass;
495 output FCore.Graph outEnv;
496 algorithm
497 815999 (outCache,outClass,outEnv) := lookupClassInEnv(inCache, inEnv, ident, {}, Mutable.create(false), inInfo);
498 end lookupClassIdent;
499
500 protected function lookupClass1 "help function to lookupClass, does all the work."
501 input FCore.Cache inCache;
502 input FCore.Graph inEnv;
503 input Absyn.Path inPath "The path of the class to lookup";
504 input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion.";
505 input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment";
506 input Option<SourceInfo> inInfo;
507 output FCore.Cache outCache;
508 output SCode.Element outClass;
509 output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)";
510 output FCore.Scope outPrevFrames;
511 protected
512 Integer errors = Error.getNumErrorMessages();
513 algorithm
514 try
515 1972668 (outCache, outClass, outEnv, outPrevFrames) := lookupClass2(inCache, inEnv,
516 inPath, inPrevFrames, inState, inInfo);
517 else
518
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 137243 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 137220 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 22 times.
137243 if isSome(inInfo) and errors == Error.getNumErrorMessages() then
519 3 Error.addSourceMessage(Error.LOOKUP_ERROR,
520 {AbsynUtil.pathString(inPath), FGraph.printGraphPathStr(inEnv)},
521 Util.getOption(inInfo));
522 end if;
523 137243 fail();
524 end try;
525 end lookupClass1;
526
527 protected function lookupClass2 "help function to lookupClass, does all the work."
528 input FCore.Cache inCache;
529 input FCore.Graph inEnv;
530 input Absyn.Path inPath "The path of the class to lookup";
531 input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion.";
532 input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment";
533 input Option<SourceInfo> inInfo;
534 output FCore.Cache outCache;
535 output SCode.Element outClass;
536 output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)";
537 output FCore.Scope outPrevFrames;
538 algorithm
539 (outCache,outClass,outEnv,outPrevFrames) := match (inCache,inEnv,inPath,inPrevFrames)
540 local
541 FCore.Ref r;
542 FCore.Cache cache;
543 SCode.Element c;
544 FCore.Graph env,env_1,env_2;
545 FCore.Scope prevFrames;
546 Absyn.Path path;
547 String id,pack;
548 Option<FCore.Ref> optFrame;
549
550 // Fully qualified names are looked up in top scope. With previous frames remembered.
551 case (cache,env,Absyn.FULLYQUALIFIED(path),{})
552 algorithm
553
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 456301 times.
456301 r::prevFrames := listReverse(FGraph.currentScope(env));
554 456301 Mutable.update(inState,true);
555 456301 env := FGraph.setScope(env, {r});
556 456301 (cache,c,env_1,prevFrames) := lookupClass2(cache,env,path,prevFrames,inState,inInfo);
557 then
558 (cache,c,env_1,prevFrames);
559
560 // Qualified names are handled in a special function in order to avoid infinite recursion.
561 case (cache,env,(Absyn.QUALIFIED(name = pack,path = path)),prevFrames)
562 algorithm
563 1729557 (optFrame,prevFrames) := lookupPrevFrames(pack,prevFrames);
564 1729557 (cache,c,env_2,prevFrames) := lookupClassQualified(cache,env,pack,path,optFrame,prevFrames,inState,inInfo);
565 then
566 (cache,c,env_2,prevFrames);
567
568 // Simple names
569 case (cache,env,Absyn.IDENT(name = id),prevFrames)
570 algorithm
571 2076909 (cache,c,env_1,prevFrames) := lookupClassInEnv(cache, env, id, prevFrames, inState, inInfo);
572 then
573 (cache,c,env_1,prevFrames);
574
575 /*
576 case (cache,env,p,_,_,_)
577 algorithm
578 Debug.traceln("lookupClass failed " + AbsynUtil.pathString(p) + " " + FGraph.printGraphPathStr(env));
579 then fail();
580 */
581 end match;
582 end lookupClass2;
583
584 protected function lookupClassQualified
585 input FCore.Cache inCache;
586 input FCore.Graph inEnv;
587 input String id;
588 input Absyn.Path path;
589 input Option<FCore.Ref> inOptFrame;
590 input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion.";
591 input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment";
592 input Option<SourceInfo> inInfo;
593 output FCore.Cache outCache;
594 output SCode.Element outClass;
595 output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)";
596 output FCore.Scope outPrevFrames;
597 algorithm
598 (outCache,outClass,outEnv,outPrevFrames) := match (inCache, inEnv, inOptFrame, inPrevFrames)
599 local
600 SCode.Element c;
601 FCore.Cache cache;
602 FCore.Graph env;
603 FCore.Scope prevFrames;
604 FCore.Ref frame;
605 Option<FCore.Ref> optFrame;
606
607 // Qualified names first identifier cached in previous frames
608 case (cache, env, SOME(frame), prevFrames)
609 algorithm
610 667999 Mutable.update(inState,true);
611 667999 env := FGraph.pushScopeRef(env, frame);
612 667999 (cache,c,env,prevFrames) := lookupClass2(cache,env,path,prevFrames,inState,inInfo);
613 then
614 (cache,c,env,prevFrames);
615
616 // Qualified names in package and non-package
617 case (cache, env, NONE(), _)
618 algorithm
619 1061558 (cache,c,env,prevFrames) := lookupClassInEnv(cache,env,id,{},inState,inInfo);
620 1048384 (optFrame,prevFrames) := lookupPrevFrames(id,prevFrames);
621 1048384 (cache,c,env,prevFrames) := lookupClassQualified2(cache,env,path,c,optFrame,prevFrames,inState,inInfo);
622 then
623 (cache,c,env,prevFrames);
624
625 end match;
626 end lookupClassQualified;
627
628 protected function lookupClassQualified2
629 input FCore.Cache inCache;
630 input FCore.Graph inEnv;
631 input Absyn.Path path;
632 input SCode.Element inC;
633 input Option<FCore.Ref> optFrame;
634 input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion.";
635 input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment";
636 input Option<SourceInfo> inInfo;
637 output FCore.Cache outCache;
638 output SCode.Element outClass;
639 output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)";
640 output FCore.Scope outPrevFrames;
641 algorithm
642 (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inEnv, inC, optFrame, inPrevFrames)
643 local
644 FCore.Cache cache;
645 FCore.Graph env;
646 FCore.Scope prevFrames;
647 FCore.Ref frame;
648 SCode.Restriction restr;
649 ClassInf.State ci_state;
650 SCode.Encapsulated encflag;
651 String id;
652 SCode.Element c;
653 FCore.Ref r;
654 DAE.Mod mod;
655
656 case (cache, env, _, SOME(frame), prevFrames)
657 algorithm
658 85055 env := FGraph.pushScopeRef(env, frame);
659 85055 (cache,c,env,prevFrames) := lookupClass2(cache,env,path,prevFrames,inState,inInfo);
660 // fprintln(Flags.INST_TRACE, "LOOKUP CLASS QUALIFIED FRAME: " + FGraph.printGraphPathStr(env) + " path: " + AbsynUtil.pathString(path) + " class: " + SCodeDump.shortElementStr(c));
661 then (cache,c,env,prevFrames);
662
663 // class is an instance of a component
664 case (cache, env, SCode.CLASS(name=id), NONE(), _)
665 algorithm
666 963329 r := FNode.child(FGraph.lastScopeRef(env), id);
667
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 963329 times.
✓ Branch 3 taken 963143 times.
✓ Branch 4 taken 186 times.
963329 FCore.CL(status = FCore.CLS_INSTANCE(_)) := FNode.refData(r);
668 // fetch the env
669 186 (cache, env) := Inst.getCachedInstance(cache, env, id, r);
670 186 (cache,c,env,prevFrames) := lookupClass2(cache,env,path,{},inState,inInfo);
671 then (cache,c,env,prevFrames);
672
673 case (cache, env, SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=restr), NONE(), _)
674 algorithm
675 963143 env := FGraph.openScope(env, encflag, id, FGraph.restrictionToScopeType(restr));
676 963143 ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env));
677 // fprintln(Flags.INST_TRACE, "LOOKUP CLASS QUALIFIED PARTIALICD: " + FGraph.printGraphPathStr(env) + " path: " + AbsynUtil.pathString(path) + " class: " + SCodeDump.shortElementStr(c));
678 963143 mod := Mod.getClassModifier(inEnv, id);
679 963143 (cache,env,_,_,_) :=
680 Inst.partialInstClassIn(
681 cache,env,InnerOuter.emptyInstHierarchy,
682 mod, DAE.NOPRE(),
683 ci_state, inC, SCode.PUBLIC(), {}, 0);
684
685 963063 checkPartialScope(env, inEnv, cache, inInfo);
686 963063 (cache,c,env,prevFrames) := lookupClass2(cache,env,path,{},inState,inInfo);
687 then (cache,c,env,prevFrames);
688
689 end matchcontinue;
690 end lookupClassQualified2;
691
692 protected function checkPartialScope
693 input FCore.Graph inEnv;
694 input FCore.Graph inParentEnv;
695 input FCore.Cache inCache;
696 input Option<SourceInfo> inInfo;
697 protected
698 SCode.Element el;
699 DAE.Prefix pre;
700 String name, pre_str, cc_str;
701 SourceInfo cls_info, pre_info, info;
702 algorithm
703
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 963063 times.
✓ Branch 2 taken 403750 times.
✓ Branch 3 taken 559313 times.
✓ Branch 5 taken 403749 times.
✓ Branch 6 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
963063 if isSome(inInfo) and FGraph.isPartialScope(inEnv) and
704 Config.languageStandardAtLeast(Config.LanguageStandard._3_2) then
705
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 FCore.N(data = FCore.CL(e = el, pre = pre)) :=
706 FNode.fromRef(FGraph.lastScopeRef(inEnv));
707 1 name := SCodeUtil.elementName(el);
708
709
2/4
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
1 if FGraph.graphPrefixOf(inParentEnv, inEnv) and not
710 PrefixUtil.isNoPrefix(pre) then
711 ✗ pre_str := PrefixUtil.printPrefixStr(pre);
712 ✗ cls_info := SCodeUtil.elementInfo(el);
713 ✗ pre_info := PrefixUtil.getPrefixInfo(pre);
714 ✗ cc_str := getConstrainingClass(el, FGraph.stripLastScopeRef(inEnv), inCache);
715 ✗ Error.addMultiSourceMessage(Error.USE_OF_PARTIAL_CLASS,
716 {pre_str, name, cc_str}, {cls_info, pre_info});
717 ✗ fail();
718 else
719
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 SOME(info) := inInfo;
720
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if not Config.getGraphicsExpMode() then
721 1 Error.addSourceMessage(Error.LOOKUP_IN_PARTIAL_CLASS, {name}, info);
722 end if;
723 // We should fail here, but the MSL 3.2.1 contains such errors. So just
724 // print an error and continue anyway for now.
725 end if;
726 end if;
727 end checkPartialScope;
728
729 protected function getConstrainingClass
730 input SCode.Element inClass;
731 input FCore.Graph inEnv;
732 input FCore.Cache inCache;
733 output String outPath;
734 algorithm
735 outPath := matchcontinue inClass
736 local
737 Absyn.Path cc_path;
738 Absyn.TypeSpec ts;
739 SCode.Element el;
740 FCore.Graph env;
741
742 case SCode.CLASS(prefixes = SCode.PREFIXES(replaceablePrefix =
743 SCode.REPLACEABLE(cc = SOME(SCode.CONSTRAINCLASS(constrainingClass = cc_path)))))
744 ✗ then AbsynUtil.pathString(cc_path);
745
746 case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = ts))
747 algorithm
748 ✗ (_, el, env) := lookupClass(inCache, inEnv, AbsynUtil.typeSpecPath(ts));
749 ✗ then
750 getConstrainingClass(el, env, inCache);
751
752 ✗ else FGraph.printGraphPathStr(inEnv) + "." + SCodeUtil.elementName(inClass);
753 end matchcontinue;
754 end getConstrainingClass;
755
756 protected function lookupPrevFrames
757 input String id;
758 input FCore.Scope inPrevFrames;
759 output Option<FCore.Ref> outFrame;
760 output FCore.Scope outPrevFrames;
761 algorithm
762 (outFrame,outPrevFrames) := matchcontinue inPrevFrames
763 local
764 String sid;
765 FCore.Scope prevFrames;
766 FCore.Ref ref;
767
768 case ref::prevFrames
769 algorithm
770
2/2
✓ Branch 1 taken 117938 times.
✓ Branch 2 taken 2036366 times.
2154304 false := FNode.isRefTop(ref);
771 2036366 sid := FNode.refName(ref);
772
4/4
✓ Branch 0 taken 1088124 times.
✓ Branch 1 taken 948242 times.
✓ Branch 3 taken 831949 times.
✓ Branch 4 taken 256175 times.
2036366 true := id == sid;
773 then
774 (SOME(ref),prevFrames);
775
776 else (NONE(), {});
777
778 end matchcontinue;
779 end lookupPrevFrames;
780
781 protected function lookupQualifiedImportedVarInFrame
782 "author: PA
783 Looking up variables (constants) imported using qualified imports,
784 i.e. import Modelica.Constants.PI;"
785 input list<Absyn.Import> inImports;
786 input SCode.Ident ident;
787 output DAE.ComponentRef outCref;
788 algorithm
789 outCref := matchcontinue inImports
790 local
791 String id;
792 list<Absyn.Import> rest;
793 Absyn.Path path;
794
795 // For imported simple name, e.g. A, not possible to assert sub-path package
796 case Absyn.QUAL_IMPORT(path = path) :: _
797 algorithm
798 ✗ id := AbsynUtil.pathLastIdent(path);
799 ✗ true := id == ident;
800 ✗ then ComponentReference.pathToCref(path);
801
802 // Named imports, e.g. import A = B.C;
803 case Absyn.NAMED_IMPORT(name = id,path = path) :: _
804 algorithm
805
4/4
✓ Branch 0 taken 122838 times.
✓ Branch 1 taken 799484 times.
✓ Branch 3 taken 31189 times.
✓ Branch 4 taken 91649 times.
922322 true := id == ident;
806 91649 then ComponentReference.pathToCref(path);
807
808 // Check next frame.
809 830673 case _ :: rest then lookupQualifiedImportedVarInFrame(rest, ident);
810 end matchcontinue;
811 end lookupQualifiedImportedVarInFrame;
812
813 protected function moreLookupUnqualifiedImportedVarInFrame
814 "Helper function for lookup_unqualified_imported_var_in_frame. Returns
815 true if there are unqualified imports that matches a sought constant."
816 input FCore.Cache inCache;
817 input list<Absyn.Import> inImports;
818 input FCore.Graph inEnv;
819 input SCode.Ident inIdent;
820 output FCore.Cache outCache;
821 output Boolean outBoolean;
822 algorithm
823 (outCache,outBoolean) := matchcontinue (inCache,inImports,inEnv,inIdent)
824 local
825 FCore.Ref f;
826 String ident;
827 Boolean res;
828 FCore.Graph env;
829 FCore.Scope prevFrames;
830 list<Absyn.Import> rest;
831 FCore.Cache cache;
832 DAE.ComponentRef cref;
833 Absyn.Path path;
834
835 case (cache,Absyn.UNQUAL_IMPORT(path = path) :: _,env,ident)
836 algorithm
837 ✗ f::prevFrames := listReverse(FGraph.currentScope(env));
838 ✗ cref := ComponentReference.pathToCref(path);
839 ✗ cref := ComponentReference.crefPrependIdent(cref,ident,{},DAE.T_UNKNOWN_DEFAULT);
840 ✗ env := FGraph.setScope(env, {f});
841 ✗ (cache,_,_,_,_,_,_,_,_) := lookupVarInPackages(cache,env,cref,prevFrames,Mutable.create(false));
842 ✗ then
843 (cache,true);
844
845 // look into the parent scope
846 case (cache,(_ :: rest),env,ident)
847 algorithm
848 ✗ (cache, res) := moreLookupUnqualifiedImportedVarInFrame(cache, rest, env, ident);
849 then
850 (cache, res);
851
852 // we reached the end, no more lookup
853 66 case (cache,{},_,_) then (cache, false);
854
855 end matchcontinue;
856 end moreLookupUnqualifiedImportedVarInFrame;
857
858 protected function lookupUnqualifiedImportedVarInFrame "Find a variable from an unqualified import locally in a frame"
859 input FCore.Cache inCache;
860 input list<Absyn.Import> inImports;
861 input FCore.Graph inEnv;
862 input SCode.Ident inIdent;
863 output FCore.Cache outCache;
864 output FCore.Graph outClassEnv;
865 output DAE.Attributes outAttributes;
866 output DAE.Type outType;
867 output DAE.Binding outBinding;
868 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
869 output Boolean outBoolean;
870 output InstTypes.SplicedExpData splicedExpData;
871 output FCore.Graph outComponentEnv;
872 output String name;
873 algorithm
874 (outCache,outClassEnv,outAttributes,outType,outBinding,constOfForIteratorRange,outBoolean,splicedExpData,outComponentEnv,name):=
875 matchcontinue (inCache,inImports,inEnv,inIdent)
876 local
877 FCore.Ref f;
878 DAE.ComponentRef cref;
879 String ident;
880 Boolean more,unique;
881 FCore.Graph env,classEnv,componentEnv,env2;
882 FCore.Scope prevFrames;
883 DAE.Attributes attr;
884 DAE.Type ty;
885 DAE.Binding bind;
886 list<Absyn.Import> rest;
887 FCore.Cache cache;
888 Absyn.Path path;
889 Option<DAE.Const> cnstForRange;
890
891 // unique
892 case (cache,Absyn.UNQUAL_IMPORT(path = path) :: rest,env,ident)
893 algorithm
894
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 700 times.
700 f::prevFrames := listReverse(FGraph.currentScope(env));
895 700 cref := ComponentReference.pathToCref(path);
896 700 cref := ComponentReference.crefPrependIdent(cref,ident,{},DAE.T_UNKNOWN_DEFAULT);
897 700 env2 := FGraph.setScope(env, {f});
898 700 (cache,classEnv,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env2,cref,prevFrames,Mutable.create(false));
899 66 (cache,more) := moreLookupUnqualifiedImportedVarInFrame(cache, rest, env, ident);
900 66 unique := boolNot(more);
901 66 then
902 (cache,classEnv,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name);
903
904 // search in the parent scopes
905 case (cache,_ :: rest,env,ident)
906 algorithm
907 634 (cache,classEnv,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name) := lookupUnqualifiedImportedVarInFrame(cache, rest, env, ident);
908 then
909 (cache,classEnv,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name);
910 end matchcontinue;
911 end lookupUnqualifiedImportedVarInFrame;
912
913 protected function lookupQualifiedImportedClassInFrame
914 "Helper function to lookupQualifiedImportedClassInEnv."
915 input FCore.Cache inCache;
916 input list<Absyn.Import> inImport;
917 input FCore.Graph inEnv;
918 input SCode.Ident inIdent;
919 input Mutable<Boolean> inState;
920 input Option<SourceInfo> inInfo;
921 output FCore.Cache outCache;
922 output SCode.Element outClass;
923 output FCore.Graph outEnv;
924 output FCore.Scope outPrevFrames;
925 algorithm
926 (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inImport, inEnv, inIdent)
927 local
928 FCore.Ref r;
929 SCode.Element c;
930 FCore.Graph env_1,env;
931 FCore.Scope prevFrames;
932 String id,ident;
933 list<Absyn.Import> rest;
934 Absyn.Path path;
935 FCore.Cache cache;
936
937 case (cache, Absyn.QUAL_IMPORT(path = Absyn.IDENT(name = id)) :: _, env, ident)
938 algorithm
939 ✗ true := id == ident "For imported paths A, not possible to assert sub-path package";
940 ✗ Mutable.update(inState,true);
941 ✗ r::prevFrames := listReverse(FGraph.currentScope(env));
942 ✗ env := FGraph.setScope(env, {r});
943 ✗ (cache,c,env_1,prevFrames) := lookupClassInEnv(cache,env,id,prevFrames,Mutable.create(false),inInfo);
944 then
945 (cache,c,env_1,prevFrames);
946
947 case (cache, Absyn.QUAL_IMPORT(path = path) :: _, env, ident)
948 algorithm
949 ✗ id := AbsynUtil.pathLastIdent(path) "For imported path A.B.C, assert A.B is package" ;
950 ✗ true := id == ident;
951 ✗ Mutable.update(inState,true);
952
953 ✗ r::prevFrames := listReverse(FGraph.currentScope(env));
954 ✗ env := FGraph.setScope(env, {r});
955 // strippath = AbsynUtil.stripLast(path);
956 // (cache,c2,env_1,_) = lookupClass2(cache,{fr},strippath,prevFrames,Mutable.create(false),true);
957 ✗ (cache,c,env_1,prevFrames) := lookupClass2(cache,env,path,prevFrames,Mutable.create(false),inInfo);
958 then
959 (cache,c,env_1,prevFrames);
960
961 case (cache, Absyn.NAMED_IMPORT(name = id,path = path) :: _, env, ident)
962 algorithm
963
4/4
✓ Branch 0 taken 170841 times.
✓ Branch 1 taken 2061641 times.
✓ Branch 3 taken 54973 times.
✓ Branch 4 taken 115868 times.
2232482 true := id == ident "Named imports";
964 115868 Mutable.update(inState,true);
965
966
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 115868 times.
115868 r::prevFrames := listReverse(FGraph.currentScope(env));
967 115868 env := FGraph.setScope(env, {r});
968 // strippath = AbsynUtil.stripLast(path);
969 // Debug.traceln("named import " + id + " is " + AbsynUtil.pathString(path));
970 // (cache,c2,env_1,prevFrames) = lookupClass2(cache,{fr},strippath,prevFrames,Mutable.create(false),true);
971 115868 (cache,c,env_1,prevFrames) := lookupClass2(cache,env,path,prevFrames,Mutable.create(false),inInfo);
972 then
973 (cache,c,env_1,prevFrames);
974
975 case (cache, _ :: rest, env, ident)
976 algorithm
977 2116658 (cache,c,env_1,prevFrames) := lookupQualifiedImportedClassInFrame(cache,rest,env,ident,inState,inInfo);
978 then
979 (cache,c,env_1,prevFrames);
980
981 end matchcontinue;
982 end lookupQualifiedImportedClassInFrame;
983
984 protected function moreLookupUnqualifiedImportedClassInFrame
985 "Helper function for lookupUnqualifiedImportedClassInFrame"
986 input FCore.Cache inCache;
987 input list<Absyn.Import> inImports;
988 input FCore.Graph inEnv;
989 input SCode.Ident inIdent;
990 output FCore.Cache outCache;
991 output Boolean outBoolean;
992 algorithm
993 (outCache,outBoolean) := matchcontinue (inCache,inImports,inEnv,inIdent)
994 local
995 SCode.Element c;
996 String id,ident;
997 SCode.Encapsulated encflag;
998 Boolean res;
999 SCode.Restriction restr;
1000 FCore.Graph env_1,env2,env;
1001 ClassInf.State ci_state;
1002 Absyn.Path path;
1003 list<Absyn.Import> rest;
1004 FCore.Cache cache;
1005 FCore.Ref r;
1006 DAE.Mod mod;
1007
1008 // Not found, instantiate
1009 case (cache,Absyn.UNQUAL_IMPORT(path = path) :: _,env,ident)
1010 algorithm
1011 ✗ env := FGraph.topScope(env);
1012 ✗ (cache,(c as SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=restr)),env_1) := lookupClass(cache, env, path);
1013 ✗ env2 := FGraph.openScope(env_1, encflag, id, FGraph.restrictionToScopeType(restr));
1014 ✗ ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env2));
1015 // fprintln(Flags.INST_TRACE, "LOOKUP MORE UNQUALIFIED IMPORTED ICD: " + FGraph.printGraphPathStr(env) + "." + ident);
1016 ✗ mod := Mod.getClassModifier(env_1, id);
1017 ✗ (cache, env, _,_,_) := Inst.partialInstClassIn(cache, env2, InnerOuter.emptyInstHierarchy, mod, DAE.NOPRE(), ci_state, c, SCode.PUBLIC(), {}, 0);
1018 ✗ r := FGraph.lastScopeRef(env);
1019 ✗ env := FGraph.setScope(env, {r});
1020 ✗ (cache,_,_) := lookupClass(cache, env, Absyn.IDENT(ident));
1021 ✗ then
1022 (cache, true);
1023
1024 // Look in the parent scope
1025 case (cache,_ :: rest,env,ident)
1026 algorithm
1027 ✗ (cache, res) := moreLookupUnqualifiedImportedClassInFrame(cache, rest, env, ident);
1028 then
1029 (cache, res);
1030
1031 1000 case (cache,{},_,_) then (cache,false);
1032
1033 end matchcontinue;
1034 end moreLookupUnqualifiedImportedClassInFrame;
1035
1036 protected function lookupUnqualifiedImportedClassInFrame
1037 "Finds a class from an unqualified import locally in a frame"
1038 input FCore.Cache inCache;
1039 input list<Absyn.Import> inImports;
1040 input FCore.Graph inEnv;
1041 input SCode.Ident inIdent;
1042 input Option<SourceInfo> inInfo;
1043 output FCore.Cache outCache;
1044 output SCode.Element outClass;
1045 output FCore.Graph outEnv;
1046 output FCore.Scope outPrevFrames;
1047 output Boolean outBoolean;
1048 algorithm
1049 (outCache,outClass,outEnv,outPrevFrames,outBoolean) := matchcontinue (inCache,inImports,inEnv,inIdent)
1050 local
1051 FCore.Ref r;
1052 SCode.Element c,c_1;
1053 String id,ident;
1054 SCode.Encapsulated encflag;
1055 Boolean more,unique;
1056 SCode.Restriction restr;
1057 FCore.Graph env_1,env2,env, env3;
1058 FCore.Scope prevFrames;
1059 ClassInf.State ci_state;
1060 Absyn.Path path;
1061 list<Absyn.Import> rest;
1062 FCore.Cache cache;
1063 DAE.Mod mod;
1064
1065 // Not in cache, instantiate, unique
1066 case (cache,Absyn.UNQUAL_IMPORT(path = path) :: rest,env,ident)
1067 algorithm
1068
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1627 times.
1627 r::prevFrames := listReverse(FGraph.currentScope(env));
1069 1627 env3 := FGraph.setScope(env, {r});
1070
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1627 times.
1627 (cache,(c as
1071 SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=restr)),env_1,prevFrames)
1072 := lookupClass2(cache,env3,path,prevFrames,Mutable.create(false),inInfo);
1073 1627 env2 := FGraph.openScope(env_1, encflag, id, FGraph.restrictionToScopeType(restr));
1074 1627 ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env2));
1075 // fprintln(Flags.INST_TRACE, "LOOKUP UNQUALIFIED IMPORTED ICD: " + FGraph.printGraphPathStr(env) + "." + ident);
1076 1627 mod := Mod.getClassModifier(env_1, id);
1077 1627 (cache,env2,_,_,_) :=
1078 Inst.partialInstClassIn(cache, env2, InnerOuter.emptyInstHierarchy,
1079 mod, DAE.NOPRE(), ci_state, c, SCode.PUBLIC(), {}, 0);
1080 // Restrict import to the imported scope only, not its parents, thus {f} below
1081 1627 (cache,c_1,env2,prevFrames) := lookupClassInEnv(cache,env2,ident,prevFrames,Mutable.create(true),inInfo) "Restrict import to the imported scope only, not its parents..." ;
1082 1000 (cache,more) := moreLookupUnqualifiedImportedClassInFrame(cache, rest, env, ident);
1083 1000 unique := boolNot(more);
1084 1000 then
1085 (cache,c_1,env2,prevFrames,unique);
1086
1087 // Look in the parent scope
1088 case (cache,_ :: rest,env,ident)
1089 algorithm
1090 627 (cache,c,env_1,prevFrames,unique) := lookupUnqualifiedImportedClassInFrame(cache, rest, env, ident,inInfo);
1091 then
1092 (cache,c,env_1,prevFrames,unique);
1093
1094 end matchcontinue;
1095 end lookupUnqualifiedImportedClassInFrame;
1096
1097 public function lookupRecordConstructorClass
1098 "Searches for a record constructor implicitly defined by a record class."
1099 input FCore.Cache inCache;
1100 input FCore.Graph inEnv;
1101 input Absyn.Path inPath;
1102 output FCore.Cache outCache;
1103 output SCode.Element outClass;
1104 output FCore.Graph outEnv;
1105 algorithm
1106 (outCache,outClass,outEnv) := match (inCache,inEnv,inPath)
1107 local
1108 SCode.Element c;
1109 FCore.Graph env,env_1;
1110 Absyn.Path path;
1111 FCore.Cache cache;
1112
1113 case (cache,env,path)
1114 algorithm
1115 13 (cache,c,env_1) := lookupClass(cache,env, path);
1116
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 SCode.CLASS( restriction=SCode.R_RECORD(_)) := c;
1117 13 (cache,_,c) := buildRecordConstructorClass(cache,env_1,c);
1118
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 then
1119 (cache,c,env_1);
1120 end match;
1121 end lookupRecordConstructorClass;
1122
1123 public function lookupConnectorVar
1124 "Simplified lookup of connector references. The lookup will stop if it finds a
1125 deleted component, so if status is VAR_DELETED() then attr and ty will belong
1126 to the deleted component instead of the looked for component."
1127 input FCore.Graph env;
1128 input DAE.ComponentRef cr;
1129 input Boolean firstId = true;
1130 output DAE.Attributes attr;
1131 output DAE.Type ty;
1132 output FCore.Status status;
1133 output Boolean isExpandable = false;
1134 protected
1135 FCore.Graph comp_env;
1136 DAE.Attributes parent_attr;
1137 algorithm
1138 (attr, ty, status) := match cr
1139 case DAE.CREF_IDENT()
1140 algorithm
1141 34572 (DAE.TYPES_VAR(attributes = attr, ty = ty), status, _) :=
1142 lookupConnectorVar2(env, cr.ident);
1143 32770 ty := checkSubscripts(ty, cr.subscriptLst);
1144 32770 then
1145 (attr, ty, status);
1146
1147 case DAE.CREF_QUAL()
1148 algorithm
1149 40761 (DAE.TYPES_VAR(attributes = parent_attr, ty = ty), status, comp_env) :=
1150 lookupConnectorVar2(env, cr.ident);
1151
1152
2/2
✓ Branch 1 taken 40536 times.
✓ Branch 2 taken 225 times.
40761 if FCore.isDeletedComp(status) then
1153 // Stop if we find a deleted component.
1154 attr := parent_attr;
1155 else
1156 try
1157 40536 (attr, ty, status, isExpandable) :=
1158 lookupConnectorVar(comp_env, cr.componentRef, false);
1159 else
1160
1/2
✓ Branch 1 taken 1802 times.
✗ Branch 2 not taken.
1802 if Types.isExpandableConnector(ty) then
1161 1802 attr := parent_attr;
1162 1802 isExpandable := true;
1163 else
1164 ✗ fail();
1165 end if;
1166 end try;
1167
1168 // Propagate variability.
1169 40536 attr := DAEUtil.setAttrVariability(attr, SCodeUtil.variabilityOr(
1170 DAEUtil.getAttrVariability(attr), DAEUtil.getAttrVariability(parent_attr)));
1171
1172 // Use the inner/outer from the first identifier.
1173
2/2
✓ Branch 0 taken 31240 times.
✓ Branch 1 taken 9296 times.
40536 if firstId then
1174 31240 attr := DAEUtil.setAttrInnerOuter(attr, DAEUtil.getAttrInnerOuter(parent_attr));
1175 end if;
1176 end if;
1177 40761 then
1178 (attr, ty, status);
1179
1180 end match;
1181 end lookupConnectorVar;
1182
1183 protected function lookupConnectorVar2
1184 "Helper function to lookupConnectorVar."
1185 input FCore.Graph env;
1186 input String name;
1187 output DAE.Var var;
1188 output FCore.Status status;
1189 output FCore.Graph compEnv;
1190 protected
1191 FCore.Scope scope;
1192 FCore.Children ht;
1193 algorithm
1194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 75333 times.
75333 FCore.G(scope = scope) := env;
1195
1196 // Connectors are not allowed to be constant, so we don't need to look outside
1197 // the local scope. But we do need to check outside implicit scopes, e.g.
1198 // for-scopes.
1199
1/2
✓ Branch 0 taken 75637 times.
✗ Branch 1 not taken.
75637 for r in scope loop
1200 75637 ht := FNode.children(FNode.fromRef(r));
1201
1202 try
1203 75637 (var, _, _, status, compEnv) := lookupVar2(ht, name, env);
1204
1/2
✓ Branch 0 taken 73531 times.
✗ Branch 1 not taken.
73531 return;
1205 else
1206 // Continue to the next scope only if the current scope is implicit.
1207
2/2
✓ Branch 1 taken 1802 times.
✓ Branch 2 taken 304 times.
2106 true := FNode.isImplicitRefName(r);
1208 end try;
1209 end for;
1210
1211 ✗ fail();
1212 end lookupConnectorVar2;
1213
1214 public function lookupVar
1215 "LS: when looking up qualified component reference, lookupVar only
1216 checks variables when looking for the prefix, i.e. for Constants.PI
1217 where Constants is a package and is implicitly instantiated, PI is not
1218 found since Constants is not a variable (it is a type and/or class).
1219
1220 1) One option is to make it a variable and put it in the global frame.
1221 2) Another option is to add a lookup rule that also looks in types.
1222
1223 Now implicitly instantiated packages exists both as a class and as a
1224 type (see implicit_instantiation in Inst.mo). Is this correct?
1225
1226 lookupVar is modified to implement 2. Is this correct?
1227
1228 old lookupVar is changed to lookupVarInternal and a new lookupVar
1229 is written, that first tests the old lookupVar, and if not found
1230 looks in the types
1231
1232 function: lookupVar
1233
1234 This function tries to finds a variable in the environment
1235
1236 Arg1: The environment to search in
1237 Arg2: The variable to search for."
1238 input FCore.Cache inCache;
1239 input FCore.Graph inEnv;
1240 input DAE.ComponentRef inComponentRef;
1241 output FCore.Cache outCache;
1242 output DAE.Attributes outAttributes;
1243 output DAE.Type outType;
1244 output DAE.Binding outBinding;
1245 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
1246 output InstTypes.SplicedExpData outSplicedExpData;
1247 output FCore.Graph outClassEnv "only used for package constants";
1248 output FCore.Graph outComponentEnv "only used for package constants";
1249 output String name "so the FQ path can be constructed";
1250 algorithm
1251 (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,outSplicedExpData,outClassEnv,outComponentEnv,name) :=
1252 matchcontinue (inCache,inEnv,inComponentRef)
1253 local
1254 DAE.Attributes attr;
1255 DAE.Type ty;
1256 DAE.Binding binding;
1257 FCore.Graph env, componentEnv, classEnv;
1258 DAE.ComponentRef cref;
1259 FCore.Cache cache;
1260 InstTypes.SplicedExpData splicedExpData;
1261 Option<DAE.Const> cnstForRange;
1262
1263 /*/ debugging
1264 case (cache,env,cref)
1265 algorithm
1266 print("CO: " + ComponentReferenceBasics.printComponentRefStr(cref) + " env: " + FGraph.printGraphPathStr(env) + "\n");
1267 then
1268 fail();*/
1269
1270 // try the old lookupVarInternal
1271 case (cache,env,cref)
1272 algorithm
1273 2720161 (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name) := lookupVarInternal(cache, env, cref, InstTypes.SEARCH_ALSO_BUILTIN());
1274 then
1275 (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name);
1276
1277 // then look in classes (implicitly instantiated packages)
1278 case (cache,env,cref)
1279 algorithm
1280 758656 (cache,classEnv,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cref,{},Mutable.create(false));
1281 60343 checkPackageVariableConstant(env,classEnv,componentEnv,attr,ty,cref);
1282 // optional Expression.exp to return
1283 60331 then
1284 (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name);
1285
1286 ✗ case (cache,env,_) guard Config.getGraphicsExpMode() then (cache,DAE.dummyAttrConst,DAE.T_UNKNOWN_DEFAULT,DAE.UNBOUND(),NONE(),InstTypes.SPLICEDEXPDATA(NONE(),DAE.T_UNKNOWN_DEFAULT),env,env,"#varNotFound#");
1287
1288 /*/ fail if we couldn't find it
1289 case (_,env,cref)
1290 algorithm
1291 fprintln(Flags.FAILTRACE, "- Lookup.lookupVar failed:\n" +
1292 ComponentReferenceBasics.printComponentRefStr(cref) + " in:\n" +
1293 FGraph.printGraphPathStr(env));
1294 then fail();*/
1295 end matchcontinue;
1296 end lookupVar;
1297
1298 public function lookupVarIdent "Like lookupVar, but takes only an ident+subscript."
1299 input FCore.Cache inCache;
1300 input FCore.Graph inEnv;
1301 input String ident;
1302 input list<DAE.Subscript> ss={};
1303 output FCore.Cache outCache;
1304 output DAE.Attributes outAttributes;
1305 output DAE.Type outType;
1306 output DAE.Binding outBinding;
1307 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
1308 output InstTypes.SplicedExpData outSplicedExpData;
1309 output FCore.Graph outClassEnv "only used for package constants";
1310 output FCore.Graph outComponentEnv "only used for package constants";
1311 output String name "so the FQ path can be constructed";
1312 algorithm
1313 (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,outSplicedExpData,outClassEnv,outComponentEnv,name) :=
1314 matchcontinue (inCache,inEnv)
1315 local
1316 DAE.Attributes attr;
1317 DAE.Type ty;
1318 DAE.Binding binding;
1319 FCore.Graph env, componentEnv, classEnv;
1320 DAE.ComponentRef cref;
1321 FCore.Cache cache;
1322 InstTypes.SplicedExpData splicedExpData;
1323 Option<DAE.Const> cnstForRange;
1324
1325 // try the old lookupVarInternal
1326 case (cache,env)
1327 algorithm
1328 639334 (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name) := lookupVarInternalIdent(cache, env, ident, ss, InstTypes.SEARCH_ALSO_BUILTIN());
1329 then
1330 (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name);
1331
1332 // then look in classes (implicitly instantiated packages)
1333 case (cache,env)
1334 algorithm
1335 // TODO: Skip makeCrefIdent by rewriting lookupVarInPackages
1336 512924 cref := ComponentReferenceBasics.makeCrefIdent(ident, DAE.T_UNKNOWN_DEFAULT, ss);
1337 512924 (cache,classEnv,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cref,{},Mutable.create(false));
1338 199 checkPackageVariableConstant(env,classEnv,componentEnv,attr,ty,cref);
1339 // optional Expression.exp to return
1340 199 then
1341 (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name);
1342
1343 end matchcontinue;
1344 end lookupVarIdent;
1345
1346 protected function checkPackageVariableConstant "
1347 Variables in packages must be constant. This function produces an error message and fails
1348 if variable is not constant."
1349 input FCore.Graph parentEnv;
1350 input FCore.Graph classEnv;
1351 input FCore.Graph componentEnv;
1352 input DAE.Attributes attr;
1353 input DAE.Type tp;
1354 input DAE.ComponentRef cref;
1355 algorithm
1356 () := match attr
1357 local
1358 String s1,s2;
1359
1360 // do not fail if is a constant
1361 case DAE.ATTR(variability = SCode.CONST()) then ();
1362
1363 /*/ do not fail if is a parameter in non-package
1364 case (_, _, _,DAE.ATTR(variability = SCode.PARAM()),_,_)
1365 algorithm
1366 FCore.CL(e = cl) = FNode.refData(FGraph.lastScopeRef(classEnv));
1367 false = SCodeUtil.isPackage(cl);
1368 // print("cref: " + ComponentReferenceBasics.printComponentRefStr(cref) + "\nprenv: " + FGraph.getGraphNameStr(parentEnv) + "\nclenv: " + FGraph.getGraphNameStr(classEnv) + "\ncoenv: " + FGraph.getGraphNameStr(componentEnv) + "\n");
1369 then
1370 ();*/
1371
1372 // fail if is not a constant
1373 else
1374 algorithm
1375 12 s1 := ComponentReferenceBasics.printComponentRefStr(cref);
1376 12 s2 := FGraph.printGraphPathStr(classEnv);
1377 12 Error.addMessage(Error.PACKAGE_VARIABLE_NOT_CONSTANT,{s1,s2});
1378
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 true := Flags.isSet(Flags.FAILTRACE);
1379 ✗ Debug.traceln("- Lookup.checkPackageVariableConstant failed: " + s1 + " in " + s2);
1380 ✗ then fail();
1381 end match;
1382 end checkPackageVariableConstant;
1383
1384 public function lookupVarInternal "Helper function to lookupVar. Searches the frames for variables."
1385 input FCore.Cache inCache;
1386 input FCore.Graph inEnv;
1387 input DAE.ComponentRef inComponentRef;
1388 input InstTypes.SearchStrategy searchStrategy "if SEARCH_LOCAL_ONLY it won't search in the builtin scope";
1389 output FCore.Cache outCache;
1390 output DAE.Attributes outAttributes;
1391 output DAE.Type outType;
1392 output DAE.Binding outBinding;
1393 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
1394 output InstTypes.SplicedExpData splicedExpData;
1395 output FCore.Graph outClassEnv "the environment of the variable, typically the same as input, but e.g. for loop scopes can be 'stripped'";
1396 output FCore.Graph outComponentEnv "the component environment of the variable";
1397 output String name;
1398 algorithm
1399 (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outClassEnv,outComponentEnv,name) :=
1400 matchcontinue (inCache,inEnv,inComponentRef,searchStrategy)
1401 local
1402 DAE.Attributes attr;
1403 DAE.Type ty;
1404 DAE.Binding binding;
1405 FCore.Children ht;
1406 DAE.ComponentRef ref;
1407 FCore.Cache cache;
1408 Option<DAE.Const> cnstForRange;
1409 FCore.Graph env,componentEnv;
1410 FCore.Ref r;
1411
1412 // look into the current frame
1413 case (cache, FCore.G(scope = r :: _), ref, _)
1414 algorithm
1415 2960640 ht := FNode.children(FNode.fromRef(r));
1416 2960640 (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarF(cache, ht, ref, inEnv);
1417 2001256 then
1418 (cache,attr,ty,binding,cnstForRange,splicedExpData,inEnv,componentEnv,name);
1419
1420 // look in the next frame, only if current frame is a for loop scope.
1421 case (cache, FCore.G(scope = r :: _), ref, _)
1422 algorithm
1423
2/2
✓ Branch 1 taken 758624 times.
✓ Branch 2 taken 200760 times.
959384 true := FNode.isImplicitRefName(r);
1424 200760 (env, _) := FGraph.stripLastScopeRef(inEnv);
1425 200760 (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name) := lookupVarInternal(cache, env, ref, searchStrategy);
1426 then
1427 (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name);
1428
1429 // If not in top scope, look in top scope for builtin variables, e.g. time.
1430 case (cache, FCore.G(scope = _::_::_), ref, InstTypes.SEARCH_ALSO_BUILTIN())
1431 algorithm
1432
2/2
✓ Branch 1 taken 377077 times.
✓ Branch 2 taken 3 times.
377080 true := Builtin.variableIsBuiltin(ref);
1433 3 env := FGraph.topScope(inEnv);
1434 3 ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env)));
1435 3 (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarF(cache, ht, ref, env);
1436 3 then
1437 (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name);
1438
1439 end matchcontinue;
1440 end lookupVarInternal;
1441
1442 public function lookupVarInternalIdent "Helper function to lookupVar. Searches the frames for variables."
1443 input FCore.Cache inCache;
1444 input FCore.Graph inEnv;
1445 input String ident;
1446 input list<DAE.Subscript> ss={};
1447 input InstTypes.SearchStrategy searchStrategy = InstTypes.SEARCH_LOCAL_ONLY() "if SEARCH_LOCAL_ONLY it won't search in the builtin scope";
1448 output FCore.Cache outCache;
1449 output DAE.Attributes outAttributes;
1450 output DAE.Type outType;
1451 output DAE.Binding outBinding;
1452 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
1453 output InstTypes.SplicedExpData splicedExpData;
1454 output FCore.Graph outClassEnv "the environment of the variable, typically the same as input, but e.g. for loop scopes can be 'stripped'";
1455 output FCore.Graph outComponentEnv "the component environment of the variable";
1456 output String name;
1457 algorithm
1458 (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outClassEnv,outComponentEnv,name) :=
1459 matchcontinue (inCache,inEnv,searchStrategy)
1460 local
1461 DAE.Attributes attr;
1462 DAE.Type ty;
1463 DAE.Binding binding;
1464 FCore.Children ht;
1465 FCore.Cache cache;
1466 Option<DAE.Const> cnstForRange;
1467 FCore.Graph env,componentEnv;
1468 FCore.Ref r;
1469
1470 // look into the current frame
1471 case (cache, FCore.G(scope = r :: _), _)
1472 algorithm
1473 4605667 ht := FNode.children(FNode.fromRef(r));
1474 4605667 (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarFIdent(cache, ht, ident, ss, inEnv);
1475 186471 then
1476 (cache,attr,ty,binding,cnstForRange,splicedExpData,inEnv,componentEnv,name);
1477
1478 // look in the next frame, only if current frame is a for loop scope.
1479 case (cache, FCore.G(scope = r :: _), _)
1480 algorithm
1481
2/2
✓ Branch 1 taken 4207682 times.
✓ Branch 2 taken 211514 times.
4419196 true := FNode.isImplicitRefName(r);
1482 211514 (env, _) := FGraph.stripLastScopeRef(inEnv);
1483 211514 (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name) := lookupVarInternalIdent(cache, env, ident, ss, searchStrategy);
1484 then
1485 (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name);
1486
1487 // If not in top scope, look in top scope for builtin variables, e.g. time.
1488 case (cache, FCore.G(scope = _::_::_), InstTypes.SEARCH_ALSO_BUILTIN())
1489 algorithm
1490
2/2
✓ Branch 1 taken 510474 times.
✓ Branch 2 taken 11 times.
510485 true := Builtin.variableNameIsBuiltin(ident);
1491 11 env := FGraph.topScope(inEnv);
1492 11 ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env)));
1493 11 (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarFIdent(cache, ht, ident, ss, env);
1494 11 then
1495 (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name);
1496
1497 end matchcontinue;
1498 end lookupVarInternalIdent;
1499
1500 protected function frameIsImplAddedScope
1501 "returns true if the frame is a for-loop scope or a valueblock scope.
1502 This is indicated by the name of the frame."
1503 input FCore.Node f;
1504 output Boolean b;
1505 algorithm
1506 b := match f
1507 local
1508 FCore.Name oname;
1509 6028 case FCore.N(name=oname) then FCore.isImplicitScope(oname);
1510 else false;
1511 end match;
1512 end frameIsImplAddedScope;
1513
1514 public function lookupVarInPackages "This function is called when a lookup of a variable with qualified names
1515 does not have the first element as a component, e.g. A.B.C is looked up
1516 where A is not a component. This implies that A is a class, and this
1517 class should be temporary instantiated, and the lookup should
1518 be performed within that class. I.e. the function performs lookup of
1519 variables in the class hierarchy.
1520
1521 Note: the splicedExpData is currently not relevant, since constants are always evaluated to a value.
1522 However, this might change in the future since it makes more sense to calculate the constants
1523 during setup in runtime (to gain precision and postpone choice of precision to runtime)."
1524 input FCore.Cache inCache;
1525 input FCore.Graph inEnv;
1526 input DAE.ComponentRef inComponentRef;
1527 input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion.";
1528 input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in a lower scope.";
1529 output FCore.Cache outCache;
1530 output FCore.Graph outClassEnv;
1531 output DAE.Attributes outAttributes;
1532 output DAE.Type outType;
1533 output DAE.Binding outBinding;
1534 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
1535 output InstTypes.SplicedExpData splicedExpData "currently not relevant for constants, but might be used in the future";
1536 output FCore.Graph outComponentEnv;
1537 output String name "We only return the environment the component was found in; not its FQ name.";
1538 algorithm
1539 (outCache,outClassEnv,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) :=
1540 matchcontinue (inCache, inEnv, inComponentRef, inPrevFrames)
1541 local
1542 SCode.Element c;
1543 String n,id;
1544 SCode.Encapsulated encflag;
1545 SCode.Restriction r;
1546 FCore.Graph env2,env3,env5,env,p_env,componentEnv;
1547 FCore.Scope prevFrames, fs;
1548 ClassInf.State ci_state;
1549 DAE.Attributes attr;
1550 DAE.Type ty;
1551 DAE.Binding bind;
1552 DAE.ComponentRef cref,cr;
1553 FCore.Ref f, rr;
1554 Option<FCore.Ref> of;
1555 FCore.Cache cache;
1556 Option<DAE.Const> cnstForRange;
1557 Absyn.Path scope;
1558 FCore.Children ht;
1559 DAE.Mod mod;
1560
1561 // If we search for A1.A2....An.x while in scope A1.A2...An, just search for x.
1562 // Must do like this to ensure finite recursion
1563 case (cache, env, DAE.CREF_QUAL(ident = id,subscriptLst = {},componentRef = cref), prevFrames)
1564 algorithm
1565 1100296 (of,prevFrames) := lookupPrevFrames(id,prevFrames);
1566 () := match of
1567 // first part of name is a previous frame
1568 case SOME(f)
1569 algorithm
1570 78895 Mutable.update(inState,true);
1571 78895 env5 := FGraph.pushScopeRef(env, f);
1572 then
1573 ();
1574 // no prev frame
1575 case NONE()
1576 algorithm
1577
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 106689 times.
1021401 (cache,(c as SCode.CLASS(name=n,encapsulatedPrefix=encflag,restriction=r)),env2,prevFrames) :=
1578 lookupClassInEnv(cache,
1579 env,
1580 id,
1581 prevFrames,
1582 Mutable.create(true), // In order to use the prevFrames, we need to make sure we can't instantiate one of the classes too soon!
1583 NONE());
1584 106689 Mutable.update(inState,true);
1585 // see if we have an instance of a component!
1586 106689 rr := FNode.child(FGraph.lastScopeRef(env2), id);
1587
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 106689 times.
106689 if FNode.isRefInstance(rr) // is an instance, use it
1588 then
1589 ✗ (cache, env5) := Inst.getCachedInstance(cache, env2, id, rr);
1590 else // not an instance, instantiate it - lookup of constants on form A.B in packages. instantiate package and look inside.
1591 106689 env3 := FGraph.openScope(env2, encflag, n, FGraph.restrictionToScopeType(r));
1592 106689 ci_state := ClassInfUtil.start(r, FGraph.getGraphName(env3));
1593 // fprintln(Flags.INST_TRACE, "LOOKUP VAR IN PACKAGES ICD: " + FGraph.printGraphPathStr(env3) + " var: " + ComponentReferenceBasics.printComponentRefStr(cref));
1594 106689 mod := Mod.getClassModifier(env2, n);
1595 106689 (cache,env5,_,_,_,_,_,_,_,_,_,_) :=
1596 Inst.instClassIn(cache,env3,InnerOuter.emptyInstHierarchy,UnitAbsyn.noStore,
1597 mod, DAE.NOPRE(), ci_state, c, SCode.PUBLIC(), {},
1598 /*true*/false, InstTypes.INNER_CALL(), ConnectionGraph.EMPTY,
1599 Connect.emptySet, NONE());
1600 end if;
1601 then ();
1602 end match;
1603 185582 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env5,cref,prevFrames,inState);
1604 // Add the class name to the spliced exp so that the name is correct.
1605 117400 splicedExpData := prefixSplicedExp(ComponentReferenceBasics.crefFirstCref(inComponentRef), splicedExpData);
1606 117400 then
1607 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name);
1608
1609 // Why is this done? It is already done done in lookupVar!
1610 // BZ: This is due to recursive call when it might become DAE.CREF_IDENT calls.
1611 case (cache, env, (cr as DAE.CREF_IDENT()), _)
1612 algorithm
1613 1244226 (cache,env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackagesIdent(cache, env, cr.ident, cr.subscriptLst, inPrevFrames, inState);
1614 then
1615 (cache,env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name);
1616
1617 // Lookup where the first identifier is a component.
1618 case (cache, env, cr as DAE.CREF_QUAL(), _)
1619 algorithm
1620 987913 ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env)));
1621 868685 (cache, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name) := lookupVarF(cache, ht, cr, env);
1622 474 then
1623 (cache, env, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name);
1624
1625 // Search parent scopes
1626 case (cache, FCore.G(scope = f::fs), cr as DAE.CREF_QUAL(), prevFrames)
1627 algorithm
1628
2/2
✓ Branch 1 taken 68184 times.
✓ Branch 2 taken 800027 times.
868211 false := Mutable.access(inState);
1629 800027 env := FGraph.setScope(inEnv, fs);
1630 800027 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cr,f::prevFrames,inState);
1631 then
1632 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name);
1633
1634 else
1635 algorithm
1636 //true = Flags.isSet(Flags.FAILTRACE);
1637 //Debug.traceln("- Lookup.lookupVarInPackages failed on exp:" + ComponentReferenceBasics.printComponentRefStr(cr) + " in scope: " + FGraph.printGraphPathStr(env));
1638 then
1639 fail();
1640 end matchcontinue;
1641 end lookupVarInPackages;
1642
1643 public function lookupVarInPackagesIdent "This function is called when a lookup of a variable with qualified names
1644 does not have the first element as a component, e.g. A.B.C is looked up
1645 where A is not a component. This implies that A is a class, and this
1646 class should be temporary instantiated, and the lookup should
1647 be performed within that class. I.e. the function performs lookup of
1648 variables in the class hierarchy.
1649
1650 Note: the splicedExpData is currently not relevant, since constants are always evaluated to a value.
1651 However, this might change in the future since it makes more sense to calculate the constants
1652 during setup in runtime (to gain precision and postpone choice of precision to runtime)."
1653 input FCore.Cache inCache;
1654 input FCore.Graph inEnv;
1655 input String id;
1656 input list<DAE.Subscript> ss;
1657 input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion.";
1658 input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in a lower scope.";
1659 output FCore.Cache outCache;
1660 output FCore.Graph outClassEnv;
1661 output DAE.Attributes outAttributes;
1662 output DAE.Type outType;
1663 output DAE.Binding outBinding;
1664 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
1665 output InstTypes.SplicedExpData splicedExpData "currently not relevant for constants, but might be used in the future";
1666 output FCore.Graph outComponentEnv;
1667 output String name "We only return the environment the component was found in; not its FQ name.";
1668 algorithm
1669 (outCache,outClassEnv,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) :=
1670 matchcontinue (inCache, inEnv, inPrevFrames)
1671 local
1672 FCore.Graph env,p_env,componentEnv;
1673 FCore.Scope prevFrames, fs;
1674 FCore.Node node;
1675 DAE.Attributes attr;
1676 DAE.Type ty;
1677 DAE.Binding bind;
1678 DAE.ComponentRef cr;
1679 FCore.Ref f;
1680 FCore.Cache cache;
1681 Option<DAE.Const> cnstForRange;
1682 Absyn.Path scope;
1683 Boolean unique;
1684 FCore.Children ht;
1685 list<Absyn.Import> qimports, uqimports;
1686
1687 // Why is this done? It is already done done in lookupVar!
1688 // BZ: This is due to recursive call when it might become DAE.CREF_IDENT calls.
1689 case (cache, env, _)
1690 algorithm
1691 4719056 (cache,attr,ty,bind,cnstForRange,splicedExpData,_,componentEnv,name) := lookupVarInternalIdent(cache, env, id, ss);
1692 60068 Mutable.update(inState,true);
1693 60068 then
1694 (cache,env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name);
1695
1696 // Lookup where the first identifier is a component.
1697 case (cache, env, _)
1698 algorithm
1699 4658988 ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env)));
1700 3674703 (cache, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name) := lookupVarFIdent(cache, ht, id, ss, env);
1701 ✗ then
1702 (cache, env, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name);
1703
1704 // Search among imports
1705 case (cache, env, prevFrames)
1706 algorithm
1707 4658988 node := FNode.fromRef(FGraph.lastScopeRef(env));
1708 3674703 (qimports, uqimports) := FNode.imports(node);
1709 try
1710 // Search among qualified imports, e.g. import A.B; or import D=A.B;
1711
2/2
✓ Branch 0 taken 222 times.
✓ Branch 1 taken 94537 times.
94759 false := listEmpty(qimports);
1712 94537 cr := lookupQualifiedImportedVarInFrame(qimports, id);
1713 91649 Mutable.update(inState,true);
1714 // if the first name of the import A.B is equal with the scope we are in, skip it!
1715
3/4
✓ Branch 4 taken 3752 times.
✓ Branch 5 taken 87897 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3752 times.
91649 cr := if FNode.name(FNode.fromRef(FGraph.lastScopeRef(env))) == ComponentReferenceBasics.crefFirstIdent(cr)
1716 then ComponentReference.crefStripFirstIdent(cr)
1717 else cr;
1718
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 91649 times.
91649 f::prevFrames := listReverse(FGraph.currentScope(env));
1719 91649 env := FGraph.setScope(env, {f});
1720 91649 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cr,prevFrames,inState);
1721 else
1722 // Search among unqualified imports, e.g. import A.B.*
1723
2/2
✓ Branch 0 taken 94059 times.
✓ Branch 1 taken 700 times.
94759 false := listEmpty(uqimports);
1724 700 (cache,p_env,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name) := lookupUnqualifiedImportedVarInFrame(cache, uqimports, env, id);
1725 66 reportSeveralNamesError(unique,id);
1726 66 Mutable.update(inState,true);
1727 end try;
1728 66 then
1729 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name);
1730
1731 // Search parent scopes
1732 case (cache, FCore.G(scope = f::fs), prevFrames)
1733 algorithm
1734
2/2
✓ Branch 1 taken 215186 times.
✓ Branch 2 taken 3459451 times.
3674637 false := Mutable.access(inState);
1735 3459451 env := FGraph.setScope(inEnv, fs);
1736 3459451 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackagesIdent(cache,env,id,ss,f::prevFrames,inState);
1737 then
1738 (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name);
1739
1740 else
1741 algorithm
1742 //true = Flags.isSet(Flags.FAILTRACE);
1743 //Debug.traceln("- Lookup.lookupVarInPackages failed on exp:" + ComponentReferenceBasics.printComponentRefStr(cr) + " in scope: " + FGraph.printGraphPathStr(env));
1744 then
1745 fail();
1746 end matchcontinue;
1747 end lookupVarInPackagesIdent;
1748
1749 public function lookupVarLocal
1750 "This function is very similar to `lookup_var\', but it only looks
1751 in the topmost environment frame, which means that it only finds
1752 names defined in the local scope.
1753 ----EXCEPTION---: When the topmost scope is the scope of a for loop, the lookup
1754 continues on the next scope. This to allow variables in the local scope to
1755 also be found even if inside a for scope.
1756 Arg1: The environment to search in
1757 Arg2: The variable to search for."
1758 input FCore.Cache inCache;
1759 input FCore.Graph inEnv;
1760 input DAE.ComponentRef inComponentRef;
1761 output FCore.Cache outCache;
1762 output DAE.Attributes outAttributes;
1763 output DAE.Type outType;
1764 output DAE.Binding outBinding;
1765 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
1766 output InstTypes.SplicedExpData splicedExpData;
1767 output FCore.Graph outClassEnv;
1768 output FCore.Graph outComponentEnv;
1769 output String name;
1770 algorithm
1771 // adrpo: use lookupVarInternal as is the SAME but it doesn't search in the builtin scope!
1772 39754 (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outClassEnv,outComponentEnv,name) :=
1773 lookupVarInternal(inCache, inEnv, inComponentRef, InstTypes.SEARCH_LOCAL_ONLY());
1774 end lookupVarLocal;
1775
1776 public function lookupIdentLocal "Searches for a variable in the local scope."
1777 input FCore.Cache inCache;
1778 input FCore.Graph inEnv;
1779 input SCode.Ident inIdent;
1780 output FCore.Cache outCache;
1781 output DAE.Var outVar;
1782 output SCode.Element outElement;
1783 output DAE.Mod outMod;
1784 output FCore.Status instStatus;
1785 output FCore.Graph outComponentEnv;
1786 algorithm
1787 (outCache,outVar,outElement,outMod,instStatus,outComponentEnv):=
1788 matchcontinue (inCache,inEnv,inIdent)
1789 local
1790 DAE.Var fv;
1791 SCode.Element c;
1792 DAE.Mod m;
1793 FCore.Status i;
1794 FCore.Ref r;
1795 FCore.Graph env,componentEnv;
1796 FCore.Children ht;
1797 String id;
1798 FCore.Cache cache;
1799
1800 // component environment
1801 case (cache, FCore.G(scope = r::_), id)
1802 algorithm
1803 799031 ht := FNode.children(FNode.fromRef(r));
1804 799031 (fv,c,m,i,componentEnv) := lookupVar2(ht, id, inEnv);
1805 589437 then
1806 (cache,fv,c,m,i,componentEnv);
1807
1808 // Look in the next frame, if the current frame is a for loop scope.
1809 case (cache, FCore.G(scope = r::_), id)
1810 algorithm
1811
2/2
✓ Branch 1 taken 209593 times.
✓ Branch 2 taken 1 time.
209594 true := FNode.isImplicitRefName(r);
1812 1 (env, _) := FGraph.stripLastScopeRef(inEnv);
1813 1 (cache,fv,c,m,i,componentEnv) := lookupIdentLocal(cache, env, id);
1814 then
1815 (cache,fv,c,m,i,componentEnv);
1816
1817 end matchcontinue;
1818 end lookupIdentLocal;
1819
1820 public function lookupClassLocal "Searches for a class definition in the local scope."
1821 input FCore.Graph inEnv;
1822 input SCode.Ident inIdent;
1823 output SCode.Element outClass;
1824 output FCore.Graph outEnv;
1825 algorithm
1826 (outClass,outEnv) := match(inEnv,inIdent)
1827 local
1828 SCode.Element cl;
1829 FCore.Graph env;
1830 FCore.Children ht;
1831 String id;
1832 FCore.Ref r;
1833
1834 case (env as FCore.G(scope = r::_),id)
1835 algorithm
1836 149362 ht := FNode.children(FNode.fromRef(r));
1837 149362 r := FCore.RefTree.get(ht, id);
1838
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 16743 times.
✓ Branch 3 taken 13478 times.
✓ Branch 4 taken 3265 times.
16743 FCore.N(data = FCore.CL(e = cl)) := FNode.fromRef(r);
1839 then
1840 (cl,env);
1841 end match;
1842 end lookupClassLocal;
1843
1844 public function lookupIdent
1845 "Same as lookupIdentLocal, except check all frames"
1846 input FCore.Cache inCache;
1847 input FCore.Graph inEnv;
1848 input SCode.Ident inIdent;
1849 output FCore.Cache outCache;
1850 output DAE.Var outVar;
1851 output SCode.Element outElement;
1852 output DAE.Mod outMod;
1853 output FCore.Status instStatus;
1854 output FCore.Graph outEnv "the env where we found the ident";
1855 algorithm
1856 (outCache,outVar,outElement,outMod,instStatus,outEnv):=
1857 matchcontinue (inCache,inEnv,inIdent)
1858 local
1859 DAE.Var fv;
1860 SCode.Element c;
1861 DAE.Mod m;
1862 FCore.Status i;
1863 FCore.Children ht;
1864 String id;
1865 FCore.Graph e;
1866 FCore.Cache cache;
1867 FCore.Ref r;
1868
1869 case (cache,FCore.G(scope = r::_),id)
1870 algorithm
1871 520317 ht := FNode.children(FNode.fromRef(r));
1872 520317 (fv,c,m,i,_) := lookupVar2(ht, id, inEnv);
1873 84558 then
1874 (cache,fv,c,m,i,inEnv);
1875
1876 case (cache, FCore.G(scope = _::_),id)
1877 algorithm
1878 435759 (e, _) := FGraph.stripLastScopeRef(inEnv);
1879 435759 (cache,fv,c,m,i,e) := lookupIdent(cache, e, id);
1880 then
1881 (cache,fv,c,m,i,e);
1882
1883 end matchcontinue;
1884 end lookupIdent;
1885
1886 // Function lookup
1887 public function lookupFunctionsInEnv
1888 "Returns a list of types that the function has."
1889 input FCore.Cache inCache;
1890 input FCore.Graph inEnv;
1891 input Absyn.Path inId;
1892 input SourceInfo inInfo;
1893 output FCore.Cache outCache;
1894 output list<DAE.Type> outTypesTypeLst;
1895 algorithm
1896 (outCache,outTypesTypeLst) := matchcontinue (inCache,inEnv,inId,inInfo)
1897 local
1898 FCore.Graph env_1, cenv, env;
1899 list<DAE.Type> res;
1900 list<Absyn.Path> names;
1901 FCore.Children httypes;
1902 FCore.Children ht;
1903 String str, name;
1904 FCore.Cache cache;
1905 Absyn.Path id;
1906 SourceInfo info;
1907
1908 /*
1909 case (cache,env,id,info)
1910 algorithm
1911 print("Looking up: " + AbsynUtil.pathString(id) + " in env: " + FGraph.printGraphPathStr(env) + "\n");
1912 then
1913 fail();*/
1914
1915 /*/ strip env if path is fully qualified in env
1916 case (cache,env,id,info)
1917 algorithm
1918 id = Env.pathStripEnvIfFullyQualifedInEnv(id, env);
1919 (cache,res) = lookupFunctionsInEnv(cache,env,id,info);
1920 then
1921 (cache,res);*/
1922
1923 // we might have a component reference, i.e. world.gravityAcceleration
1924 case (cache,env,Absyn.QUALIFIED(name, id),info)
1925 algorithm
1926 52370 ErrorExt.setCheckpoint("functionViaComponentRef");
1927 52370 (cache,_,_,_,_,_,_,cenv,_) := lookupVarIdent(cache, env, name, {});
1928 11128 (cache, res) := lookupFunctionsInEnv(cache, cenv, id, info);
1929 11128 ErrorExt.rollBack("functionViaComponentRef");
1930 11128 then
1931 (cache,res);
1932
1933 case (_,_,Absyn.QUALIFIED(_, _),_)
1934 algorithm
1935 41242 ErrorExt.rollBack("functionViaComponentRef");
1936 41242 then
1937 fail();
1938
1939 // here we do some bad things which unfortunately are needed for some MSL models (MoistAir1)
1940 // we search the environment in reverse instead of finding out where the first id of the path is
1941 case (cache,env,id,_)
1942 algorithm
1943 74956 env := FGraph.selectScope(env, id);
1944 233 name := AbsynUtil.pathLastIdent(id);
1945 233 (cache, res) := lookupFunctionsInEnv(cache, env, Absyn.IDENT(name), inInfo);
1946 then
1947 (cache,res);
1948
1949 // Builtin operators are looked up in top frame directly
1950 case (cache,env,(Absyn.IDENT(name = str)),info)
1951 algorithm
1952 29544 Static.elabBuiltinHandler(str) "Check for builtin operators";
1953 4367 env := FGraph.topScope(env);
1954 4367 ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env)));
1955 4367 httypes := getHtTypes(FGraph.lastScopeRef(env));
1956 4367 (cache,res) := lookupFunctionsInFrame(cache, ht, httypes, env, str, info);
1957 then
1958 (cache,res);
1959
1960 // Check for cardinality that can not be represented in the environment.
1961 case (cache,env,Absyn.IDENT(name = str as "cardinality"),_)
1962 algorithm
1963 ✗ env := FGraph.topScope(env);
1964 ✗ res := createGenericBuiltinFunctions(env, str);
1965 ✗ then
1966 (cache,res);
1967
1968 // not fully qualified!
1969 case (cache,env,id,info)
1970 algorithm
1971
3/4
✓ Branch 0 taken 70357 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 66292 times.
✓ Branch 3 taken 4065 times.
70357 failure(Absyn.FULLYQUALIFIED(_) := id);
1972 66292 (cache,res) := lookupFunctionsInEnv2(cache,env,id,false,info);
1973 then
1974 (cache,res);
1975
1976 // fullyqual
1977 case (cache,env,Absyn.FULLYQUALIFIED(id),info)
1978 algorithm
1979 4065 env := FGraph.topScope(env);
1980 4065 (cache,res) := lookupFunctionsInEnv2(cache,env,id,true,info);
1981 then
1982 (cache,res);
1983
1984 case (cache,env,id,_)
1985 algorithm
1986 id := match id
1987 case Absyn.IDENT("Clock") then Absyn.QUALIFIED("OpenModelica",Absyn.QUALIFIED("Internal",Absyn.IDENT("ClockConstructor")));
1988 else id;
1989 end match;
1990
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 4843 times.
✓ Branch 3 taken 3962 times.
✓ Branch 4 taken 881 times.
17168 (cache,SCode.CLASS(classDef=SCode.OVERLOAD(pathLst=names),info=info),env_1) := lookupClass(cache,env,id);
1991 881 (cache,res) := lookupFunctionsListInEnv(cache,env_1,names,info,{});
1992 // print(stringDelimitList(List.map(res,TypesDump.unparseType),"\n###\n"));
1993 then (cache,res);
1994
1995 16287 case (cache,_,_,_) then (cache,{});
1996
1997 case (_,_,id,_)
1998 algorithm
1999 ✗ true := Flags.isSet(Flags.FAILTRACE);
2000 ✗ Debug.traceln("lookupFunctionsInEnv failed on: " + AbsynUtil.pathString(id));
2001 ✗ then
2002 fail();
2003
2004 end matchcontinue;
2005 end lookupFunctionsInEnv;
2006
2007 public function lookupFunctionsListInEnv
2008 input FCore.Cache inCache;
2009 input FCore.Graph inEnv;
2010 input list<Absyn.Path> inIds;
2011 input SourceInfo info;
2012 input list<DAE.Type> inAcc;
2013 output FCore.Cache outCache;
2014 output list<DAE.Type> outTypesTypeLst;
2015 algorithm
2016 (outCache,outTypesTypeLst) := matchcontinue (inCache, inEnv, inIds, inAcc)
2017 local
2018 Absyn.Path id;
2019 list<DAE.Type> res;
2020 String str;
2021 FCore.Cache cache;
2022 FCore.Graph env;
2023 list<Absyn.Path> ids;
2024 list<DAE.Type> acc;
2025
2026 980 case (cache, _, {}, acc) then (cache,listReverse(acc));
2027 case (cache, env, id::ids, acc)
2028 algorithm
2029
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1870 times.
1870 (cache,res as _::_) := lookupFunctionsInEnv(cache,env,id,info);
2030
2031 1870 (cache,acc) := lookupFunctionsListInEnv(cache,env,ids,info,listAppend(res,acc));
2032 then (cache,acc);
2033 case (_, env, id::_, _)
2034 algorithm
2035 ✗ str := AbsynUtil.pathString(id) + " not found in scope: " + FGraph.printGraphPathStr(env);
2036 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, info);
2037 ✗ then fail();
2038 end matchcontinue;
2039 end lookupFunctionsListInEnv;
2040
2041 protected function lookupFunctionsInEnv2
2042 "Returns a list of types that the function has."
2043 input FCore.Cache inCache;
2044 input FCore.Graph inEnv;
2045 input Absyn.Path inPath;
2046 input Boolean followedQual "cannot pop frames if we followed a qualified path at any point";
2047 input SourceInfo info;
2048 output FCore.Cache outCache;
2049 output list<DAE.Type> outTypesTypeLst;
2050 algorithm
2051 (outCache,outTypesTypeLst) := matchcontinue (inCache, inEnv, inPath, followedQual)
2052 local
2053 Absyn.Path id,path;
2054 FCore.Children httypes;
2055 FCore.Children ht;
2056 list<DAE.Type> res;
2057 FCore.Graph env,env_1,env2,env_2;
2058 String pack,str;
2059 SCode.Element c;
2060 SCode.Encapsulated encflag;
2061 SCode.Restriction restr;
2062 ClassInf.State ci_state;
2063 FCore.Ref r;
2064 FCore.Cache cache;
2065 DAE.Mod mod;
2066
2067 // Simple name, search frame
2068 case (cache, FCore.G(scope = r::_), Absyn.IDENT(name = str), _)
2069 algorithm
2070 127450 ht := FNode.children(FNode.fromRef(r));
2071 127450 httypes := getHtTypes(r);
2072
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 64981 times.
127450 (cache,res as _::_):= lookupFunctionsInFrame(cache, ht, httypes, inEnv, str, info);
2073 64981 then
2074 (cache,res);
2075
2076 // Simple name, if class with restriction function found in frame instantiate to get type.
2077 case (cache, FCore.G(scope = r::_), id as Absyn.IDENT(), _)
2078 algorithm
2079 // adrpo: do not search in the entire environment as we anyway recurse with the fs argument!
2080 // just search in {f} not f::fs as otherwise we might get us in an infinite loop
2081 // Bjozac: Readded the f::fs search frame, otherwise we might get caught in a inifinite loop!
2082 // Did not investigate this further then that it can crasch the kernel.
2083
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23598 times.
62573 (cache,(c as SCode.CLASS(name=str,restriction=restr)),env_1) := lookupClass(cache, inEnv, id);
2084
2/2
✓ Branch 1 taken 104 times.
✓ Branch 2 taken 23494 times.
23598 true := SCodeUtil.isFunctionRestriction(restr);
2085 // get function dae from instantiation
2086 // fprintln(Flags.INST_TRACE, "LOOKUP FUNCTIONS IN ENV ID ICD: " + FGraph.printGraphPathStr(env_1) + "." + str);
2087
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 19567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19567 times.
23494 (cache,env_2 as FCore.G(scope = r::_),_)
2088 := InstFunction.implicitFunctionTypeInstantiation(cache,env_1,InnerOuter.emptyInstHierarchy, c);
2089 19567 ht := FNode.children(FNode.fromRef(r));
2090 19567 httypes := getHtTypes(r);
2091
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14003 times.
19567 (cache,res as _::_):= lookupFunctionsInFrame(cache, ht, httypes, env_2, str, info);
2092 14003 then
2093 (cache,res);
2094
2095 // For qualified function names, e.g. Modelica.Math.sin
2096 case (cache, FCore.G(scope = r::_), Absyn.QUALIFIED(name = pack,path = path), _)
2097 algorithm
2098
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 94219 times.
94582 (cache,(c as SCode.CLASS(name=str,encapsulatedPrefix=encflag,restriction=restr)),env_1) := lookupClass(cache, inEnv, Absyn.IDENT(pack));
2099
2100 94219 r := FNode.child(FGraph.lastScopeRef(env_1), str);
2101
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 94219 times.
94219 if FNode.isRefInstance(r) // we have an instance of a component
2102 then
2103 ✗ (cache, env2) := Inst.getCachedInstance(cache, env_1, str, r);
2104 else
2105 94219 env2 := FGraph.openScope(env_1, encflag, str, FGraph.restrictionToScopeType(restr));
2106 94219 ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env2));
2107 // fprintln(Flags.INST_TRACE, "LOOKUP FUNCTIONS IN ENV QUAL ICD: " + FGraph.printGraphPathStr(env2) + "." + str);
2108 94219 mod := Mod.getClassModifier(env_1, str);
2109 94219 (cache,env2,_,_,_) :=
2110 Inst.partialInstClassIn(
2111 cache, env2, InnerOuter.emptyInstHierarchy,
2112 mod, DAE.NOPRE(),
2113 ci_state, c, SCode.PUBLIC(), {}, 0);
2114 end if;
2115 94159 (cache,res) := lookupFunctionsInEnv2(cache, env2, path, true, info);
2116 then
2117 (cache,res);
2118
2119 // Did not match. Search next frame.
2120 case (cache, FCore.G(scope = r::_), id, false)
2121 algorithm
2122
2/2
✓ Branch 2 taken 142 times.
✓ Branch 3 taken 47794 times.
47936 false := FNode.isEncapsulated(FNode.fromRef(r));
2123 47794 (env, _) := FGraph.stripLastScopeRef(inEnv);
2124 47794 (cache,res) := lookupFunctionsInEnv2(cache, env, id, false, info);
2125 then
2126 (cache,res);
2127
2128 case (cache, FCore.G(scope = r::_), id as Absyn.IDENT(), false)
2129 algorithm
2130
2/2
✓ Branch 2 taken 43022 times.
✓ Branch 3 taken 76 times.
43098 true := FNode.isEncapsulated(FNode.fromRef(r));
2131 76 env := FGraph.topScope(inEnv); // (cache,env) = Builtin.initialGraph(cache);
2132 76 (cache,res) := lookupFunctionsInEnv2(cache, env, id, true, info);
2133 then
2134 (cache,res);
2135
2136 end matchcontinue;
2137 end lookupFunctionsInEnv2;
2138
2139 protected function createGenericBuiltinFunctions
2140 "author: PA
2141 This function creates function types on-the-fly for special builtin
2142 operators/functions which can not be represented in the builtin
2143 environment."
2144 input FCore.Graph inEnv;
2145 input String inString;
2146 output list<DAE.Type> outTypesTypeLst;
2147 algorithm
2148 outTypesTypeLst := match inString
2149 local
2150 // function_name cardinality
2151 case "cardinality"
2152 then {DAE.T_FUNCTION(
2153 {DAE.FUNCARG("x",DAE.T_COMPLEX(ClassInf.CONNECTOR(Absyn.IDENT("$$"),false),{},NONE(), false),DAE.C_VAR(),DAE.NON_PARALLEL(),NONE())},
2154 DAE.T_INTEGER_DEFAULT,
2155 DAE.FUNCTION_ATTRIBUTES_DEFAULT,
2156 Absyn.IDENT("cardinality")),
2157 DAE.T_FUNCTION(
2158 {DAE.FUNCARG("x",DAE.T_COMPLEX(ClassInf.CONNECTOR(Absyn.IDENT("$$"),true),{},NONE(), false),DAE.C_VAR(),DAE.NON_PARALLEL(),NONE())},
2159 DAE.T_INTEGER_DEFAULT,
2160 DAE.FUNCTION_ATTRIBUTES_DEFAULT,
2161 Absyn.IDENT("cardinality"))};
2162
2163 end match;
2164 end createGenericBuiltinFunctions;
2165
2166 // - Internal functions
2167 // Type lookup
2168
2169 protected function lookupTypeInEnv
2170 "function: lookupTypeInEnv"
2171 input FCore.Cache inCache;
2172 input FCore.Graph inEnv;
2173 input String id;
2174 output FCore.Cache outCache;
2175 output DAE.Type outType;
2176 output FCore.Graph outEnv;
2177 algorithm
2178 (outCache,outType,outEnv):=
2179 matchcontinue (inCache,inEnv)
2180 local
2181 DAE.Type c;
2182 FCore.Graph env_1,env;
2183 FCore.Children httypes;
2184 FCore.Children ht;
2185 FCore.Cache cache;
2186 FCore.Ref r;
2187
2188 case (cache, env as FCore.G(scope = r::_))
2189 algorithm
2190 128752 ht := FNode.children(FNode.fromRef(r));
2191 128752 httypes := getHtTypes(r);
2192 128752 (cache,c,env_1) := lookupTypeInFrame(cache, ht, httypes, env, id);
2193 then
2194 (cache,c,env_1);
2195
2196 case (cache,env as FCore.G(scope = r::_))
2197 algorithm
2198 117007 (env, _) := FGraph.stripLastScopeRef(env);
2199 117007 (cache,c,env_1) := lookupTypeInEnv(cache,env,id);
2200 7105 env_1 := FGraph.pushScopeRef(env_1, r);
2201 7105 then
2202 (cache,c,env_1);
2203 end matchcontinue;
2204 end lookupTypeInEnv;
2205
2206 protected function getHtTypes
2207 input FCore.Ref inParentRef;
2208 output FCore.Children ht;
2209 algorithm
2210 ht := matchcontinue inParentRef
2211 local FCore.Ref r;
2212
2213 // there is a ty node
2214 case _
2215 algorithm
2216 280136 r := FNode.child(inParentRef, FNode.tyNodeName);
2217 128557 ht := FNode.children(FNode.fromRef(r));
2218 then
2219 ht;
2220
2221 // no ty node
2222 151579 else FCore.RefTree.new();
2223 end matchcontinue;
2224 end getHtTypes;
2225
2226 protected function lookupTypeInFrame
2227 "Searches a frame for a type."
2228 input FCore.Cache inCache;
2229 input FCore.Children inBinTree1;
2230 input FCore.Children inBinTree2;
2231 input FCore.Graph inEnv3;
2232 input SCode.Ident inIdent4;
2233 output FCore.Cache outCache;
2234 output DAE.Type outType;
2235 output FCore.Graph outEnv;
2236 algorithm
2237 (outCache,outType,outEnv):=
2238 match (inCache, inBinTree2, inEnv3, inIdent4)
2239 local
2240 DAE.Type t;
2241 FCore.Children httypes;
2242 FCore.Graph env;
2243 String id;
2244 FCore.Cache cache;
2245 FCore.Node item;
2246
2247 case (cache, httypes, env, id)
2248 algorithm
2249 128752 item := FNode.fromRef(FCore.RefTree.get(httypes, id));
2250 11745 (cache,t,env) := lookupTypeInFrame2(cache,item,env,id);
2251 then
2252 (cache,t,env);
2253 end match;
2254 end lookupTypeInFrame;
2255
2256 protected function lookupTypeInFrame2
2257 "Searches a frame for a type."
2258 input FCore.Cache inCache;
2259 input FCore.Node item;
2260 input FCore.Graph inEnv3;
2261 input SCode.Ident inIdent4;
2262 output FCore.Cache outCache;
2263 output DAE.Type outType;
2264 output FCore.Graph outEnv;
2265 algorithm
2266 (outCache,outType,outEnv):=
2267 match (inCache,item,inEnv3,inIdent4)
2268 local
2269 DAE.Type t,ty;
2270 FCore.Graph env,cenv,env_1,env_3;
2271 String id;
2272 SCode.Element cdef, comp;
2273 FCore.Cache cache;
2274 SourceInfo info;
2275
2276 11745 case (cache,FCore.N(data = FCore.FT(t :: _)),env,_) then (cache,t,env);
2277
2278 case (_,FCore.N(data = FCore.CO(e = comp)),_,id)
2279 algorithm
2280 ✗ info := SCodeUtil.elementInfo(comp);
2281 ✗ Error.addSourceMessage(Error.LOOKUP_TYPE_FOUND_COMP, {id}, info);
2282 ✗ then
2283 fail();
2284
2285 // Record constructor function
2286 case (cache,FCore.N(data = FCore.CL(e = cdef as SCode.CLASS(restriction=SCode.R_RECORD(_)))),env,_)
2287 algorithm
2288 ✗ (cache,env_3,ty) := buildRecordType(cache,env,cdef);
2289 ✗ then
2290 (cache,ty,env_3);
2291
2292 case (cache,FCore.N(data = FCore.CL(e = cdef as SCode.CLASS(restriction=SCode.R_METARECORD()))),env,_)
2293 algorithm
2294 ✗ (cache,env_3,ty) := buildMetaRecordType(cache,env,cdef);
2295 ✗ then
2296 (cache,ty,env_3);
2297
2298 // Found function
2299 case (cache,FCore.N(data = FCore.CL(e = cdef as SCode.CLASS(restriction=SCode.R_FUNCTION(_)))),env,id)
2300 algorithm
2301 // fprintln(Flags.INST_TRACE, "LOOKUP TYPE IN FRAME ICD: " + FGraph.printGraphPathStr(env) + " id:" + id);
2302
2303 // select the env if is the same as cenv as is updated!
2304 cenv := env; // selectUpdatedEnv(env, cenv);
2305
2306 ✗ (cache ,env_1,_) := InstFunction.implicitFunctionInstantiation(
2307 cache,cenv,InnerOuter.emptyInstHierarchy,
2308 DAE.NOMOD(), DAE.NOPRE(), cdef, {});
2309
2310 ✗ (cache,ty,env_3) := lookupTypeInEnv(cache, env_1, id);
2311 then
2312 (cache,ty,env_3);
2313
2314 end match;
2315 end lookupTypeInFrame2;
2316
2317 protected function lookupFunctionsInFrame
2318 "This actually only looks up the function name and find all
2319 corresponding types that have this function name."
2320 input FCore.Cache inCache;
2321 input FCore.Children inClasses;
2322 input FCore.Children inFuncTypes;
2323 input FCore.Graph inEnv;
2324 input SCode.Ident inFuncName;
2325 input SourceInfo inInfo;
2326 output FCore.Cache outCache;
2327 output list<DAE.Type> outFuncTypes;
2328 protected
2329 FCore.Ref r;
2330 FNode.Data data;
2331 DAE.Type ty;
2332 algorithm
2333 try // Try to look up the function among the function types first.
2334 151384 r := FCore.RefTree.get(inFuncTypes, inFuncName);
2335
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 57347 times.
57347 FCore.N(data = FCore.FT(outFuncTypes)) := FNode.fromRef(r);
2336 outCache := inCache;
2337 else // If not found, try to look the function up in the environment instead.
2338 94037 r := FCore.RefTree.get(inClasses, inFuncName);
2339 30850 FCore.N(data = data) := FNode.fromRef(r);
2340
2341 (outCache, outFuncTypes) := matchcontinue data
2342 local
2343 SCode.Element cl;
2344 list<DAE.Type> tps;
2345 FCore.Cache cache;
2346 FCore.Graph env;
2347
2348 // MetaModelica partial functions.
2349 case _
2350 algorithm
2351 30850 DAE.TYPES_VAR(ty = ty) := FNode.refInstVar(r);
2352 ty := match ty
2353 case DAE.T_FUNCTION()
2354 algorithm
2355 368 ty.path := Absyn.IDENT(inFuncName);
2356 then ty;
2357 end match;
2358 184 then
2359 (inCache, {ty});
2360
2361 // Found a component, print an error.
2362 case FCore.CO(__)
2363 algorithm
2364 3 Error.addSourceMessage(Error.LOOKUP_TYPE_FOUND_COMP, {inFuncName}, inInfo);
2365 3 then
2366 fail();
2367
2368 // A record, create a record constructor.
2369 case FCore.CL(e = cl as SCode.CLASS(restriction = SCode.R_RECORD(__)))
2370 algorithm
2371 2 (cache, _, ty) := buildRecordType(inCache, inEnv, cl);
2372 2 then
2373 (cache, {ty});
2374
2375 // A function, instantiate to get the type.
2376 case FCore.CL(e = cl) guard(SCodeUtil.isFunction(cl))
2377 algorithm
2378 30591 (cache, env) := InstFunction.implicitFunctionTypeInstantiation(
2379 inCache, inEnv, InnerOuter.emptyInstHierarchy, cl);
2380 26676 (cache, tps) := lookupFunctionsInEnv2(cache, env,
2381 Absyn.IDENT(inFuncName), true, inInfo);
2382 then
2383 (cache, tps);
2384
2385 // An external object.
2386 case FCore.CL(e = cl) guard(SCodeUtil.classIsExternalObject(cl))
2387 algorithm
2388 22 (cache, env) := Inst.instClass(inCache, inEnv,
2389 InnerOuter.emptyInstHierarchy, UnitAbsyn.noStore, DAE.NOMOD(),
2390 DAE.NOPRE(), cl, {}, false, InstTypes.TOP_CALL(),
2391 ConnectionGraph.EMPTY, Connect.emptySet);
2392 22 (cache, ty) := lookupTypeInEnv(cache, env, inFuncName);
2393 22 then
2394 (cache, {ty});
2395
2396 end matchcontinue;
2397 end try;
2398 end lookupFunctionsInFrame;
2399
2400 public function selectUpdatedEnv
2401 input FCore.Graph inNewEnv;
2402 input FCore.Graph inOldEnv;
2403 output FCore.Graph outEnv;
2404 algorithm
2405 // return the new env only if it is not top scope and points to the same env
2406 ✗ outEnv := if not FGraph.isTopScope(inNewEnv) and
2407 stringEq(FGraph.getGraphNameStr(inNewEnv), FGraph.getGraphNameStr(inOldEnv))
2408 then inNewEnv else inOldEnv;
2409 end selectUpdatedEnv;
2410
2411 protected function buildRecordType ""
2412 input FCore.Cache cache;
2413 input FCore.Graph env;
2414 input SCode.Element icdef;
2415 output FCore.Cache outCache;
2416 output FCore.Graph outEnv;
2417 output DAE.Type ftype;
2418 protected
2419 String name;
2420 SCode.Element cdef;
2421 algorithm
2422 7 (outCache,_,cdef) := buildRecordConstructorClass(cache,env,icdef);
2423 7 name := SCodeUtil.className(cdef);
2424 // fprintln(Flags.INST_TRACE", "LOOKUP BUILD RECORD TY ICD: " + FGraph.printGraphPathStr(env) + "." + name);
2425 7 (outCache,outEnv,_) := InstFunction.implicitFunctionTypeInstantiation(
2426 outCache,env,InnerOuter.emptyInstHierarchy, cdef);
2427 7 (outCache,ftype,_) := lookupTypeInEnv(outCache,outEnv,name);
2428 end buildRecordType;
2429
2430 protected function buildRecordConstructorClass
2431 "
2432 Creates the record constructor class, i.e. a function, from the record
2433 class given as argument."
2434 input FCore.Cache inCache;
2435 input FCore.Graph inEnv;
2436 input SCode.Element inClass;
2437 output FCore.Cache outCache;
2438 output FCore.Graph outEnv;
2439 output SCode.Element outClass;
2440 algorithm
2441 (outCache,outEnv,outClass) :=
2442 matchcontinue (inCache,inEnv,inClass)
2443 local
2444 list<SCode.Element> funcelts;
2445 SCode.Element reselt;
2446 SCode.Element cl;
2447 String id;
2448 SourceInfo info;
2449 FCore.Cache cache;
2450 FCore.Graph env;
2451
2452 case (cache,env,cl as SCode.CLASS(name=id,info=info))
2453 algorithm
2454 20 (cache,env,funcelts,_) := buildRecordConstructorClass2(cache,env,cl,DAE.NOMOD());
2455 20 reselt := buildRecordConstructorResultElt(funcelts,id,env,info);
2456 20 cl := SCode.CLASS(id,SCode.defaultPrefixes,SCode.NOT_ENCAPSULATED(),SCode.NOT_PARTIAL(),SCode.R_FUNCTION(SCode.FR_RECORD_CONSTRUCTOR()),SCode.PARTS((reselt :: funcelts),{},{},{},{},{},{},NONE()),SCode.noComment,info);
2457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 then
2458 (cache,env,cl);
2459 else
2460 algorithm
2461 ✗ true := Flags.isSet(Flags.FAILTRACE);
2462 ✗ Debug.trace("buildRecordConstructorClass failed\n");
2463 ✗ then fail();
2464 end matchcontinue;
2465 end buildRecordConstructorClass;
2466
2467 protected function buildRecordConstructorClass2
2468 input FCore.Cache inCache;
2469 input FCore.Graph inEnv;
2470 input SCode.Element cl;
2471 input DAE.Mod mods;
2472 output FCore.Cache outCache;
2473 output FCore.Graph outEnv;
2474 output list<SCode.Element> funcelts;
2475 output list<SCode.Element> elts;
2476 algorithm
2477 (outCache,outEnv,funcelts,elts) := matchcontinue(inCache, inEnv, cl)
2478 local
2479 list<SCode.Element> cdefelts,classExtendsElts,extendsElts,compElts;
2480 list<tuple<SCode.Element,DAE.Mod>> eltsMods;
2481 String name;
2482 Absyn.Path fpath;
2483 SourceInfo info;
2484 FCore.Cache cache;
2485 FCore.Graph env,env1;
2486
2487 // a class with parts
2488 case (cache, env, SCode.CLASS(name = name,info = info))
2489 algorithm
2490 20 (cache,env,_,elts,_,_,_,_,_) := InstExtends.instDerivedClasses(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOMOD(),DAE.NOPRE(),cl,true,info);
2491 20 env := FGraph.openScope(env, SCode.NOT_ENCAPSULATED(), name, SOME(FCore.CLASS_SCOPE()));
2492 20 fpath := FGraph.getGraphName(env);
2493 20 (cdefelts,classExtendsElts,extendsElts,compElts) := InstUtil.splitElts(elts);
2494 20 (cache,env,_,_,eltsMods,_,_,_,_) := InstExtends.instExtendsAndClassExtendsList(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOMOD(), DAE.NOPRE(), extendsElts, classExtendsElts, elts, ClassInf.RECORD(fpath), name, true, false);
2495 20 eltsMods := listAppend(eltsMods,InstUtil.addNomod(compElts)) annotation(__OpenModelica_DisableListAppendWarning=true);
2496 // print("Record Elements: " +
2497 // stringDelimitList(
2498 // List.map(
2499 // List.map(
2500 // eltsMods,
2501 // Util.tuple21),
2502 // SCodeDump.printElementStr), "\n"));
2503 20 (cache, env1, _) := InstUtil.addClassdefsToEnv(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), cdefelts, false, NONE());
2504 20 (cache, env1, _) := InstUtil.addComponentsToEnv(cache, env1, InnerOuter.emptyInstHierarchy, mods, DAE.NOPRE(), ClassInf.RECORD(fpath), eltsMods, true);
2505 20 (cache, env1, funcelts) := buildRecordConstructorElts(cache,env1,eltsMods,mods);
2506
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 then (cache,env1,funcelts,elts);
2507
2508 // fail
2509 else algorithm
2510 ✗ Debug.traceln("buildRecordConstructorClass2 failed, cl:"+SCodeDump.unparseElementStr(cl,SCodeDump.defaultOptions)+"\n");
2511 ✗ then fail();
2512 /* TODO: short class defs */
2513 end matchcontinue;
2514 end buildRecordConstructorClass2;
2515
2516 protected function selectModifier
2517 "@author: adrpo
2518 if the first modifier is empty (NOMOD) use the second one!"
2519 input DAE.Mod inModID;
2520 input DAE.Mod inModNoID;
2521 output DAE.Mod outMod;
2522 algorithm
2523 outMod := match inModID
2524 case DAE.NOMOD() then inModNoID;
2525 else inModID;
2526 end match;
2527 end selectModifier;
2528
2529 protected function buildRecordConstructorElts
2530 "Helper function to build_record_constructor_class. Creates the elements
2531 of the function class.
2532
2533 TODO: This function should be replaced by a proper instantiation using instClassIn instead, followed by a
2534 traversal of the DAE.Var changing direction to input.
2535 Reason for not doing that now: records can contain arrays with unknown dimensions."
2536 input FCore.Cache inCache;
2537 input FCore.Graph inEnv;
2538 input list<tuple<SCode.Element,DAE.Mod>> inSCodeElementLst;
2539 input DAE.Mod mods;
2540 output FCore.Cache outCache;
2541 output FCore.Graph outEnv;
2542 output list<SCode.Element> outSCodeElementLst;
2543 algorithm
2544 (outCache, outEnv, outSCodeElementLst) := matchcontinue (inCache, inEnv, inSCodeElementLst)
2545 local
2546 FCore.Cache cache;
2547 FCore.Graph env;
2548 list<tuple<SCode.Element,DAE.Mod>> rest;
2549 list<SCode.Element> res;
2550 SCode.Element comp;
2551 String id;
2552 SCode.ConnectorType ct;
2553 SCode.Replaceable repl;
2554 SCode.Visibility vis;
2555 SCode.Final f;
2556 SCode.Redeclare redecl;
2557 Absyn.InnerOuter io;
2558 list<Absyn.Subscript> d;
2559 SCode.Parallelism prl;
2560 SCode.Variability var;
2561 Absyn.IsField isf;
2562 Absyn.Direction dir;
2563 Absyn.TypeSpec tp;
2564 SCode.Comment comment;
2565 Option<Absyn.Exp> cond;
2566 SCode.Mod mod,umod;
2567 DAE.Mod mod_1, compMod, fullMod, selectedMod, cmod;
2568 SourceInfo info;
2569
2570 case (cache, env, {}) then (cache,env,{});
2571
2572 // final becomes protected, Modelica Spec 3.2, Section 12.6, Record Constructor Functions, page 140
2573 case (cache, env, ((( SCode.COMPONENT(
2574 id,
2575 SCode.PREFIXES(_, redecl, f as SCode.FINAL(), io, repl),
2576 SCode.ATTR(d,ct,prl,var,_,isf),tp,mod,comment,cond,info)),cmod) :: rest))
2577 algorithm
2578 ✗ (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info);
2579 ✗ mod_1 := Mod.merge(mods,mod_1);
2580 // adrpo: this was wrong, you won't find any id modification there!!!
2581 // bjozac: This was right, you will find id modification unless modifers does not belong to component!
2582 // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty!
2583 ✗ compMod := Mod.lookupCompModification(mod_1,id);
2584 ✗ fullMod := mod_1;
2585 ✗ selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one.
2586 ✗ (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info);
2587 ✗ selectedMod := Mod.merge(cmod,selectedMod);
2588 ✗ umod := Mod.unelabMod(selectedMod);
2589 ✗ (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods);
2590 // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed.
2591 // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability!
2592 // mahge: 2013-01-15 : direction should be set to bidir.
2593 // var = SCode.VAR();
2594 dir := Absyn.BIDIR();
2595 vis := SCode.PROTECTED();
2596 ✗ then
2597 (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis,redecl, f,io,repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res);
2598
2599 // constants become protected, Modelica Spec 3.2, Section 12.6, Record Constructor Functions, page 140
2600 // mahge: 2013-01-15 : only if they have bindings. otherwise they are still modifiable.
2601 case (cache, env, ((( SCode.COMPONENT(
2602 id,
2603 SCode.PREFIXES(vis, redecl, _, io, repl),
2604 SCode.ATTR(d,ct,prl,SCode.CONST(),_,isf),tp,mod as SCode.NOMOD(),comment,cond,info)), cmod) :: rest))
2605 algorithm
2606 ✗ (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info);
2607 ✗ mod_1 := Mod.merge(mods,mod_1);
2608 // adrpo: this was wrong, you won't find any id modification there!!!
2609 // bjozac: This was right, you will find id modification unless modifers does not belong to component!
2610 // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty!
2611 ✗ compMod := Mod.lookupCompModification(mod_1,id);
2612 ✗ fullMod := mod_1;
2613 ✗ selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one.
2614 ✗ (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info);
2615 ✗ selectedMod := Mod.merge(cmod,selectedMod);
2616 ✗ umod := Mod.unelabMod(selectedMod);
2617 ✗ (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods);
2618 // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed.
2619 // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability!
2620 var := SCode.VAR();
2621 dir := Absyn.INPUT();
2622 vis := SCode.PUBLIC();
2623 f := SCode.NOT_FINAL();
2624 ✗ then
2625 (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis,redecl,f,io,repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res);
2626
2627
2628 case (cache, env, ((( SCode.COMPONENT(
2629 id,
2630 SCode.PREFIXES(_, redecl, f, io, repl),
2631 SCode.ATTR(d,ct,prl,var as SCode.CONST(),_,isf),tp,mod,comment,cond,info)),cmod) :: rest))
2632 algorithm
2633 ✗ (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info);
2634 ✗ mod_1 := Mod.merge(mods,mod_1);
2635 // adrpo: this was wrong, you won't find any id modification there!!!
2636 // bjozac: This was right, you will find id modification unless modifers does not belong to component!
2637 // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty!
2638 ✗ compMod := Mod.lookupCompModification(mod_1,id);
2639 ✗ fullMod := mod_1;
2640 ✗ selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one.
2641 ✗ (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info);
2642 ✗ selectedMod := Mod.merge(cmod,selectedMod);
2643 ✗ umod := Mod.unelabMod(selectedMod);
2644 ✗ (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods);
2645 // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed.
2646 // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability!
2647 // mahge: 2013-01-15 : direction should be set to bidir.
2648 // var = SCode.VAR();
2649 dir := Absyn.BIDIR();
2650 vis := SCode.PROTECTED();
2651 ✗ then
2652 (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis,redecl,f,io,repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res);
2653
2654 // all others, add input see Modelica Spec 3.2, Section 12.6, Record Constructor Functions, page 140
2655 case (cache, env, ((( SCode.COMPONENT(
2656 id,
2657 SCode.PREFIXES(_, redecl, _, io, repl),
2658 SCode.ATTR(d,ct,prl,_,_,isf),tp,mod,comment,cond,info)),cmod) :: rest))
2659 algorithm
2660 147 (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info);
2661 147 mod_1 := Mod.merge(mods,mod_1);
2662 // adrpo: this was wrong, you won't find any id modification there!!!
2663 // bjozac: This was right, you will find id modification unless modifers does not belong to component!
2664 // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty!
2665 147 compMod := Mod.lookupCompModification(mod_1,id);
2666 147 fullMod := mod_1;
2667 147 selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one.
2668 147 (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info);
2669 147 selectedMod := Mod.merge(cmod,selectedMod);
2670 147 umod := Mod.unelabMod(selectedMod);
2671 147 (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods);
2672 // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed.
2673 // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability!
2674 var := SCode.VAR();
2675 vis := SCode.PUBLIC();
2676 f := SCode.NOT_FINAL();
2677 dir := Absyn.INPUT();
2678 147 then
2679 (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis, redecl, f, io, repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res);
2680
2681 case (_, _, (comp,cmod)::_)
2682 algorithm
2683 ✗ true := Flags.isSet(Flags.FAILTRACE);
2684 ✗ Debug.traceln("- Lookup.buildRecordConstructorElts failed " + SCodeDump.unparseElementStr(comp,SCodeDump.defaultOptions) + " with mod: " + Mod.printModStr(cmod) + " and: " + Mod.printModStr(mods));
2685 ✗ then fail();
2686 end matchcontinue;
2687 end buildRecordConstructorElts;
2688
2689 protected function buildRecordConstructorResultElt
2690 "This function builds the result element of a
2691 record constructor function, i.e. the returned variable"
2692 input list<SCode.Element> elts;
2693 input SCode.Ident id;
2694 input FCore.Graph env;
2695 input SourceInfo info;
2696 output SCode.Element outElement;
2697 algorithm
2698 //print(" creating element of type: " + id + "\n");
2699 //print(" with generated mods:" + SCodeUtil.printSubs1Str(submodlst) + "\n");
2700 //print(" creating element of type: " + id + "\n");
2701 //print(" with generated mods:" + SCodeUtil.printSubs1Str(submodlst) + "\n");
2702 ✗ outElement := SCode.COMPONENT("result",SCode.defaultPrefixes,
2703 SCode.ATTR({},SCode.POTENTIAL(),SCode.NON_PARALLEL(),SCode.VAR(),Absyn.OUTPUT(),Absyn.NONFIELD()),
2704 Absyn.TPATH(Absyn.IDENT(id),NONE()),
2705 SCode.NOMOD(),SCode.noComment,NONE(),info);
2706 annotation(__OpenModelica_EarlyInline = true);
2707 end buildRecordConstructorResultElt;
2708
2709 protected function lookupClassInEnv
2710 "Helper function to lookupClass2. Searches the environment for the class.
2711 It first checks the current scope, and then base classes. The specification
2712 says that we first search elements in the current scope (+ the ones inherited
2713 from base classes)"
2714 input FCore.Cache inCache;
2715 input FCore.Graph inEnv;
2716 input String id;
2717 input FCore.Scope inPrevFrames;
2718 input Mutable<Boolean> inState;
2719 input Option<SourceInfo> inInfo;
2720 output FCore.Cache outCache;
2721 output SCode.Element outClass;
2722 output FCore.Graph outEnv;
2723 output FCore.Scope outPrevFrames;
2724 algorithm
2725 (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inEnv, inPrevFrames, inInfo)
2726 local
2727 SCode.Element c;
2728 FCore.Graph env_1,env,i_env;
2729 FCore.Scope prevFrames;
2730 FCore.Node frame;
2731 FCore.Ref r;
2732 String sid,scope;
2733 FCore.Cache cache;
2734 SourceInfo info;
2735
2736 case (cache, env as FCore.G(scope = r::_), prevFrames, _)
2737 algorithm
2738 9871673 frame := FNode.fromRef(r);
2739 9871673 (cache,c,env_1,prevFrames) := lookupClassInFrame(cache, frame, env, id, prevFrames, inState, inInfo);
2740 3884447 Mutable.update(inState,true);
2741 3884447 then
2742 (cache,c,env_1,prevFrames);
2743
2744 case (cache, env as FCore.G(scope = r :: _), prevFrames, _)
2745 algorithm
2746
2/2
✓ Branch 1 taken 474653 times.
✓ Branch 2 taken 5512573 times.
5987226 false := FNode.isRefTop(r);
2747 5512573 frame := FNode.fromRef(r);
2748 5512573 sid := FNode.refName(r);
2749
2/2
✓ Branch 1 taken 5244699 times.
✓ Branch 2 taken 267874 times.
5512573 true := FNode.isEncapsulated(frame);
2750
4/4
✓ Branch 0 taken 9922 times.
✓ Branch 1 taken 257952 times.
✓ Branch 3 taken 7020 times.
✓ Branch 4 taken 2902 times.
267874 true := stringEq(id, sid) "Special case if looking up the class that -is- encapsulated. That must be allowed." ;
2751 7020 (env, _) := FGraph.stripLastScopeRef(env);
2752 7020 (cache,c,env,prevFrames) := lookupClassInEnv(cache, env, id, r::prevFrames, inState, inInfo);
2753 7020 Mutable.update(inState,true);
2754 7020 then
2755 (cache,c,env,prevFrames);
2756
2757 // lookup stops at encapsulated classes except for builtin
2758 // scope, if not found in builtin scope, error
2759 case (cache, env as FCore.G(scope = r :: _), _, SOME(info))
2760 algorithm
2761
2/2
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 2613331 times.
2613376 false := FNode.isRefTop(r);
2762 2613331 frame := FNode.fromRef(r);
2763
2/2
✓ Branch 1 taken 2427354 times.
✓ Branch 2 taken 185977 times.
2613331 true := FNode.isEncapsulated(frame);
2764 185977 i_env := FGraph.topScope(env);
2765
2/2
✓ Branch 0 taken 185977 times.
✓ Branch 1 taken 22 times.
185999 failure(lookupClassInEnv(cache, i_env, id, {}, inState, NONE()));
2766 22 scope := FGraph.printGraphPathStr(env);
2767 22 Error.addSourceMessage(Error.LOOKUP_ERROR, {id,scope}, info);
2768 22 then
2769 fail();
2770
2771 // lookup stops at encapsulated classes, except for builtin scope
2772 case (cache, env as FCore.G(scope = r::_), prevFrames, _)
2773 algorithm
2774 5980206 frame := FNode.fromRef(r);
2775
2/2
✓ Branch 1 taken 5719352 times.
✓ Branch 2 taken 260854 times.
5980206 true := FNode.isEncapsulated(frame);
2776 260854 i_env := FGraph.topScope(env);
2777 260854 (cache,c,env_1,prevFrames) := lookupClassInEnv(cache, i_env, id, {}, inState, inInfo);
2778 223477 Mutable.update(inState,true);
2779 223477 then
2780 (cache,c,env_1,prevFrames);
2781
2782 // if not found and not encapsulated, and no ident has been previously found, look in next enclosing scope
2783 case (cache, env as FCore.G(scope = r::_), prevFrames, _)
2784 algorithm
2785
2/2
✓ Branch 1 taken 474653 times.
✓ Branch 2 taken 5282076 times.
5756729 false := FNode.isRefTop(r);
2786 5282076 frame := FNode.fromRef(r);
2787
2/2
✓ Branch 1 taken 37377 times.
✓ Branch 2 taken 5244699 times.
5282076 false := FNode.isEncapsulated(frame);
2788
2/2
✓ Branch 1 taken 686407 times.
✓ Branch 2 taken 4558292 times.
5244699 false := Mutable.access(inState);
2789 4558292 (env, _) := FGraph.stripLastScopeRef(env);
2790 4558292 (cache,c,env_1,prevFrames) := lookupClassInEnv(cache, env, id, r::prevFrames, inState, inInfo);
2791 3512445 Mutable.update(inState, true);
2792 3512445 then
2793 (cache,c,env_1,prevFrames);
2794
2795 end matchcontinue;
2796 end lookupClassInEnv;
2797
2798 protected function lookupClassInFrame "Search for a class within one frame."
2799 input FCore.Cache inCache;
2800 input FCore.Node inFrame;
2801 input FCore.Graph inEnv;
2802 input SCode.Ident inIdent;
2803 input FCore.Scope inPrevFrames;
2804 input Mutable<Boolean> inState;
2805 input Option<SourceInfo> inInfo;
2806 output FCore.Cache outCache;
2807 output SCode.Element outClass;
2808 output FCore.Graph outEnv;
2809 output FCore.Scope outPrevFrames;
2810 algorithm
2811 (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inFrame, inEnv, inIdent, inPrevFrames)
2812 local
2813 SCode.Element c;
2814 FCore.Graph totenv,env_1;
2815 FCore.Scope prevFrames;
2816 FCore.Ref r;
2817 FCore.Children ht;
2818 String name;
2819 list<Absyn.Import> qimports, uqimports;
2820 FCore.Cache cache;
2821 Boolean unique;
2822
2823 // Check this scope for class
2824 case (cache, FCore.N(children = ht), totenv, name, prevFrames)
2825 algorithm
2826 9871673 r := FCore.RefTree.get(ht, name);
2827
2/2
✓ Branch 1 taken 126954 times.
✓ Branch 2 taken 3767623 times.
3894577 FCore.N(data = FCore.CL(e = c)) := FNode.fromRef(r);
2828 3767623 then
2829 (cache,c,totenv,prevFrames);
2830
2831 // Search in imports
2832 case (cache, _, totenv, name, _)
2833 algorithm
2834 6104050 (qimports, uqimports) := FNode.imports(inFrame);
2835 try
2836 // Search among the qualified imports, e.g. import A.B; or import D=A.B;
2837
2/2
✓ Branch 0 taken 680 times.
✓ Branch 1 taken 325531 times.
326211 false := listEmpty(qimports);
2838 325531 (cache,c,env_1,prevFrames) := lookupQualifiedImportedClassInFrame(cache,qimports,totenv,name,inState,inInfo);
2839 else
2840 // Search among the unqualified imports, e.g. import A.B.*;
2841
2/2
✓ Branch 0 taken 208760 times.
✓ Branch 1 taken 1627 times.
210387 false := listEmpty(uqimports);
2842 1627 (cache,c,env_1,prevFrames,unique) := lookupUnqualifiedImportedClassInFrame(cache,uqimports,totenv,name,inInfo);
2843 1000 Mutable.update(inState,true);
2844 1000 reportSeveralNamesError(unique,name);
2845 end try;
2846 116824 then
2847 (cache,c,env_1,prevFrames);
2848
2849 end matchcontinue;
2850 end lookupClassInFrame;
2851
2852 protected function reportSeveralNamesError
2853 "given a boolean, report error message of importing several names
2854 if boolean flag is false and fail. If flag is true succeed and do nothing."
2855 input Boolean unique;
2856 input String name;
2857 algorithm
2858 () := match unique
2859
2860 case true then ();
2861
2862 case false
2863 algorithm
2864 ✗ Error.addMessage(Error.IMPORT_SEVERAL_NAMES, {name});
2865 then ();
2866
2867 end match;
2868 end reportSeveralNamesError;
2869
2870 protected function lookupVar2
2871 "Helper function to lookupVarF and lookupIdent."
2872 input FCore.Children inBinTree;
2873 input SCode.Ident inIdent;
2874 input FCore.Graph inGraph;
2875 output DAE.Var outVar;
2876 output SCode.Element outElement;
2877 output DAE.Mod outMod;
2878 output FCore.Status instStatus;
2879 output FCore.Graph outEnv;
2880 protected
2881 FCore.Ref r;
2882 FCore.Scope s;
2883 FCore.Node n;
2884 String name;
2885 algorithm
2886 13640687 r := FCore.RefTree.get(inBinTree, inIdent);
2887 4524783 outVar := FNode.refInstVar(r);
2888 3284366 s := FNode.refRefTargetScope(r);
2889 3284366 n := FNode.fromRef(r);
2890
2891
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 3284366 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3284366 if not FNode.isComponent(n) and Flags.isSet(Flags.LOOKUP) then
2892 // MetaModelica function references generate too much failtrace...
2893 ✗ false := Config.acceptMetaModelicaGrammar();
2894 ✗ FCore.N(data = FCore.CL(e = SCode.CLASS(name = name))) := n;
2895 ✗ name := inIdent + " = " + FGraph.printGraphPathStr(inGraph) + "." + name;
2896 ✗ Debug.traceln("- Lookup.lookupVar2 failed because we found a class instead of a variable: " + name);
2897 ✗ fail();
2898 end if;
2899
2900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3284366 times.
3284366 FCore.N(data = FCore.CO(outElement, outMod, _, instStatus)) := n;
2901 3284366 outEnv := FGraph.setScope(inGraph, s);
2902 end lookupVar2;
2903
2904 protected function checkSubscripts "This function checks a list of subscripts agains type, and removes
2905 dimensions from the type according to the subscripting."
2906 input DAE.Type inType;
2907 input list<DAE.Subscript> inExpSubscriptLst;
2908 output DAE.Type outType;
2909 algorithm
2910 outType := matchcontinue (inType,inExpSubscriptLst)
2911 local
2912 DAE.Type t,t_1;
2913 DAE.Dimension dim;
2914 list<DAE.Subscript> ys,s;
2915 Integer sz,ind,dim_int;
2916 list<DAE.Exp> se;
2917 DAE.Exp e;
2918
2919 // empty case
2920 case (t,{}) then t;
2921
2922 case (DAE.T_ARRAY(dims = {dim},ty = t),(DAE.WHOLEDIM() :: ys))
2923 algorithm
2924 1533 t_1 := checkSubscripts(t, ys);
2925 1533 then
2926 DAE.T_ARRAY(t_1,{dim});
2927
2928 case (DAE.T_ARRAY(dims = {_}, ty = t),
2929 DAE.SLICE(exp = e as DAE.RANGE()) :: ys)
2930 algorithm
2931 44 t_1 := checkSubscripts(t, ys);
2932 44 dim_int := Expression.rangeSize(e);
2933 ✗ then
2934 DAE.T_ARRAY(t_1, {DAE.DIM_INTEGER(dim_int)});
2935
2936 case (DAE.T_ARRAY(dims = {dim}, ty = t),
2937 (DAE.SLICE(exp = DAE.ARRAY(array = se)) :: ys))
2938 algorithm
2939 995 Expression.dimensionSize(dim);
2940 991 t_1 := checkSubscripts(t, ys);
2941 991 dim_int := listLength(se) "FIXME: Check range IMPLEMENTED 2007-05-18 BZ" ;
2942 1982 then
2943 DAE.T_ARRAY(t_1,{DAE.DIM_INTEGER(dim_int)});
2944
2945 case (DAE.T_ARRAY(dims = {_}, ty = t),
2946 (DAE.SLICE(exp = e) :: ys))
2947 algorithm
2948
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 49 times.
49 DAE.T_ARRAY(dims={dim}) := Expression.typeof(e);
2949 49 t_1 := checkSubscripts(t, ys);
2950 49 then
2951 DAE.T_ARRAY(t_1, {dim});
2952
2953 case (DAE.T_ARRAY(dims = {dim}, ty = t),
2954 (DAE.INDEX(exp = DAE.ICONST(integer = ind)) :: ys))
2955 algorithm
2956 342904 sz := Expression.dimensionSize(dim);
2957
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 342434 times.
342435 true := (ind > 0);
2958
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 342434 times.
342434 true := (ind <= sz);
2959 342434 t_1 := checkSubscripts(t, ys);
2960 then
2961 t_1;
2962
2963 // HJ: Subscripts needn't be constant. No range-checking can be done
2964 case (DAE.T_ARRAY(dims = {dim}, ty = t),
2965 (DAE.INDEX() :: ys))
2966 algorithm
2967
2/2
✓ Branch 1 taken 878 times.
✓ Branch 2 taken 7474 times.
8352 true := Expression.dimensionKnown(dim);
2968 7474 t_1 := checkSubscripts(t, ys);
2969 then
2970 t_1;
2971
2972 case (DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()}, ty = t),
2973 (DAE.INDEX() :: ys))
2974 algorithm
2975 642 t_1 := checkSubscripts(t, ys);
2976 then
2977 t_1;
2978
2979 case (DAE.T_ARRAY(dims = {DAE.DIM_EXP()}, ty = t),
2980 (DAE.INDEX() :: ys))
2981 algorithm
2982 236 t_1 := checkSubscripts(t, ys);
2983 then
2984 t_1;
2985
2986 case (DAE.T_ARRAY(ty = t),
2987 (DAE.WHOLEDIM() :: ys))
2988 algorithm
2989 ✗ t_1 := checkSubscripts(t, ys);
2990 then
2991 t_1;
2992
2993 case (DAE.T_SUBTYPE_BASIC(complexType = t),ys)
2994 25 then checkSubscripts(t,ys);
2995
2996 case(t as DAE.T_UNKNOWN(), _) then t;
2997
2998 ✗ case (DAE.T_METAARRAY(), {DAE.INDEX()}) then inType.ty;
2999 case (DAE.T_METAARRAY(), {_}) then inType;
3000
3001 case (t,s)
3002 algorithm
3003 ✗ true := Flags.isSet(Flags.FAILTRACE);
3004 ✗ Debug.trace("- Lookup.checkSubscripts failed (tp: ");
3005 ✗ Debug.trace(TypesDump.printTypeStr(t));
3006 ✗ Debug.trace(" subs:");
3007 ✗ Debug.trace(stringDelimitList(List.map(s,ExpressionBasics.printSubscriptStr),","));
3008 ✗ Debug.trace(")\n");
3009 ✗ then
3010 fail();
3011 end matchcontinue;
3012 end checkSubscripts;
3013
3014 protected function lookupVarF
3015 "This function looks in a frame to find a declared variable. If
3016 the name being looked up is qualified, the first part of the name
3017 is looked up, and lookupVar2 is used to for further lookup in
3018 the result of that lookup.
3019 2007-05-29 If we can construct a expression, we do after expanding the
3020 subscript with dimensions to fill the Cref."
3021 input FCore.Cache inCache;
3022 input FCore.Children inBinTree;
3023 input DAE.ComponentRef inComponentRef;
3024 input FCore.Graph inEnv;
3025 output FCore.Cache outCache;
3026 output DAE.Attributes outAttributes;
3027 output DAE.Type outType;
3028 output DAE.Binding outBinding;
3029 output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
3030 output InstTypes.SplicedExpData splicedExpData;
3031 output FCore.Graph outComponentEnv;
3032 output String name;
3033 algorithm
3034 (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) :=
3035 match (inCache, inBinTree, inComponentRef)
3036 local
3037 String id;
3038 DAE.ConnectorType ct;
3039 SCode.Parallelism prl;
3040 SCode.Variability vt,vt2;
3041 Absyn.Direction di;
3042 DAE.Type ty,idTp,ty2_2, tyParent, tyChild, ty1;
3043 DAE.Binding binding, parentBinding;
3044 FCore.Children ht;
3045 list<DAE.Subscript> ss;
3046 FCore.Graph componentEnv;
3047 DAE.ComponentRef ids;
3048 FCore.Cache cache;
3049 Absyn.InnerOuter io;
3050 Option<DAE.Exp> texp;
3051 DAE.ComponentRef xCref,tCref;
3052 list<DAE.ComponentRef> ltCref;
3053 DAE.Exp splicedExp;
3054 DAE.Type eType;
3055 Option<DAE.Const> cnstForRange;
3056 SCode.Visibility vis;
3057 DAE.Attributes attr;
3058 Option<DAE.Exp> oSplicedExp;
3059
3060 // Simple identifier
3061 case (_, _, DAE.CREF_IDENT(ident = id,subscriptLst = ss))
3062 algorithm
3063 2469542 (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) := lookupVarFIdent(inCache,inBinTree,id,ss,inEnv);
3064 then (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name);
3065
3066 // Qualified variables looked up through component environment with or without spliced exp
3067 case (cache, ht, DAE.CREF_QUAL(ident = id,subscriptLst = ss,componentRef = ids))
3068 algorithm
3069 1359783 (DAE.TYPES_VAR(_,DAE.ATTR(variability = vt2),tyParent,parentBinding,_),_,_,_,componentEnv) := lookupVar2(ht, id, inEnv);
3070
3071 // leave just the last scope from component env as it SHOULD BE ONLY THERE, i.e. don't go on searching the parents!
3072 // componentEnv = FGraph.setScope(componentEnv, List.create(FGraph.lastScopeRef(componentEnv)));
3073
3074 (attr,ty,binding,cnstForRange,componentEnv,name) := match tyParent
3075 case DAE.T_METAARRAY()
3076 algorithm
3077 ✗ true := listLength(TypesDump.getDimensions(tyParent)) == listLength(ss);
3078 ✗ (cache,attr,ty,binding,cnstForRange,name) := lookupVarFMetaModelica(cache, componentEnv, ids, Types.metaArrayElementType(tyParent));
3079 ✗ splicedExpData := InstTypes.SPLICEDEXPDATA(NONE(),ty);
3080 ✗ then (attr,ty,binding,cnstForRange,componentEnv,name);
3081 case _ guard Types.isBoxedType(tyParent) and not Types.isUnknownType(tyParent)
3082 algorithm
3083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1520 times.
1520 {} := ss;
3084 1520 (cache,attr,ty,binding,cnstForRange,name) := lookupVarFMetaModelica(cache, componentEnv, ids, tyParent);
3085 1520 splicedExpData := InstTypes.SPLICEDEXPDATA(NONE(),ty);
3086 1520 then (attr,ty,binding,cnstForRange,componentEnv,name);
3087 else
3088 algorithm
3089 492067 (cache,DAE.ATTR(ct,prl,vt,di,io,vis),tyChild,binding,cnstForRange,InstTypes.SPLICEDEXPDATA(texp,idTp),_,componentEnv,name) := lookupVar(cache, componentEnv, ids);
3090
3091 273410 ltCref := elabComponentRecursive((texp));
3092 273410 ty := tyChild; // In case it's an unspliced expression
3093 oSplicedExp := match ltCref
3094 case tCref::_ // with a spliced exp
3095 algorithm
3096 273410 ty1 := checkSubscripts(tyParent, ss);
3097 273410 ty := sliceDimensionType(ty1,tyChild);
3098 273410 ty2_2 := Types.simplifyType(tyParent);
3099 273410 ss := addArrayDimensions(ty2_2,ss);
3100 273410 xCref := ComponentReferenceBasics.makeCrefQual(id,ty2_2,ss,tCref);
3101 273410 eType := Types.simplifyType(ty);
3102 273410 splicedExp := Expression.makeCrefExp(xCref,eType);
3103 then SOME(splicedExp);
3104 case {} // without spliced Expression
3105 then NONE();
3106 end match;
3107 273410 vt := SCodeUtil.variabilityOr(vt,vt2);
3108 273410 binding := lookupBinding(inComponentRef, tyParent, ty, parentBinding, binding);
3109 273410 splicedExpData := InstTypes.SPLICEDEXPDATA(oSplicedExp,idTp);
3110 273410 then
3111 (DAE.ATTR(ct,prl,vt,di,io,vis),ty,binding,cnstForRange,componentEnv,name);
3112 end match;
3113 274930 then (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name);
3114
3115 end match;
3116 end lookupVarF;
3117
3118 protected function lookupVarFIdent
3119 "This function looks in a frame to find a declared variable. If
3120 the name being looked up is qualified, the first part of the name
3121 is looked up, and lookupVar2 is used to for further lookup in
3122 the result of that lookup.
3123 2007-05-29 If we can construct a expression, we do after expanding the
3124 subscript with dimensions to fill the Cref."
3125 input output FCore.Cache cache;
3126 input FCore.Children ht;
3127 input String ident;
3128 input list<DAE.Subscript> ss;
3129 input FCore.Graph inEnv;
3130 output DAE.Attributes attr;
3131 output DAE.Type ty_1;
3132 output DAE.Binding bind;
3133 output Option<DAE.Const> cnstForRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator";
3134 output InstTypes.SplicedExpData splicedExpData;
3135 output FCore.Graph componentEnv;
3136 output String name;
3137 protected
3138 DAE.Type tty, ty;
3139 list<DAE.Subscript> ss_1;
3140 algorithm
3141 10749923 (DAE.TYPES_VAR(name,attr,ty,bind,_,cnstForRange),_,_,_,componentEnv) := lookupVar2(ht, ident, inEnv);
3142 1913285 ty_1 := checkSubscripts(ty, ss);
3143 1913285 tty := Types.simplifyType(ty);
3144 1913285 ss_1 := addArrayDimensions(tty,ss);
3145 3826570 splicedExpData := InstTypes.SPLICEDEXPDATA(SOME(Expression.makeCrefExp(ComponentReferenceBasics.makeCrefIdent(ident,tty,ss_1),tty)),ty);
3146 end lookupVarFIdent;
3147
3148
3149 protected function lookupVarFMetaModelica
3150 input FCore.Cache inCache;
3151 input FCore.Graph inEnv;
3152 input DAE.ComponentRef cr;
3153 input DAE.Type inType;
3154 output FCore.Cache cache = inCache;
3155 output DAE.Attributes attr;
3156 output DAE.Type ty;
3157 output DAE.Binding binding;
3158 output Option<DAE.Const> cnstForRange;
3159 output String name;
3160 algorithm
3161 (attr,ty,binding,cnstForRange,name) := match cr
3162 local
3163 list<DAE.Var> fields;
3164 case DAE.CREF_IDENT()
3165 algorithm
3166 1520 fields := Types.getMetaRecordFields(inType);
3167 1520 DAE.TYPES_VAR(name,attr,ty,binding,_,cnstForRange) := listGet(fields,Types.findVarIndex(cr.ident,fields)+1);
3168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1520 times.
1520 for s in cr.subscriptLst loop
3169 ty := match ty
3170 ✗ case DAE.T_METAARRAY() then ty.ty;
3171 end match;
3172 end for;
3173 1520 ty := Types.getMetaRecordIfSingleton(ty);
3174 1520 then (attr,ty,binding,cnstForRange,name);
3175 case DAE.CREF_QUAL()
3176 algorithm
3177 ✗ fields := Types.getMetaRecordFields(inType);
3178 ✗ DAE.TYPES_VAR(name,attr,ty,binding,_,cnstForRange) := listGet(fields,Types.findVarIndex(cr.ident,fields)+1);
3179 ✗ for s in cr.subscriptLst loop
3180 ty := match ty
3181 ✗ case DAE.T_METAARRAY() then ty.ty;
3182 end match;
3183 end for;
3184 ✗ ty := Types.getMetaRecordIfSingleton(ty);
3185 ✗ (cache,attr,ty,binding,cnstForRange,name) := lookupVarFMetaModelica(cache, inEnv, cr.componentRef, ty);
3186 ✗ then (attr,ty,binding,cnstForRange,name);
3187 end match;
3188 end lookupVarFMetaModelica;
3189
3190 protected function lookupBinding
3191 "@author: adrpo
3192 this function uses the binding of the parent
3193 if the parent is an array of records"
3194 input DAE.ComponentRef inCref;
3195 input DAE.Type inParentType;
3196 input DAE.Type inChildType;
3197 input DAE.Binding inParentBinding;
3198 input DAE.Binding inChildBinding;
3199 output DAE.Binding outBinding;
3200 algorithm
3201 outBinding := matchcontinue(inCref, inParentBinding)
3202 local
3203 DAE.Type tyElement;
3204 DAE.Binding b;
3205 DAE.Exp e;
3206 Values.Value v;
3207 DAE.Const c;
3208 DAE.BindingSource s;
3209 list<DAE.Subscript> ss;
3210 String cId;
3211 list<DAE.Exp> exps;
3212 list<String> comp;
3213
3214 case (DAE.CREF_QUAL(_, _, ss, DAE.CREF_IDENT(cId, _, {})), DAE.EQBOUND(e, _, c, s))
3215 algorithm
3216
2/2
✓ Branch 1 taken 3580 times.
✓ Branch 2 taken 309 times.
3889 true := Types.isArray(inParentType);
3217 309 tyElement := Types.arrayElementType(inParentType);
3218
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 309 times.
309 true := Types.isRecord(tyElement);
3219
3220 // print("CREF EB: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nTyParent: " + TypesDump.printTypeStr(inParentType) + "\nParent:\n" + TypesDump.printBindingStr(inParentBinding) + "\nChild:\n" + TypesDump.printBindingStr(inChildBinding) + "\n");
3221
3222
2/2
✓ Branch 1 taken 89 times.
✓ Branch 2 taken 220 times.
309 DAE.RECORD(_, exps, comp, _) := Expression.applyExpSubscripts(e, ss);
3223
3224 220 e := listGet(exps, List.position(cId, comp));
3225 220 b := DAE.EQBOUND(e, NONE(), c, s);
3226
3227 // print("CREF EB RESULT: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nBinding:\n" + TypesDump.printBindingStr(b) + "\n");
3228 then
3229 b;
3230
3231 /*
3232 case (DAE.CREF_QUAL(id, _, ss, DAE.CREF_IDENT(cId, _, {})), _, _, DAE.EQBOUND(e, ov, c, s), _)
3233 algorithm
3234 true = Types.isArray(inParentType);
3235 tyElement = Types.arrayElementType(inParentType);
3236 true = Types.isRecord(tyElement);
3237 // e = Expression.makeCrefExp(inCref, Expression.typeof(e));
3238 // b = DAE.EQBOUND(e, NONE(), c, s);
3239 then
3240 inChildBinding;*/
3241
3242 case (DAE.CREF_QUAL(_, _, ss, DAE.CREF_IDENT(cId, _, {})), DAE.VALBOUND(v, s))
3243 algorithm
3244
1/2
✓ Branch 1 taken 19915 times.
✗ Branch 2 not taken.
19915 true := Types.isArray(inParentType);
3245 ✗ tyElement := Types.arrayElementType(inParentType);
3246 ✗ true := Types.isRecord(tyElement);
3247 // print("CREF VB: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nTyParent: " + TypesDump.printTypeStr(inParentType) + "\nParent:\n" + TypesDump.printBindingStr(inParentBinding) + "\nChild:\n" + TypesDump.printBindingStr(inChildBinding) + "\n");
3248 ✗ e := ValuesUtil.valueExp(v);
3249 ✗ DAE.RECORD(_, exps, comp, _) := Expression.applyExpSubscripts(e, ss);
3250
3251 ✗ e := listGet(exps, List.position(cId, comp));
3252
3253 ✗ b := DAE.EQBOUND(e, NONE(), DAE.C_CONST(), s);
3254 // print("CREF VB RESULT: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nBinding:\n" + TypesDump.printBindingStr(b) + "\n");
3255 then
3256 b;
3257
3258 /*
3259 case (DAE.CREF_QUAL(id, _, ss, DAE.CREF_IDENT(cId, _, {})), _, _, DAE.VALBOUND(v, s), _)
3260 algorithm
3261 true = Types.isArray(inParentType);
3262 tyElement = Types.arrayElementType(inParentType);
3263 true = Types.isRecord(tyElement);
3264 //e = Expression.makeCrefExp(inCref, inChildType);
3265 //b = DAE.EQBOUND(e, NONE(), DAE.C_CONST(), s);
3266 then
3267 inChildBinding;*/
3268
3269 else inChildBinding;
3270
3271 end matchcontinue;
3272 end lookupBinding;
3273
3274 protected function elabComponentRecursive "
3275 Helper function for lookupvarF, to return an ComponentRef if there is one."
3276 input Option<DAE.Exp> oCref;
3277 output list<DAE.ComponentRef> lref;
3278 algorithm
3279 lref := match oCref
3280 local
3281 DAE.ComponentRef ecpr;
3282
3283 // expression is an unqualified component reference
3284 case SOME(DAE.CREF(ecpr as DAE.CREF_IDENT(_,_,_),_ )) then (ecpr::{});
3285
3286 // expression is an qualified component reference
3287 case SOME(DAE.CREF(ecpr as DAE.CREF_QUAL(_,_,_,_),_ )) then (ecpr::{});
3288
3289 else {};
3290 end match;
3291 end elabComponentRecursive;
3292
3293 protected function addArrayDimensions "This is the function where we add arrays representing the dimension of the type.
3294 In type {array 2[array 3 ]] Will generate 2 arrays. {1,2} and {1,2,3}"
3295 input DAE.Type tySub;
3296 input list<DAE.Subscript> ss;
3297 output list<DAE.Subscript> outType;
3298 algorithm
3299 outType :=
3300 matchcontinue ss
3301 local
3302 list<DAE.Subscript> subs;
3303 DAE.Dimensions dims;
3304 case _
3305 algorithm
3306
2/2
✓ Branch 1 taken 1644702 times.
✓ Branch 2 taken 541993 times.
2186695 true := Types.isArray(tySub);
3307 541993 dims := TypesDump.getDimensions(tySub);
3308 541993 subs := List.map(dims, makeDimensionSubscript);
3309 534206 subs := expandWholeDimSubScript(ss,subs);
3310 then subs;
3311 else ss; // non array, return
3312 end matchcontinue;
3313 end addArrayDimensions;
3314
3315 protected function makeDimensionSubscript
3316 "Creates a slice with all indices of the dimension."
3317 input DAE.Dimension inDim;
3318 output DAE.Subscript outSub;
3319 algorithm
3320 outSub := match inDim
3321 local
3322 list<DAE.Exp> expl;
3323 Absyn.Path enum_name;
3324 list<String> l;
3325
3326 // Special case when addressing array[0].
3327 case DAE.DIM_INTEGER(integer = 0)
3328 then DAE.SLICE(DAE.ARRAY(DAE.T_INTEGER_DEFAULT, true, {DAE.ICONST(0)}));
3329
3330 // Array with integer dimension.
3331 case DAE.DIM_INTEGER()
3332 1177892 then DAE.SLICE(DAE.RANGE(
3333 DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT, {DAE.DIM_INTEGER(inDim.integer)}),
3334 DAE.ICONST(1), NONE(), DAE.ICONST(inDim.integer)));
3335
3336 // Array with boolean dimension.
3337 case DAE.DIM_BOOLEAN()
3338 algorithm
3339 expl := {DAE.BCONST(false), DAE.BCONST(true)};
3340 15 then
3341 DAE.SLICE(DAE.ARRAY(DAE.T_BOOL_DEFAULT, true, expl));
3342
3343 // Array with enumeration dimension.
3344 case DAE.DIM_ENUM(enumTypeName = enum_name, literals = l)
3345 algorithm
3346 690 expl := makeEnumLiteralIndices(enum_name, l, 1);
3347 690 then DAE.SLICE(DAE.ARRAY(DAE.T_ENUMERATION(NONE(), enum_name, l, {}, {}), true, expl));
3348 end match;
3349 end makeDimensionSubscript;
3350
3351 protected function makeEnumLiteralIndices
3352 "Creates a list of enumeration literal expressions from an enumeration."
3353 input Absyn.Path enumTypeName;
3354 input list<String> enumLiterals;
3355 input Integer enumIndex;
3356 output list<DAE.Exp> enumIndices;
3357 algorithm
3358 enumIndices := match enumLiterals
3359 local
3360 String l;
3361 list<String> ls;
3362 DAE.Exp e;
3363 list<DAE.Exp> expl;
3364 Absyn.Path enum_type_name;
3365 case {} then {};
3366 case l :: ls
3367 algorithm
3368 5513 enum_type_name := AbsynUtil.joinPaths(enumTypeName, Absyn.IDENT(l));
3369 5513 e := DAE.ENUM_LITERAL(enum_type_name, enumIndex);
3370 5513 expl := makeEnumLiteralIndices(enumTypeName, ls, enumIndex + 1);
3371 then
3372 e :: expl;
3373 end match;
3374 end makeEnumLiteralIndices;
3375
3376 protected function expandWholeDimSubScript " Function expandWholeDimSubScript
3377 This function replaces Wholedim(if possible) with the expanded dimension.
3378 If there exist a subscript, the subscript is used instead of the expanded dimension.
3379 "
3380 input list<DAE.Subscript> inSubs;
3381 input list<DAE.Subscript> inSlice;
3382 output list<DAE.Subscript> outSubs;
3383 algorithm
3384 outSubs :=
3385 matchcontinue(inSubs,inSlice)
3386 local
3387 DAE.Subscript sub1,sub2;
3388 list<DAE.Subscript> subs1,subs2;
3389 // If a for-iterator is used as subscript we get a cref subscript in inSubs,
3390 // but nothing in inSlice because it only contains integers (see
3391 // addArrayDimensions above). This case makes sure that for-iterators are
3392 // not lost here.
3393 case (((sub1 as DAE.INDEX(exp = DAE.CREF())) :: subs1),
3394 subs2)
3395 algorithm
3396 7027 subs2 := expandWholeDimSubScript(subs1, subs2);
3397 then
3398 (sub1 :: subs2);
3399 case(_,{}) then {};
3400 case({},subs2) then subs2;
3401 case(((DAE.WHOLEDIM())::subs1), (sub2::subs2))
3402 algorithm
3403 1469 subs2 := expandWholeDimSubScript(subs1,subs2);
3404 then
3405 (sub2::subs2);
3406 case((sub1::subs1), (_::subs2))
3407 algorithm
3408 343527 subs2 := expandWholeDimSubScript(subs1,subs2);
3409 then
3410 (sub1::subs2);
3411 end matchcontinue;
3412 end expandWholeDimSubScript;
3413
3414 protected function sliceDimensionType "Lifts an type to spcified dimension by type2
3415 "
3416 input DAE.Type inTypeD;
3417 input DAE.Type inTypeL;
3418 output DAE.Type outType;
3419
3420 algorithm
3421 outType := match (inTypeD,inTypeL)
3422 local
3423 DAE.Type t,tOrg;
3424 list<Integer> dimensions;
3425 DAE.Dimensions dim2;
3426 case(t, tOrg)
3427 algorithm
3428 273410 dimensions := Types.getDimensionSizes(t);
3429 273410 dim2 := List.map(dimensions, Expression.intDimension);
3430 273410 dim2 := listReverse(dim2);
3431 273410 t := ((List.foldr(dim2,Types.liftArray, tOrg)));
3432 then
3433 t;
3434 end match;
3435 end sliceDimensionType;
3436
3437
3438 public function buildMetaRecordType "common function when looking up the type of a metarecord"
3439 input FCore.Cache inCache;
3440 input FCore.Graph inEnv;
3441 input SCode.Element cdef;
3442 output FCore.Cache outCache;
3443 output FCore.Graph outEnv;
3444 output DAE.Type ftype;
3445 protected
3446 String id;
3447 FCore.Graph env;
3448 Absyn.Path utPath,path;
3449 Integer index;
3450 list<DAE.Var> varlst;
3451 list<SCode.Element> els;
3452 Boolean singleton;
3453 FCore.Cache cache;
3454 list<DAE.Type> typeVarsType;
3455 list<String> typeVars;
3456 algorithm
3457
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 48727 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48727 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48727 times.
48727 SCode.CLASS(name=id,restriction=SCode.R_METARECORD(name=utPath,index=index,singleton=singleton,typeVars=typeVars),classDef=SCode.PARTS(elementLst = els)) := cdef;
3458 48727 env := FGraph.openScope(inEnv, SCode.NOT_ENCAPSULATED(), id, SOME(FCore.CLASS_SCOPE()));
3459 // print("buildMetaRecordType " + id + " in scope " + FGraph.printGraphPathStr(env) + "\n");
3460 48727 (cache,utPath) := Inst.makeFullyQualified(inCache,env,utPath);
3461 48727 path := AbsynUtil.joinPaths(utPath, Absyn.IDENT(id));
3462 48727 (outCache,outEnv,_,_,_,_,_,varlst,_,_) := Inst.instElementList(
3463 cache,env,InnerOuter.emptyInstHierarchy, UnitAbsyn.noStore,
3464 DAE.NOMOD(),DAE.NOPRE(),
3465 ClassInf.META_RECORD(Absyn.IDENT("")), List.map1(els,Util.makeTuple,DAE.NOMOD()),
3466 {}, false, InstTypes.INNER_CALL(), ConnectionGraph.EMPTY, Connect.emptySet, true);
3467 48705 varlst := Types.boxVarLst(varlst);
3468 // for v in varlst loop print(TypesDump.unparseType(v.ty)+"\n"); end for;
3469
4/4
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 48705 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 48705 times.
48749 typeVarsType := list(DAE.T_METAPOLYMORPHIC(tv) for tv in typeVars);
3470
2/2
✓ Branch 0 taken 41196 times.
✓ Branch 1 taken 7509 times.
89901 ftype := DAE.T_METARECORD(path,utPath,typeVarsType,index,varlst,singleton);
3471 // print("buildMetaRecordType " + id + " in scope " + FGraph.printGraphPathStr(env) + " OK " + TypesDump.unparseType(ftype) +"\n");
3472 end buildMetaRecordType;
3473
3474 public function isIterator
3475 "Looks up a cref and returns SOME(true) if it references an iterator,
3476 SOME(false) if it references an element in the current scope, and NONE() if
3477 the name couldn't be found in the current scope at all."
3478 input FCore.Cache inCache;
3479 input FCore.Graph inEnv;
3480 input DAE.ComponentRef inCref;
3481 output Option<Boolean> outIsIterator;
3482 output FCore.Cache outCache;
3483 algorithm
3484 (outIsIterator, outCache) := matchcontinue(inCache, inEnv)
3485 local
3486 String id;
3487 FCore.Cache cache;
3488 FCore.Graph env;
3489 FCore.Children ht;
3490 Option<Boolean> res;
3491 Option<DAE.Const> ic;
3492 FCore.Ref ref;
3493 Boolean b;
3494
3495 // Look in the current scope.
3496 case (cache, FCore.G(scope = ref::_))
3497 algorithm
3498 135996 ht := FNode.children(FNode.fromRef(ref));
3499 // Only look up the first part of the cref, we're only interested in if
3500 // it exists and if it's an iterator or not.
3501 135996 id := ComponentReferenceBasics.crefFirstIdent(inCref);
3502 135996 (DAE.TYPES_VAR(constOfForIteratorRange = ic),_,_,_,_) := lookupVar2(ht, id, inEnv);
3503
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 129968 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 129649 times.
129968 b := isSome(ic);
3504 129968 then
3505 (SOME(b), cache);
3506
3507 // If not found, look in the next scope only if the current scope is implicit.
3508 case (cache, FCore.G(scope = ref::_))
3509 algorithm
3510
2/2
✓ Branch 2 taken 331 times.
✓ Branch 3 taken 5697 times.
6028 true := frameIsImplAddedScope(FNode.fromRef(ref));
3511 5697 (env, _) := FGraph.stripLastScopeRef(inEnv);
3512 5697 (res, cache) := isIterator(cache, env, inCref);
3513 then
3514 (res, cache);
3515
3516 331 else (NONE(), inCache);
3517
3518 end matchcontinue;
3519 end isIterator;
3520
3521 public function isFunctionCallViaComponent
3522 input FCore.Cache inCache;
3523 input FCore.Graph inEnv;
3524 input Absyn.Path inPath;
3525 output Boolean yes;
3526 algorithm
3527 yes := matchcontinue inPath
3528 local
3529 Absyn.Ident name;
3530 // see if the first path ident is a component
3531 // we might have a component reference, i.e. world.gravityAcceleration
3532 case Absyn.QUALIFIED(name, _)
3533 algorithm
3534 35075 ErrorExt.setCheckpoint("functionViaComponentRef10");
3535 35075 lookupVarIdent(inCache, inEnv, name, {});
3536 622 ErrorExt.rollBack("functionViaComponentRef10");
3537 then
3538 true;
3539
3540 case Absyn.QUALIFIED(_, _)
3541 algorithm
3542 34453 ErrorExt.rollBack("functionViaComponentRef10");
3543 34453 then
3544 fail();
3545
3546 else false;
3547
3548 end matchcontinue;
3549 end isFunctionCallViaComponent;
3550
3551 protected function prefixSplicedExp
3552 "Prefixes a spliced exp that contains a cref with another cref."
3553 input DAE.ComponentRef inCref;
3554 input InstTypes.SplicedExpData inSplicedExp;
3555 output InstTypes.SplicedExpData outSplicedExp;
3556 algorithm
3557 outSplicedExp := match inSplicedExp
3558 local
3559 DAE.Type ety, ty;
3560 DAE.ComponentRef cref;
3561
3562 case InstTypes.SPLICEDEXPDATA(SOME(DAE.CREF(cref, ety)), ty)
3563 algorithm
3564 117400 cref := ComponentReference.joinCrefs(inCref, cref);
3565 234800 then
3566 InstTypes.SPLICEDEXPDATA(SOME(DAE.CREF(cref, ety)), ty);
3567
3568 else inSplicedExp;
3569 end match;
3570 end prefixSplicedExp;
3571
3572 public function isArrayType
3573 input FCore.Cache inCache;
3574 input FCore.Graph inEnv;
3575 input Absyn.Path inPath;
3576 output FCore.Cache outCache = inCache;
3577 output Boolean outIsArray;
3578 protected
3579 SCode.Element el;
3580 Absyn.Path p;
3581 FCore.Graph env;
3582 algorithm
3583 try
3584 2 (outCache, el, env) := lookupClass(inCache, inEnv, inPath);
3585
3586 outIsArray := match el
3587 case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = Absyn.TPATH(arrayDim = SOME(_))))
3588 then true;
3589
3590 case SCode.CLASS(classDef = SCode.DERIVED(attributes = SCode.ATTR(arrayDims = _ :: _)))
3591 then true;
3592
3593 case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = Absyn.TPATH(path = p)))
3594 algorithm
3595 ✗ (outCache, outIsArray) := isArrayType(outCache, env, p);
3596 ✗ then
3597 outIsArray;
3598
3599 else false;
3600 end match;
3601 else
3602 ✗ outIsArray := false;
3603 end try;
3604 end isArrayType;
3605
3606 annotation(__OpenModelica_Interface="frontend");
3607 end Lookup;
3608