Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 62.3% 48 / 0 / 77
Functions: -% 0 / 1 / 1
Branches: 82.4% 28 / 0 / 34

OMCompiler/Compiler/NFFrontEnd/NFLookupState.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 NFLookupState
37
38 import Absyn;
39 import AbsynUtil;
40 import ComponentRef = NFComponentRef;
41 import SCode;
42 import NFInstNode.InstNode;
43 import InstContext = NFInstContext;
44
45 protected
46 import Dump;
47 import Error;
48 import SCodeUtil;
49 import Class = NFClass;
50 import Component = NFComponent;
51 import Inst = NFInst;
52 import Restriction = NFRestriction;
53
54 public
55 uniontype LookupStateName
56 record PATH
57 Absyn.Path path;
58 end PATH;
59
60 record CREF
61 Absyn.ComponentRef cref;
62 end CREF;
63
64 function toString
65 input LookupStateName name;
66 output String str;
67 algorithm
68 str := match name
69 3 case PATH() then AbsynUtil.pathString(name.path);
70 4 case CREF() then Dump.printComponentRefStr(name.cref);
71 end match;
72 end toString;
73
74 function firstIdent
75 input LookupStateName name;
76 output String id;
77 algorithm
78 id := match name
79 ✗ case PATH() then AbsynUtil.pathFirstIdent(name.path);
80 ✗ case CREF() then AbsynUtil.crefFirstIdent(name.cref);
81 end match;
82 end firstIdent;
83
84 function secondIdent
85 input LookupStateName name;
86 output String id;
87 algorithm
88 id := match name
89 ✗ case PATH() then AbsynUtil.pathSecondIdent(name.path);
90 ✗ case CREF() then AbsynUtil.crefSecondIdent(name.cref);
91 end match;
92 end secondIdent;
93 end LookupStateName;
94
95 uniontype LookupState
96
97 "LookupState is used by the lookup to keep track of what state it's in so that
98 the rules for composite name lookup can be enforced."
99 record BEGIN "The start state." end BEGIN;
100 record COMP "A component." end COMP;
101 record CLASS_COMP "A component found in a class." end CLASS_COMP;
102 record COMP_CLASS "A class found in component." end COMP_CLASS;
103 record COMP_FUNC "A function found in component." end COMP_FUNC;
104 record PACKAGE "A package." end PACKAGE;
105 record CLASS "A class." end CLASS;
106 record FUNC "A function." end FUNC;
107 record PREDEF_COMP "A predefined component." end PREDEF_COMP;
108 record PREDEF_CLASS "A predefined class." end PREDEF_CLASS;
109 record IMPORT end IMPORT;
110 record PARTIAL_CLASS "A partial class." end PARTIAL_CLASS;
111 record NON_CONSTANT "A nonconstant found in a context where a constant is required." end NON_CONSTANT;
112 record NON_ENCAPSULATED "A nonencapsulated element found in a context where encapsulated is required." end NON_ENCAPSULATED;
113 record ERROR "An error occured during lookup."
114 LookupState errorState;
115 end ERROR;
116
117 function assertClass
118 input LookupState endState;
119 input InstNode node;
120 input Absyn.Path name;
121 input InstContext.Type context;
122 input SourceInfo info;
123 algorithm
124 1148882 assertState(endState, LookupState.CLASS(), node,
125 LookupStateName.PATH(name), context, info);
126 end assertClass;
127
128 function assertFunction
129 input LookupState endState;
130 input InstNode node;
131 input Absyn.ComponentRef name;
132 input InstContext.Type context;
133 input SourceInfo info;
134 algorithm
135 109926 assertState(endState, LookupState.FUNC(), node,
136 LookupStateName.CREF(name), context, info);
137 end assertFunction;
138
139 function assertComponent
140 input LookupState endState;
141 input InstNode node;
142 input Absyn.ComponentRef name;
143 input InstContext.Type context;
144 input SourceInfo info;
145 algorithm
146 1178170 assertState(endState, LookupState.COMP(), node,
147 LookupStateName.CREF(name), context, info);
148 end assertComponent;
149
150 function assertImport
151 input LookupState endState;
152 input InstNode node;
153 input Absyn.Path name;
154 input SourceInfo info;
155 algorithm
156 10991 assertState(endState, LookupState.IMPORT(), node,
157 LookupStateName.PATH(name), NFInstContext.NO_CONTEXT, info);
158 end assertImport;
159
160 function isCallableType
161 input InstNode node;
162 output Boolean callable;
163 protected
164 InstNode n;
165 algorithm
166
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4076 times.
4076 if not InstNode.isClass(node) then
167 callable := false;
168 ✗ return;
169 end if;
170
171 4076 n := InstNode.resolveInner(node);
172 4076 Inst.expand(n, NFInstContext.NO_CONTEXT);
173
174 callable := match InstNode.restriction(n)
175 case Restriction.RECORD() then true;
176 case Restriction.OPERATOR() then true;
177 case Restriction.ENUMERATION() then true;
178 case Restriction.TYPE() guard InstNode.isEnumerationType(n) then true;
179 89 else InstNode.isClockType(n);
180 end match;
181 end isCallableType;
182
183 function isCallableComponent
184 input InstNode node;
185 output Boolean callable;
186 algorithm
187 101 callable := Class.isFunction(InstNode.getClass(node));
188 end isCallableComponent;
189
190 function isFunction
191 input LookupState state;
192 input InstNode node;
193 output Boolean isFunction;
194 algorithm
195 isFunction := match state
196 case FUNC() then true;
197 case COMP_FUNC() then true;
198 1525 case CLASS() then isCallableType(node);
199 ✗ case COMP() then isCallableComponent(node);
200 else false;
201 end match;
202 end isFunction;
203
204 function isClass
205 input LookupState state;
206 output Boolean isClass;
207 algorithm
208 isClass := match state
209 case COMP_CLASS() then true;
210 case CLASS() then true;
211 case PREDEF_CLASS() then true;
212 else false;
213 end match;
214 end isClass;
215
216 function assertState
217 input LookupState endState;
218 input LookupState expectedState;
219 input InstNode node;
220 input LookupStateName name;
221 input InstContext.Type context;
222 input SourceInfo info;
223 algorithm
224 () := match (endState, expectedState)
225 local
226 String name_str;
227 SourceInfo info2;
228 InstNode node2;
229
230 // Found the expected kind of element.
231 case (COMP(), COMP()) then ();
232 case (CLASS_COMP(), COMP()) then ();
233 case (PREDEF_COMP(), COMP()) then ();
234 case (FUNC(), COMP()) then ();
235 case (COMP_FUNC(), COMP()) then ();
236 case (PACKAGE(), CLASS()) then ();
237 case (CLASS(), CLASS()) then ();
238 case (PREDEF_CLASS(), CLASS()) then ();
239 case (FUNC(), CLASS()) then ();
240 case (FUNC(), FUNC()) then ();
241 case (COMP_FUNC(), FUNC()) then ();
242
243 case (CLASS(), FUNC()) guard isCallableType(node) then ();
244 case (COMP(), FUNC()) guard isCallableComponent(node) then ();
245
246 // Found a class via a component, but expected a function.
247 case (COMP_CLASS(), FUNC())
248 algorithm
249 ✗ printFoundWrongTypeError(endState, expectedState, name, info);
250 ✗ then
251 fail();
252
253 // Found a function via a component, but didn't expect a function.
254 case (COMP_FUNC(), _)
255 algorithm
256 ✗ name_str := LookupStateName.toString(name);
257 ✗ Error.addSourceMessage(Error.FOUND_FUNC_NAME_VIA_COMP_NONCALL, {name_str}, info);
258 ✗ then
259 fail();
260
261 // Found a class via a component. Only components and functions are
262 // allowed to be lookup up via a component.
263 case (COMP_CLASS(), _)
264 algorithm
265 4 Error.addSourceMessage(Error.FOUND_CLASS_NAME_VIA_COMPONENT,
266 {LookupStateName.toString(name)}, info);
267 2 then
268 fail();
269
270 // Invalid form when looking for a function via a component, only
271 // c.C1...Cn.f is allowed.
272 case (ERROR(errorState = COMP_FUNC()), FUNC())
273 algorithm
274 ✗ name_str := InstNode.name(node);
275 ✗ info2 := InstNode.info(node);
276 ✗ Error.addSourceMessage(Error.NON_CLASS_IN_COMP_FUNC_NAME, {name_str}, info2);
277 ✗ then
278 fail();
279
280 // Found class when looking up a composite component name.
281 case (ERROR(errorState = COMP_FUNC()), COMP())
282 algorithm
283 1 name_str := InstNode.name(node);
284 2 Error.addSourceMessage(Error.UNEXPECTED_COMPONENT_IN_COMPOSITE_NAME,
285 {name_str, LookupStateName.toString(name)}, info);
286 1 then
287 fail();
288
289 // Found class via composite component name when actually looking for a class.
290 case (ERROR(errorState = COMP_FUNC()), _)
291 algorithm
292 ✗ name_str := InstNode.name(node);
293 ✗ Error.addSourceMessage(Error.LOOKUP_CLASS_VIA_COMP_COMP,
294 {name_str, LookupStateName.toString(name)}, info);
295 ✗ then
296 fail();
297
298 // Found class when looking up a composite component name.
299 case (ERROR(errorState = CLASS_COMP()), COMP())
300 algorithm
301 ✗ name_str := InstNode.name(node);
302 ✗ Error.addSourceMessage(Error.CLASS_IN_COMPOSITE_COMP_NAME,
303 {name_str, LookupStateName.toString(name)}, info);
304 ✗ then
305 fail();
306
307 // Found class via composite component name when actually looking for a class.
308 case (ERROR(errorState = CLASS_COMP()), _)
309 algorithm
310 ✗ name_str := InstNode.name(node);
311 ✗ Error.addSourceMessage(Error.LOOKUP_CLASS_VIA_COMP_COMP,
312 {name_str, LookupStateName.toString(name)}, info);
313 ✗ then
314 fail();
315
316 // Found import as part of a composite name where it's not the first
317 // identifier, e.g. A.B.C where B or C are imported names.
318 case (ERROR(errorState = IMPORT()), _)
319 algorithm
320 1 name_str := InstNode.name(node);
321 2 Error.addSourceMessage(Error.IMPORT_IN_COMPOSITE_NAME,
322 {name_str, LookupStateName.toString(name)}, info);
323 1 then
324 fail();
325
326 case (ERROR(errorState = PARTIAL_CLASS()), _)
327 algorithm
328
2/4
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
1 if not (InstContext.inRelaxed(context) or InstContext.inRedeclared(context)) then
329 1 node2 := listHead(InstNode.scopeList(node));
330
331
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 if InstNode.isComponent(node2) then
332 6 Error.addMultiSourceMessage(Error.USE_OF_PARTIAL_CLASS,
333 {InstNode.name(node2), InstNode.name(node), AbsynUtil.pathString(Class.constrainingClassPath(node))},
334 {InstNode.info(node), InstNode.info(node2)});
335 else
336 ✗ Error.addSourceMessage(Error.LOOKUP_IN_PARTIAL_CLASS,
337 {InstNode.name(node)}, info);
338 end if;
339
340 1 fail();
341 end if;
342 then
343 ();
344
345 case (ERROR(errorState = NON_CONSTANT()), _)
346 algorithm
347 3 Error.addMultiSourceMessage(Error.NON_CONSTANT_IN_ENCLOSING_SCOPE,
348 {InstNode.name(node)}, {InstNode.info(node), info});
349 1 then
350 fail();
351
352 case (ERROR(errorState = NON_ENCAPSULATED()), _)
353 algorithm
354 4 Error.addMultiSourceMessage(Error.NON_ENCAPSULATED_CLASS_ACCESS,
355 {InstNode.name(InstNode.parent(node)), InstNode.name(node)},
356 {InstNode.info(node), info});
357 1 then
358 fail();
359
360 // Found some element when looking for import.
361 case (_, IMPORT()) then ();
362
363 // Found the wrong kind of element.
364 else
365 algorithm
366 3 printFoundWrongTypeError(endState, expectedState, name, info);
367 3 then
368 fail();
369
370 end match;
371 end assertState;
372
373 function isError
374 input LookupState state;
375 output Boolean isError;
376 algorithm
377 isError := match state
378 case ERROR() then true;
379 else false;
380 end match;
381 end isError;
382
383 function lookupStateString
384 "Returns the string representation of a LookupState, with translation."
385 input LookupState state;
386 output String str;
387 algorithm
388 str := match state
389 case BEGIN() then "<begin>";
390 case COMP() then "component";
391 case CLASS_COMP() then "component";
392 case COMP_CLASS() then "class";
393 case COMP_FUNC() then "function";
394 case PACKAGE() then "package";
395 case CLASS() then "class";
396 case FUNC() then "function";
397 case PREDEF_COMP() then "component";
398 case PREDEF_CLASS() then "class";
399 end match;
400 end lookupStateString;
401
402 function printFoundWrongTypeError
403 "Helper function to assertState, prints out an error when the wrong kind
404 of element was found."
405 input LookupState foundState;
406 input LookupState expectedState;
407 input LookupStateName name;
408 input SourceInfo info;
409 protected
410 String name_str, found_str, expected_str;
411 algorithm
412 3 name_str := LookupStateName.toString(name);
413 3 found_str := lookupStateString(foundState);
414 3 expected_str := lookupStateString(expectedState);
415 3 Error.addSourceMessage(Error.LOOKUP_FOUND_WRONG_TYPE,
416 {name_str, expected_str, found_str}, info);
417 end printFoundWrongTypeError;
418
419 function next
420 "Checks that the found name is allowed to be looked up given the current state
421 of the name lookup, and returns the new state if it is. Otherwise it will
422 print a (hopefully relevant) error message and fail."
423 input InstNode node;
424 input LookupState currentState;
425 input InstContext.Type context;
426 input Boolean checkAccessViolations = true;
427 output LookupState nextState;
428 protected
429 LookupState entry_ty;
430 algorithm
431
4/4
✓ Branch 0 taken 1544872 times.
✓ Branch 1 taken 13639 times.
✓ Branch 3 taken 1544832 times.
✓ Branch 4 taken 40 times.
1558511 if checkAccessViolations and not InstContext.inInstanceAPI(context) then
432 // Check that the element is allowed to be accessed given its visibility.
433 1544832 checkProtection(node, currentState);
434 // Check that we're allowed to look in the current scope.
435 //checkPackageLikeAccess(inCurrentState, el, inEnv);
436 end if;
437
438 // Get the state for the found element, and check that the transition to the
439 // new state is valid.
440 1558509 entry_ty := nodeState(node);
441 1558509 nextState := next2(entry_ty, currentState, node);
442 end next;
443
444 function checkProtection
445 "Checks if a found element is protected during lookup, and prints an error if
446 the element was not the first part of a name while being protected.
447 I.e. P.a is allowed if P is protected, but not e.g. a.P or a.P.b."
448 input InstNode node;
449 input LookupState currentState;
450 algorithm
451 () := match currentState
452 // The first part of a name is allowed to be protected, it's only
453 // accessing a protected element via dot-notation that's illegal.
454 case BEGIN() then ();
455
456 else
457 algorithm
458 // A protected element generates an error.
459
3/4
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1544830 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
1544832 if InstNode.isProtected(node) and
460 not Flags.isConfigFlagSet(Flags.ALLOW_NON_STANDARD_MODELICA, "protectedAccess") then
461 4 Error.addSourceMessage(Error.PROTECTED_ACCESS,
462 {InstNode.name(node)}, InstNode.info(node));
463 2 fail();
464 end if;
465 then
466 ();
467
468 end match;
469 end checkProtection;
470
471 function nodeState
472 input InstNode node;
473 output LookupState state;
474 algorithm
475
5/6
✓ Branch 1 taken 2139943 times.
✓ Branch 2 taken 1455193 times.
✓ Branch 4 taken 2139943 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2139942 times.
✓ Branch 8 taken 1 time.
3595136 if InstNode.isComponent(node) or InstNode.isName(node) or InstNode.isEmpty(node) then
476 state := COMP();
477 else
478 2139942 state := elementState(InstNode.definition(node));
479 end if;
480 end nodeState;
481
482 function elementState
483 "Returns the lookup state of a given element."
484 input SCode.Element element;
485 output LookupState state;
486 algorithm
487 state := match element
488 case SCode.CLASS(restriction = SCode.R_PACKAGE()) then PACKAGE();
489 case SCode.CLASS(restriction = SCode.R_FUNCTION()) then FUNC();
490 case SCode.CLASS() then CLASS();
491 else
492 algorithm
493 ✗ Error.terminate(getInstanceName() + " got unknown element.", sourceInfo());
494 ✗ then
495 fail();
496 end match;
497 end elementState;
498
499 function next2
500 "This function implements the state machine that checks which transitions are
501 valid during composite name lookup, as defined in section 5.3.2 of the
502 specification. elementState is expected to be one of COMP,
503 CLASS, FUNC or PACKAGE, indicating what type the found
504 element is. The state machine looks like this flow diagram (nodes in
505 [brackets] are nodes with an edge to themselves):
506
507 BEGIN----------------+----------------+--------------+
508 |(COMP) |(PACKAGE) |(CLASS/FUNC)
509 v v v
510 +--------------[COMP]----------[PACKAGE]<->[CLASS/FUNC]
511 |(CLASS|PACKAGE) |(FUNC) | |(COMP)
512 | | | |only if
513 v | | |package-like
514 [COMP_CLASS] | +>[CLASS_COMP]<+
515 ^(CLASS|PACKAGE) |
516 | |
517 v(FUNC) |
518 [COMP_FUNC]<----------+
519
520 There's also PREDEF_COMP and PREDEF_CLASS for the predefined types
521 and components, e.g. Real, time, etc., which are handled as special cases in
522 lookupName and bypasses this state machine.
523 "
524 input LookupState elementState;
525 input LookupState currentState;
526 input InstNode node;
527 output LookupState nextState;
528 algorithm
529 nextState := match (elementState, currentState)
530 local
531
532 // Transitions from BEGIN.
533 case (_, BEGIN()) then elementState;
534
535 // Transitions from COMP.
536 case (COMP(), COMP()) then COMP();
537 case (FUNC(), COMP()) then COMP_FUNC();
538 case (_, COMP()) then COMP_CLASS();
539
540 // Transitions from CLASS_COMP.
541 case (COMP(), CLASS_COMP()) then CLASS_COMP();
542 case (CLASS_COMP(), CLASS_COMP()) then CLASS_COMP();
543
544 // Transitions from PACKAGE.
545 case (COMP(), PACKAGE()) then CLASS_COMP();
546 case (_, PACKAGE()) then elementState;
547
548 // Transitions from CLASS/FUNC.
549 // next has already checked that the found element is encapsulated or
550 // the class/func looks like a package, so any transition is fine here.
551 case (COMP(), CLASS()) then CLASS_COMP();
552 case (_, CLASS()) then elementState;
553 case (COMP(), FUNC()) then CLASS_COMP();
554 case (_, FUNC()) then elementState;
555
556 // Transitions from COMP_CLASS.
557 case (FUNC(), COMP_CLASS()) then COMP_FUNC();
558 case (CLASS(), COMP_CLASS()) then COMP_CLASS();
559 case (PACKAGE(), COMP_CLASS()) then COMP_CLASS();
560
561 // Transitions from COMP_FUNC.
562 case (FUNC(), COMP_FUNC()) then COMP_FUNC();
563 case (CLASS(), COMP_FUNC()) then COMP_CLASS();
564 case (PACKAGE(), COMP_FUNC()) then COMP_CLASS();
565
566 // When looking for a function in a component the only valid form is
567 // c.M1..Mn.f, where M1..Mn are classes, but we found a component instead.
568 case (COMP(), _)
569 then ERROR(COMP_FUNC());
570
571 // We found a class when only components are allowed, i.e. when not looking
572 // for a function via a component.
573 case (_, CLASS_COMP())
574 then ERROR(CLASS_COMP());
575
576 else
577 algorithm
578 ✗ Error.terminate(getInstanceName() + " failed on unknown transition for element " + InstNode.name(node), sourceInfo());
579 ✗ then
580 fail();
581
582 end match;
583 end next2;
584
585 //function checkPackageLikeAccess
586 // "Checks that the found is element is allowed to be looked up in the current
587 // scope. In particular it checks that only encapsulated elements are allowed to
588 // be looked up in classes which does not satisfy the requirements for a package."
589 // input LookupState inCurrentState;
590 // input SCode.Element inElement;
591 // input Env inEnv;
592 //algorithm
593 // () := matchcontinue(inCurrentState, inElement, inEnv)
594 // local
595 // String name, env_str;
596 // SourceInfo info;
597
598 // // Nothing to check in packages or components.
599 // case (BEGIN(), _, _) then ();
600 // case (PACKAGE(), _, _) then ();
601 // case (COMP(), _, _) then ();
602 // case (CLASS_COMP(), _, _) then ();
603
604 // // Check if the found element is encapsulated, then it's ok to look it up in
605 // // a non-package.
606 // case (_, _, _)
607 // equation
608 // true = SCodeUtil.isElementEncapsulated(inElement);
609 // then
610 // ();
611
612 // // If the found element is not encapsulated, check if the current scope
613 // // satisfies the requirements for a package, i.e. only contains classes and
614 // // constants.
615 // case (_, _, _)
616 // equation
617 // _ = NFEnv.mapScope(inEnv, isValidPackageElement);
618 // then
619 // ();
620
621 // // If the found element isn't encapsulated and the current scope doesn't
622 // // satisfy the requirements for a package, print an error.
623 // else
624 // equation
625 // (name, info) = SCodeUtil.elementNameInfo(inElement);
626 // env_str = NFEnv.printEnvPathStr(inEnv);
627 // Error.addSourceMessage(Error.NON_ENCAPSULATED_CLASS_ACCESS,
628 // {env_str, name}, info);
629 // then
630 // fail();
631
632 // end matchcontinue;
633 //end checkPackageLikeAccess;
634
635 //function isValidPackageElement
636 // "Helper function to checkPackageLikeAccess, checks that a given entry is a
637 // valid package element (a constant or class)."
638 // input Entry inEntry;
639 // output Entry outEntry;
640 //protected
641 // SCode.Element el;
642 //algorithm
643 // /* TODO: A component might be a constant due to a class prefix. */
644 // /* TODO: Return the found invalid element to improve the error message. */
645 // el := NFEnv.entryElement(inEntry);
646 // true := SCodeUtil.isValidPackageElement(el);
647 // outEntry := inEntry;
648 //end isValidPackageElement;
649
650 function checkCrefVariability
651 "Checks that a variable found in an enclosing scope is a constant, and if
652 not sets the state to an error."
653 input ComponentRef cref;
654 input Boolean inEnclosingScope;
655 input InstContext.Type context;
656 input output LookupState state;
657 algorithm
658
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1288655 times.
1288658 if isError(state) then
659 3 return;
660 end if;
661
662
6/6
✓ Branch 0 taken 1156993 times.
✓ Branch 1 taken 131662 times.
✓ Branch 3 taken 26734 times.
✓ Branch 4 taken 104928 times.
✓ Branch 7 taken 104927 times.
✓ Branch 8 taken 1 time.
1288655 if inEnclosingScope and not InstContext.inRelaxed(context) and
663 isNonConstantComponent(ComponentRef.node(cref)) then
664 state := ERROR(NON_CONSTANT());
665 end if;
666 end checkCrefVariability;
667
668 function isNonConstantComponent
669 input InstNode node;
670 output Boolean res;
671 algorithm
672
4/4
✓ Branch 1 taken 108247 times.
✓ Branch 2 taken 167409 times.
✓ Branch 5 taken 108245 times.
✓ Branch 6 taken 2 times.
275656 res := InstNode.isComponent(node) and not Component.isConst(InstNode.component(node));
673 end isNonConstantComponent;
674 end LookupState;
675
676 annotation(__OpenModelica_Interface="nf_frontend");
677 end NFLookupState;
678