Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 48.9% 43 / 0 / 88
Functions: -% 0 / 1 / 1
Branches: 39.3% 11 / 0 / 28

OMCompiler/Compiler/FrontEnd/ClassInfUtil.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 ClassInfUtil
37 " file: ClassInfUtil.mo
38 package: ClassInfUtil
39 description: Class restrictions
40
41
42 This module deals with class inference, i.e. determining if a
43 class definition adhers to one of the class restrictions, and, if
44 specifically declared in a restrictied form, if it breaks that
45 restriction.
46
47 The inference is implemented as a finite state machine. The
48 function `start\' initializes a new machine, and the function
49 `trans\' signals transitions in the machine. Finally, the state
50 can be checked agains a restriction with the `valid\' function. "
51
52
53 import Absyn;
54 import ClassInf;
55 import SCode;
56
57 protected import Config;
58 protected import Debug;
59 protected import Error;
60 protected import Flags;
61 protected import Print;
62 protected import SCodeDump;
63 protected import SCodeUtil;
64
65 public function printStateStr "- Printing
66
67 Some functions for printing error and debug information about the
68 state machine.
69
70 The code is excluded from the report.
71 "
72 input ClassInf.State inState;
73 output String outString;
74 algorithm
75 outString:=
76 match inState
77 local
78 Boolean b1,b2;
79 case ClassInf.UNKNOWN() then "unknown";
80 case ClassInf.OPTIMIZATION() then "optimization";
81 case ClassInf.MODEL() then "model";
82 case ClassInf.RECORD() then "record";
83 case ClassInf.BLOCK() then "block";
84 case ClassInf.CONNECTOR() then "connector";
85 case ClassInf.TYPE() then "type";
86 case ClassInf.PACKAGE() then "package";
87 case ClassInf.FUNCTION(isImpure = true) then "impure function";
88 case ClassInf.FUNCTION() then "function";
89 case ClassInf.TYPE_INTEGER() then "Integer";
90 case ClassInf.TYPE_REAL() then "Real";
91 case ClassInf.TYPE_STRING() then "String";
92 case ClassInf.TYPE_BOOL() then "Boolean";
93 // BTH
94 case ClassInf.TYPE_CLOCK() then "Clock";
95 case ClassInf.HAS_RESTRICTIONS(hasEquations = false, hasAlgorithms = false, hasConstraints = false) then "new def";
96 case ClassInf.HAS_RESTRICTIONS(hasEquations = b1, hasAlgorithms = b2)
97 ✗ then "has" + (if b1 then " equations" else "") + (if b2 then " algorithms" else "") + (if b1 then " constraints" else "");
98 case ClassInf.EXTERNAL_OBJ() then "ExternalObject";
99 case ClassInf.META_TUPLE() then "tuple";
100 case ClassInf.META_LIST() then "list";
101 case ClassInf.META_OPTION() then "Option";
102 case ClassInf.META_RECORD() then "meta_record";
103 case ClassInf.META_POLYMORPHIC() then "polymorphic";
104 case ClassInf.META_ARRAY() then "meta_array";
105 case ClassInf.META_UNIONTYPE() then "uniontype";
106 else "#printStateStr failed#";
107 end match;
108 end printStateStr;
109
110 public function printState
111 input ClassInf.State inState;
112 algorithm
113 ():=
114 match inState
115 local Absyn.Path p;
116
117 case ClassInf.UNKNOWN(path = p)
118 algorithm
119 ✗ Print.printBuf("UNKNOWN ");
120 ✗ Print.printBuf(AbsynUtil.pathString(p));
121 then
122 ();
123 case ClassInf.OPTIMIZATION(path = p)
124 algorithm
125 ✗ Print.printBuf("OPTIMIZATION ");
126 ✗ Print.printBuf(AbsynUtil.pathString(p));
127 then
128 ();
129 case ClassInf.MODEL(path = p)
130 algorithm
131 ✗ Print.printBuf("MODEL ");
132 ✗ Print.printBuf(AbsynUtil.pathString(p));
133 then
134 ();
135 case ClassInf.RECORD(path = p)
136 algorithm
137 ✗ Print.printBuf("RECORD ");
138 ✗ Print.printBuf(AbsynUtil.pathString(p));
139 then
140 ();
141 case ClassInf.BLOCK(path = p)
142 algorithm
143 ✗ Print.printBuf("BLOCK ");
144 ✗ Print.printBuf(AbsynUtil.pathString(p));
145 then
146 ();
147 case ClassInf.CONNECTOR(path = p)
148 algorithm
149 ✗ Print.printBuf("CONNECTOR ");
150 ✗ Print.printBuf(AbsynUtil.pathString(p));
151 then
152 ();
153 case ClassInf.TYPE(path = p)
154 algorithm
155 ✗ Print.printBuf("TYPE ");
156 ✗ Print.printBuf(AbsynUtil.pathString(p));
157 then
158 ();
159 case ClassInf.PACKAGE(path = p)
160 algorithm
161 ✗ Print.printBuf("PACKAGE ");
162 ✗ Print.printBuf(AbsynUtil.pathString(p));
163 then
164 ();
165 case ClassInf.FUNCTION(path = p, isImpure = true)
166 algorithm
167 ✗ Print.printBuf("IMPURE FUNCTION ");
168 ✗ Print.printBuf(AbsynUtil.pathString(p));
169 then
170 ();
171 case ClassInf.FUNCTION(path = p)
172 algorithm
173 ✗ Print.printBuf("FUNCTION ");
174 ✗ Print.printBuf(AbsynUtil.pathString(p));
175 then
176 ();
177 case ClassInf.TYPE_INTEGER(path = p)
178 algorithm
179 ✗ Print.printBuf("TYPE_INTEGER ");
180 ✗ Print.printBuf(AbsynUtil.pathString(p));
181 then
182 ();
183 case ClassInf.TYPE_REAL(path = p)
184 algorithm
185 ✗ Print.printBuf("TYPE_REAL ");
186 ✗ Print.printBuf(AbsynUtil.pathString(p));
187 then
188 ();
189 case ClassInf.TYPE_STRING(path = p)
190 algorithm
191 ✗ Print.printBuf("TYPE_STRING ");
192 ✗ Print.printBuf(AbsynUtil.pathString(p));
193 then
194 ();
195 case ClassInf.TYPE_BOOL(path = p)
196 algorithm
197 ✗ Print.printBuf("TYPE_BOOL ");
198 ✗ Print.printBuf(AbsynUtil.pathString(p));
199 then
200 ();
201 // BTH
202 case ClassInf.TYPE_CLOCK(path = p)
203 algorithm
204 ✗ Print.printBuf("TYPE_CLOCK ");
205 ✗ Print.printBuf(AbsynUtil.pathString(p));
206 then
207 ();
208 case ClassInf.HAS_RESTRICTIONS(path = p)
209 algorithm
210 ✗ Print.printBuf("HAS_RESTRICTIONS ");
211 ✗ Print.printBuf(AbsynUtil.pathString(p));
212 ✗ Print.printBuf(printStateStr(inState));
213 then ();
214 end match;
215 end printState;
216
217 public function getStateName "Returns the classname of the state."
218 input ClassInf.State inState;
219 output Absyn.Path outPath;
220 algorithm
221 outPath := match inState
222 local
223 Absyn.Path p;
224 case ClassInf.UNKNOWN(path = p) then p;
225 case ClassInf.OPTIMIZATION(path = p) then p;
226 case ClassInf.MODEL(path = p) then p;
227 case ClassInf.RECORD(path = p) then p;
228 case ClassInf.BLOCK(path = p) then p;
229 case ClassInf.CONNECTOR(path = p) then p;
230 case ClassInf.TYPE(path = p) then p;
231 case ClassInf.PACKAGE(path = p) then p;
232 case ClassInf.FUNCTION(path = p) then p;
233 case ClassInf.ENUMERATION(path = p) then p;
234 case ClassInf.HAS_RESTRICTIONS(path = p) then p;
235 case ClassInf.TYPE_INTEGER(path = p) then p;
236 case ClassInf.TYPE_REAL(path = p) then p;
237 case ClassInf.TYPE_STRING(path = p) then p;
238 case ClassInf.TYPE_BOOL(path = p) then p;
239 // BTH
240 case ClassInf.TYPE_CLOCK(path = p) then p;
241 case ClassInf.TYPE_ENUM(path = p) then p;
242
243 case ClassInf.EXTERNAL_OBJ(p) then p;
244
245 case ClassInf.META_TUPLE(p) then p;
246 case ClassInf.META_LIST(p) then p;
247 case ClassInf.META_OPTION(p) then p;
248 case ClassInf.META_RECORD(p) then p;
249 case ClassInf.META_UNIONTYPE(p) then p;
250 case ClassInf.META_ARRAY(p) then p;
251 case ClassInf.META_POLYMORPHIC(p) then p;
252
253 else Absyn.IDENT("#getStateName failed#");
254 end match;
255 end getStateName;
256
257 protected function printEventStr
258 input ClassInf.Event inEvent;
259 output String str;
260 algorithm
261 str := match inEvent
262 local
263 String name;
264 case ClassInf.FOUND_EQUATION() then "equation";
265 case ClassInf.FOUND_CONSTRAINT() then "constraint";
266 case ClassInf.NEWDEF() then "new definition";
267 ✗ case ClassInf.FOUND_COMPONENT(name) then "component " + name;
268 case ClassInf.FOUND_EXT_DECL() then "external function declaration";
269 else "Unknown event";
270 end match;
271 end printEventStr;
272
273 public function start "
274 This is the state machine initialization function."
275 input SCode.Restriction inRestriction;
276 input Absyn.Path inPath;
277 output ClassInf.State outState;
278 algorithm
279 2826118 outState := start_dispatch(inRestriction, AbsynUtil.makeFullyQualified(inPath));
280 end start;
281
282 // Transitions
283 protected function start_dispatch "
284 This is the state machine initialization function."
285 input SCode.Restriction inRestriction;
286 input Absyn.Path inPath;
287 output ClassInf.State outState;
288 algorithm
289 outState:=
290 match (inRestriction,inPath)
291 local Absyn.Path p; Boolean isExpandable;
292 1568 case (SCode.R_CLASS(),p) then ClassInf.UNKNOWN(p);
293 13 case (SCode.R_OPTIMIZATION(),p) then ClassInf.OPTIMIZATION(p);
294 7929 case (SCode.R_MODEL(),p) then ClassInf.MODEL(p);
295 34984 case (SCode.R_RECORD(_),p) then ClassInf.RECORD(p);
296 1428 case (SCode.R_BLOCK(),p) then ClassInf.BLOCK(p);
297
2/2
✓ Branch 0 taken 14391 times.
✓ Branch 1 taken 168 times.
28950 case (SCode.R_CONNECTOR(isExpandable),p) then ClassInf.CONNECTOR(p,isExpandable);
298 462563 case (SCode.R_TYPE(),p) then ClassInf.TYPE(p);
299 1100590 case (SCode.R_PACKAGE(),p) then ClassInf.PACKAGE(p);
300
2/2
✓ Branch 1 taken 84162 times.
✓ Branch 2 taken 9832 times.
178156 case (SCode.R_FUNCTION(),p) then ClassInf.FUNCTION(p, SCodeUtil.isRestrictionImpure(inRestriction, true));
301 1138 case (SCode.R_OPERATOR(),p) then ClassInf.FUNCTION(p, false);
302 31272 case (SCode.R_ENUMERATION(),p) then ClassInf.ENUMERATION(p);
303 60129 case (SCode.R_PREDEFINED_INTEGER(),p) then ClassInf.TYPE_INTEGER(p);
304 637711 case (SCode.R_PREDEFINED_REAL(),p) then ClassInf.TYPE_REAL(p);
305 98471 case (SCode.R_PREDEFINED_STRING(),p) then ClassInf.TYPE_STRING(p);
306 93627 case (SCode.R_PREDEFINED_BOOLEAN(),p) then ClassInf.TYPE_BOOL(p);
307 // BTH
308 case (SCode.R_PREDEFINED_CLOCK(),p)
309 algorithm
310
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 184 times.
184 true := Config.synchronousFeaturesAllowed();
311 184 then ClassInf.TYPE_CLOCK(p);
312 48112 case (SCode.R_PREDEFINED_ENUMERATION(),p) then ClassInf.TYPE_ENUM(p);
313 /* Meta Modelica extensions */
314 137846 case (SCode.R_UNIONTYPE(),p) then ClassInf.META_UNIONTYPE(p, inRestriction.typeVars);
315 ✗ case (SCode.R_METARECORD(),p) then ClassInf.META_RECORD(p);
316 end match;
317 end start_dispatch;
318
319 public function trans "
320 This is the state machine transition function. It describes the
321 transitions between states at different events.
322 "
323 input ClassInf.State inState;
324 input ClassInf.Event inEvent;
325 output ClassInf.State outState;
326 algorithm
327 outState := match (inState,inEvent)
328 local
329 Absyn.Path p;
330 ClassInf.State st;
331 ClassInf.Event ev;
332 Boolean b1,b2,b3;
333 String s;
334 312 case (ClassInf.UNKNOWN(path = p),ClassInf.NEWDEF()) then ClassInf.HAS_RESTRICTIONS(p,false,false,false); /* Event `NEWDEF\' */
335 case (ClassInf.OPTIMIZATION(),ClassInf.NEWDEF()) then inState;
336 case (ClassInf.MODEL(),ClassInf.NEWDEF()) then inState;
337 case (ClassInf.RECORD(),ClassInf.NEWDEF()) then inState;
338 case (ClassInf.BLOCK(),ClassInf.NEWDEF()) then inState;
339 case (ClassInf.CONNECTOR(),ClassInf.NEWDEF()) then inState;
340 7065 case (ClassInf.TYPE(path = p),ClassInf.NEWDEF()) then ClassInf.TYPE(p); // A type can be constructed with long definition
341 38422 case (ClassInf.PACKAGE(path = p),ClassInf.NEWDEF()) then ClassInf.PACKAGE(p);
342 case (ClassInf.FUNCTION(),ClassInf.NEWDEF()) then inState;
343 case (ClassInf.ENUMERATION(),ClassInf.NEWDEF()) then inState;
344 case (ClassInf.TYPE_INTEGER(),ClassInf.NEWDEF()) then inState;
345 case (ClassInf.TYPE_REAL(),ClassInf.NEWDEF()) then inState;
346 case (ClassInf.TYPE_STRING(),ClassInf.NEWDEF()) then inState;
347 case (ClassInf.TYPE_BOOL(),ClassInf.NEWDEF()) then inState;
348 // BTH
349 case (ClassInf.TYPE_CLOCK(),ClassInf.NEWDEF()) then inState;
350 case (ClassInf.TYPE_ENUM(),ClassInf.NEWDEF()) then inState;
351 case (ClassInf.META_UNIONTYPE(),ClassInf.NEWDEF()) then inState; // Added 2009-05-11. sjoelund
352 case (ClassInf.META_RECORD(),ClassInf.NEWDEF()) then inState; // Added 2009-08-18. sjoelund
353
354 /* Event 'FOUND_COMPONENT' */
355 ✗ case (ClassInf.UNKNOWN(path = p),ClassInf.FOUND_COMPONENT()) then ClassInf.HAS_RESTRICTIONS(p,false,false,false); /* Event `NEWDEF\' */
356 case (ClassInf.OPTIMIZATION(),ClassInf.FOUND_COMPONENT()) then inState;
357 case (ClassInf.MODEL(),ClassInf.FOUND_COMPONENT()) then inState;
358 case (ClassInf.RECORD(),ClassInf.FOUND_COMPONENT()) then inState;
359 case (ClassInf.BLOCK(),ClassInf.FOUND_COMPONENT()) then inState;
360 case (ClassInf.CONNECTOR(),ClassInf.FOUND_COMPONENT()) then inState;
361 case (ClassInf.TYPE(path = p),ClassInf.FOUND_COMPONENT(name = s)) // A type can not contain new components
362 algorithm
363
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 if not isBasicTypeComponentName(s) then
364 2 Error.addMessage(Error.TYPE_NOT_FROM_PREDEFINED, {AbsynUtil.pathString(p)});
365 1 fail();
366 end if;
367 ✗ then ClassInf.TYPE(p);
368 /* adrpo 2009-05-15: type Orientation can contain equalityConstraint function! */
369 //case (ClassInf.TYPE(path = p),ClassInf.FOUND_COMPONENT()) then ClassInf.TYPE(p);
370 case (ClassInf.PACKAGE(),ClassInf.FOUND_COMPONENT()) then inState;
371 case (ClassInf.FUNCTION(),ClassInf.FOUND_COMPONENT()) then inState;
372 case (ClassInf.ENUMERATION(),ClassInf.FOUND_COMPONENT()) then inState;
373 case (ClassInf.HAS_RESTRICTIONS(),ClassInf.FOUND_COMPONENT()) then inState;
374 case (ClassInf.TYPE_INTEGER(),ClassInf.FOUND_COMPONENT()) then inState;
375 case (ClassInf.TYPE_REAL(),ClassInf.FOUND_COMPONENT()) then inState;
376 case (ClassInf.TYPE_STRING(),ClassInf.FOUND_COMPONENT()) then inState;
377 case (ClassInf.TYPE_BOOL(),ClassInf.FOUND_COMPONENT()) then inState;
378 case (ClassInf.TYPE_CLOCK(),ClassInf.FOUND_COMPONENT()) then inState;
379 case (ClassInf.TYPE_ENUM(),ClassInf.FOUND_COMPONENT()) then inState;
380 case (ClassInf.META_RECORD(),ClassInf.FOUND_COMPONENT()) then inState; // Added 2009-08-19. sjoelund
381 case (ClassInf.META_UNIONTYPE(), ClassInf.FOUND_COMPONENT()) then inState;
382
383 /* Event `FOUND_EQUATION\' */
384 ✗ case (ClassInf.UNKNOWN(path = p),ClassInf.FOUND_EQUATION()) then ClassInf.HAS_RESTRICTIONS(p,true,false,false);
385 case (ClassInf.OPTIMIZATION(),ClassInf.FOUND_EQUATION()) then inState;
386 case (ClassInf.OPTIMIZATION(),ClassInf.FOUND_CONSTRAINT()) then inState;
387 case (ClassInf.OPTIMIZATION(),ClassInf.FOUND_ALGORITHM()) then inState;
388
389 case (ClassInf.MODEL(),ClassInf.FOUND_EQUATION()) then inState;
390 case (ClassInf.BLOCK(),ClassInf.FOUND_EQUATION()) then inState;
391
392 case (ClassInf.MODEL(),ClassInf.FOUND_ALGORITHM()) then inState;
393 case (ClassInf.BLOCK(),ClassInf.FOUND_ALGORITHM()) then inState;
394 case (ClassInf.FUNCTION(),ClassInf.FOUND_ALGORITHM()) then inState;
395
396
2/4
✓ Branch 0 taken 376 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 376 times.
✗ Branch 3 not taken.
1128 case (ClassInf.HAS_RESTRICTIONS(path=p,hasAlgorithms=b2,hasConstraints=b3),ClassInf.FOUND_EQUATION()) then ClassInf.HAS_RESTRICTIONS(p,true,b2,b3);
397 ✗ case (ClassInf.HAS_RESTRICTIONS(path=p,hasEquations=b1,hasAlgorithms=b2),ClassInf.FOUND_CONSTRAINT()) then ClassInf.HAS_RESTRICTIONS(p,b1,b2,true);
398
3/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 6 times.
33 case (ClassInf.HAS_RESTRICTIONS(path=p,hasEquations=b1,hasConstraints=b3),ClassInf.FOUND_ALGORITHM()) then ClassInf.HAS_RESTRICTIONS(p,b1,true,b3);
399
400 case (ClassInf.FUNCTION(),ClassInf.FOUND_EXT_DECL()) then inState;
401 1 case (_,ClassInf.FOUND_EXT_DECL()) then fail();
402
403 2 case (_,ClassInf.FOUND_EQUATION()) then fail();
404 ✗ case (_,ClassInf.FOUND_CONSTRAINT()) then fail();
405
406 case (st,ev)
407 algorithm
408 ✗ true := Flags.isSet(Flags.FAILTRACE);
409 ✗ Debug.traceln("- ClassInfUtil.trans failed: " + printStateStr(st) + ", " + printEventStr(ev));
410 ✗ then
411 fail();
412 end match;
413 end trans;
414
415 public function valid "
416 This is the validity function which determines if a state is valid
417 according to one of the restrictions. This means, that if a class
418 definition is to be used as, say, a connector, the state of the
419 state machine is checked against the `SCode.R_CONNECTOR\'
420 restriction using this function to find out if it is an error to
421 use this class definition as a connector.
422 "
423 input ClassInf.State inState;
424 input SCode.Restriction inRestriction;
425 algorithm
426 () := match (inState,inRestriction)
427 local
428 case (ClassInf.UNKNOWN(),_) then ();
429
430 case (ClassInf.HAS_RESTRICTIONS(),SCode.R_CLASS()) then ();
431 case (ClassInf.HAS_RESTRICTIONS(),SCode.R_MODEL()) then ();
432 case (ClassInf.HAS_RESTRICTIONS(),SCode.R_OPTIMIZATION()) then ();
433 case (ClassInf.MODEL(),SCode.R_MODEL()) then ();
434
435
436 case (ClassInf.RECORD(),SCode.R_RECORD(_)) then ();
437 case (ClassInf.RECORD(),SCode.R_CONNECTOR(_)) then ();
438 case (ClassInf.HAS_RESTRICTIONS(hasEquations=false,hasConstraints=false,hasAlgorithms=false),SCode.R_RECORD(_)) then ();
439
440 case (ClassInf.BLOCK(),SCode.R_BLOCK()) then ();
441 case (ClassInf.MODEL(),SCode.R_MODEL()) then ();
442
443 case (ClassInf.CONNECTOR(),SCode.R_TYPE()) then ();
444 case (ClassInf.CONNECTOR(isExpandable=false),SCode.R_CONNECTOR(false)) then ();
445 case (ClassInf.CONNECTOR(isExpandable=true),SCode.R_CONNECTOR(true)) then ();
446 case (ClassInf.HAS_RESTRICTIONS(hasEquations=false,hasConstraints=false,hasAlgorithms=false),SCode.R_CONNECTOR(_)) then ();
447 case (ClassInf.TYPE_INTEGER(),SCode.R_CONNECTOR(_)) then ();
448 case (ClassInf.TYPE_REAL(),SCode.R_CONNECTOR(_)) then ();
449 case (ClassInf.TYPE_STRING(),SCode.R_CONNECTOR(_)) then ();
450 case (ClassInf.TYPE_BOOL(),SCode.R_CONNECTOR(_)) then ();
451 // BTH
452 case (ClassInf.TYPE_CLOCK(),SCode.R_CONNECTOR(_)) then ();
453 case (ClassInf.TYPE_ENUM(),SCode.R_CONNECTOR(_)) then (); // used in Modelica.Electrical.Digital where we have an enum as a connector
454 case (ClassInf.ENUMERATION(),SCode.R_CONNECTOR(_)) then (); // used in Modelica.Electrical.Digital where we have an enum as a connector
455 case (ClassInf.TYPE(),SCode.R_CONNECTOR()) then (); // Note: Only allowed in some cases (outputs, etc). Happens when the base class is type T extends Real; end T;
456
457 case (ClassInf.TYPE(),SCode.R_TYPE()) then ();
458 case (ClassInf.TYPE_INTEGER(),SCode.R_TYPE()) then ();
459 case (ClassInf.TYPE_REAL(),SCode.R_TYPE()) then ();
460 case (ClassInf.TYPE_STRING(),SCode.R_TYPE()) then ();
461 case (ClassInf.TYPE_BOOL(),SCode.R_TYPE()) then ();
462 // BTH
463 case (ClassInf.TYPE_CLOCK(),SCode.R_TYPE()) then ();
464 case (ClassInf.TYPE_ENUM(),SCode.R_TYPE()) then ();
465 case (ClassInf.ENUMERATION(),SCode.R_TYPE()) then ();
466
467 case (ClassInf.PACKAGE(),SCode.R_PACKAGE()) then ();
468 case (ClassInf.HAS_RESTRICTIONS(hasEquations=false,hasConstraints=false,hasAlgorithms=false),SCode.R_PACKAGE()) then ();
469
470 case (ClassInf.FUNCTION(),SCode.R_FUNCTION(_)) then ();
471 case (ClassInf.HAS_RESTRICTIONS(hasEquations=false,hasConstraints=false),SCode.R_FUNCTION(_)) then ();
472 case (ClassInf.META_TUPLE(),SCode.R_TYPE()) then ();
473 case (ClassInf.META_LIST(),SCode.R_TYPE()) then ();
474 case (ClassInf.META_OPTION(),SCode.R_TYPE()) then ();
475 case (ClassInf.META_RECORD(),SCode.R_TYPE()) then ();
476 case (ClassInf.META_ARRAY(),SCode.R_TYPE()) then ();
477 case (ClassInf.META_UNIONTYPE(),SCode.R_TYPE()) then ();
478
479 end match;
480 end valid;
481
482 public function assertValid "This function has the same semantical meaning as the function
483 `valid\'. However, it prints an error message when it fails."
484 input ClassInf.State inState;
485 input SCode.Restriction inRestriction;
486 input SourceInfo info;
487 algorithm
488 () := matchcontinue (inState, inRestriction)
489 local
490 ClassInf.State st;
491 SCode.Restriction re;
492 String str1,str2,str3;
493 case (st, re)
494 algorithm
495 205473 valid(st, re);
496 then
497 ();
498 case (st, re)
499 algorithm
500 3 str1 := AbsynUtil.pathString(getStateName(st));
501 3 str2 := printStateStr(st);
502 3 str3 := SCodeDump.restrictionStringPP(re);
503 3 Error.addSourceMessage(Error.RESTRICTION_VIOLATION, {str1,str2,str3}, info);
504 3 then
505 fail();
506 end matchcontinue;
507 end assertValid;
508
509 public function assertTrans "This function has the same semantical meaning as the function
510 `trans\'. However, it prints an error message when it fails."
511 input ClassInf.State inState;
512 input ClassInf.Event event;
513 input SourceInfo info;
514 output ClassInf.State outState;
515 algorithm
516 outState := matchcontinue inState
517 local
518 ClassInf.State st;
519 String str1,str2,str3;
520 case st
521 64023 then trans(st, event);
522 case st
523 algorithm
524 1 str1 := AbsynUtil.pathString(getStateName(st));
525 1 str2 := printStateStr(st);
526 1 str3 := printEventStr(event);
527 1 Error.addSourceMessage(Error.TRANS_VIOLATION, {str1,str2,str3}, info);
528 1 then
529 fail();
530 end matchcontinue;
531 end assertTrans;
532
533 public function matchingState "
534 Finds a State in the list that matches the state given as first argument.
535 NOTE: Currently not used anywhere.
536 "
537 input ClassInf.State inState;
538 input list<ClassInf.State> inStateLst;
539 output Boolean outBoolean;
540 algorithm
541 outBoolean:=
542 match (inState,inStateLst)
543 local
544 list<ClassInf.State> rest;
545 Boolean res;
546 case (_,{}) then false;
547 case (ClassInf.UNKNOWN(),(ClassInf.UNKNOWN() :: _)) then true;
548 case (ClassInf.MODEL(),(ClassInf.MODEL() :: _)) then true;
549 case (ClassInf.RECORD(),(ClassInf.RECORD() :: _)) then true;
550 case (ClassInf.BLOCK(),(ClassInf.BLOCK() :: _)) then true;
551 case (ClassInf.CONNECTOR(),(ClassInf.CONNECTOR() :: _)) then true;
552 case (ClassInf.TYPE(),(ClassInf.TYPE() :: _)) then true;
553 case (ClassInf.PACKAGE(),(ClassInf.PACKAGE() :: _)) then true;
554 case (ClassInf.FUNCTION(),(ClassInf.FUNCTION() :: _)) then true;
555 case (ClassInf.ENUMERATION(),(ClassInf.ENUMERATION() :: _)) then true;
556 case (ClassInf.TYPE_INTEGER(),(ClassInf.TYPE_INTEGER() :: _)) then true;
557 case (ClassInf.TYPE_REAL(),(ClassInf.TYPE_REAL() :: _)) then true;
558 case (ClassInf.TYPE_STRING(),(ClassInf.TYPE_STRING() :: _)) then true;
559 case (ClassInf.TYPE_BOOL(),(ClassInf.TYPE_BOOL() :: _)) then true;
560 // BTH
561 case (ClassInf.TYPE_CLOCK(),(ClassInf.TYPE_CLOCK() :: _)) then true;
562 case (ClassInf.TYPE_ENUM(),(ClassInf.TYPE_ENUM() :: _)) then true;
563 case (_,(_ :: rest))
564 algorithm
565 ✗ res := matchingState(inState, rest);
566 then
567 res;
568 end match;
569 end matchingState;
570
571 public function isFunction
572 "returns true if state is FUNCTION."
573 input ClassInf.State inState;
574 output Boolean b;
575 algorithm
576 b := match inState
577 case ClassInf.FUNCTION() then true;
578 else false;
579 end match;
580 end isFunction;
581
582 public function isFunctionOrRecord "Fails for states that are not FUNCTION or RECORD."
583 input ClassInf.State inState;
584 output Boolean b;
585 algorithm
586 b := match inState
587 case ClassInf.FUNCTION() then true;
588 case ClassInf.RECORD() then true;
589 else false;
590 end match;
591 end isFunctionOrRecord;
592
593 public function isConnector "
594 Fails for states that are not CONNECTOR.
595 "
596 input ClassInf.State inState;
597 algorithm
598 ():=
599 match inState
600 case ClassInf.CONNECTOR() then ();
601 end match;
602 end isConnector;
603
604 protected constant list<String> basicTypeMods = {
605 "quantity",
606 "unit",
607 "displayUnit",
608 "min",
609 "max",
610 "start",
611 "fixed",
612 "nominal",
613 "stateSelect",
614 "uncertain", // extension for uncertainties
615 "distribution" // extension for uncertainties
616 };
617
618 public function isBasicTypeComponentName
619 "Returns true if the name can be a component of a builtin type"
620 input String name;
621 output Boolean res;
622 algorithm
623 30 res := listMember(name,basicTypeMods);
624 end isBasicTypeComponentName;
625
626 public function isTypeOrRecord
627 input ClassInf.State inState;
628 output Boolean outIsTypeOrRecord;
629 algorithm
630 outIsTypeOrRecord := match inState
631 case ClassInf.TYPE() then true;
632 case ClassInf.RECORD() then true;
633 else false;
634 end match;
635 end isTypeOrRecord;
636
637 public function isRecord
638 input ClassInf.State inState;
639 output Boolean outIsRecord;
640 algorithm
641 outIsRecord := match inState
642 case ClassInf.RECORD() then true;
643 else false;
644 end match;
645 end isRecord;
646
647 public function isMetaRecord
648 input ClassInf.State inState;
649 output Boolean outIsRecord;
650 algorithm
651 outIsRecord := match inState
652 case ClassInf.META_RECORD() then true;
653 else false;
654 end match;
655 end isMetaRecord;
656
657 annotation(__OpenModelica_Interface="frontend_dump");
658 end ClassInfUtil;
659