OMCompiler/Compiler/NFFrontEnd/NFComponent.mo
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of OpenModelica. | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), | ||
| 5 | * c/o Linköpings universitet, Department of Computer and Information Science, | ||
| 6 | * SE-58183 Linköping, Sweden. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR | ||
| 11 | * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. | ||
| 12 | * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES | ||
| 13 | * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL | ||
| 14 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 15 | * | ||
| 16 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) | ||
| 17 | * Public License (OSMC-PL) are obtained from OSMC, either from the above | ||
| 18 | * address, from the URLs: | ||
| 19 | * http://www.openmodelica.org or | ||
| 20 | * https://github.com/OpenModelica/ or | ||
| 21 | * http://www.ida.liu.se/projects/OpenModelica, | ||
| 22 | * and in the OpenModelica distribution. | ||
| 23 | * | ||
| 24 | * GNU AGPL version 3 is obtained from: | ||
| 25 | * https://www.gnu.org/licenses/licenses.html#GPL | ||
| 26 | * | ||
| 27 | * This program is distributed WITHOUT ANY WARRANTY; without | ||
| 28 | * even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 29 | * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH | ||
| 30 | * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. | ||
| 31 | * | ||
| 32 | * See the full OSMC Public License conditions for more details. | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | encapsulated uniontype NFComponent | ||
| 37 | |||
| 38 | import BaseModelica; | ||
| 39 | import Binding = NFBinding; | ||
| 40 | import Class = NFClass; | ||
| 41 | import NFClassTree.ClassTree; | ||
| 42 | import Dimension = NFDimension; | ||
| 43 | import NFInstNode.InstNode; | ||
| 44 | import NFModifier.Modifier; | ||
| 45 | import SCode.Element; | ||
| 46 | import SCode; | ||
| 47 | import Type = NFType; | ||
| 48 | import Expression = NFExpression; | ||
| 49 | import NFPrefixes.*; | ||
| 50 | import Attributes = NFAttributes; | ||
| 51 | |||
| 52 | protected | ||
| 53 | import Prefixes = NFPrefixes; | ||
| 54 | import SCodeUtil; | ||
| 55 | import Restriction = NFRestriction; | ||
| 56 | import Component = NFComponent; | ||
| 57 | import IOStream; | ||
| 58 | import NFFunction.Function; | ||
| 59 | |||
| 60 | public | ||
| 61 | type ComponentState = enumeration( | ||
| 62 | PartiallyInstantiated "Component instance has been created", | ||
| 63 | FullyInstantiated "All component expressions have been instantiated", | ||
| 64 | Typed "The component's type has been determined", | ||
| 65 | TypeChecked "The component's binding has been typed and type checked" | ||
| 66 | ); | ||
| 67 | |||
| 68 | record COMPONENT_DEF | ||
| 69 | SCode.Element definition; | ||
| 70 | Modifier modifier; | ||
| 71 | end COMPONENT_DEF; | ||
| 72 | |||
| 73 | record COMPONENT | ||
| 74 | InstNode classInst; | ||
| 75 | Type ty; | ||
| 76 | Binding binding; | ||
| 77 | Binding condition; | ||
| 78 | Attributes attributes; | ||
| 79 | SCode.Comment comment; | ||
| 80 | ComponentState state; | ||
| 81 | SourceInfo info; | ||
| 82 | end COMPONENT; | ||
| 83 | |||
| 84 | record ITERATOR | ||
| 85 | Type ty; | ||
| 86 | Variability variability; | ||
| 87 | SourceInfo info; | ||
| 88 | end ITERATOR; | ||
| 89 | |||
| 90 | record ENUM_LITERAL | ||
| 91 | Expression literal; | ||
| 92 | SCode.Comment comment; | ||
| 93 | end ENUM_LITERAL; | ||
| 94 | |||
| 95 | record TYPE_ATTRIBUTE | ||
| 96 | Type ty; | ||
| 97 | Modifier modifier; | ||
| 98 | end TYPE_ATTRIBUTE; | ||
| 99 | |||
| 100 | record INVALID_COMPONENT | ||
| 101 | Component component; | ||
| 102 | String errors; | ||
| 103 | end INVALID_COMPONENT; | ||
| 104 | |||
| 105 | record WILD "needed for new crefs in the backend" end WILD; | ||
| 106 | |||
| 107 | function new | ||
| 108 | input SCode.Element definition; | ||
| 109 | output Component component; | ||
| 110 | algorithm | ||
| 111 | 269741 | component := COMPONENT_DEF(definition, Modifier.NOMOD()); | |
| 112 | end new; | ||
| 113 | |||
| 114 | function newEnum | ||
| 115 | input Type enumType; | ||
| 116 | input String literalName; | ||
| 117 | input SCode.Comment comment; | ||
| 118 | input Integer literalIndex; | ||
| 119 | output Component component; | ||
| 120 | algorithm | ||
| 121 | 4468 | component := ENUM_LITERAL(Expression.ENUM_LITERAL(enumType, literalName, literalIndex), comment); | |
| 122 | end newEnum; | ||
| 123 | |||
| 124 | function newIterator | ||
| 125 | input Type iterType; | ||
| 126 | input SourceInfo info; | ||
| 127 | output Component component; | ||
| 128 | algorithm | ||
| 129 | 6389 | component := ITERATOR(iterType, Variability.IMPLICITLY_DISCRETE, info); | |
| 130 | end newIterator; | ||
| 131 | |||
| 132 | function definition | ||
| 133 | input Component component; | ||
| 134 | output SCode.Element definition; | ||
| 135 | algorithm | ||
| 136 | ✗ | COMPONENT_DEF(definition = definition) := component; | |
| 137 | end definition; | ||
| 138 | |||
| 139 | function isDefinition | ||
| 140 | input Component component; | ||
| 141 | output Boolean isDefinition; | ||
| 142 | algorithm | ||
| 143 | isDefinition := match component | ||
| 144 | case COMPONENT_DEF() then true; | ||
| 145 | else false; | ||
| 146 | end match; | ||
| 147 | end isDefinition; | ||
| 148 | |||
| 149 | function info | ||
| 150 | "This function shouldn't be used! Use InstNode.info instead, so that e.g. | ||
| 151 | enumeration literals can be handled correctly." | ||
| 152 | input Component component; | ||
| 153 | output SourceInfo info; | ||
| 154 | algorithm | ||
| 155 | info := match component | ||
| 156 | 39 | case COMPONENT_DEF() then SCodeUtil.elementInfo(component.definition); | |
| 157 | 665577 | case COMPONENT() then component.info; | |
| 158 | 3242 | case ITERATOR() then component.info; | |
| 159 | ✗ | case TYPE_ATTRIBUTE() then Modifier.info(component.modifier); | |
| 160 | // Fail for enumeration literals, InstNode.info handles that case instead. | ||
| 161 | end match; | ||
| 162 | end info; | ||
| 163 | |||
| 164 | function classInstance | ||
| 165 | input Component component; | ||
| 166 | output InstNode classInst; | ||
| 167 | algorithm | ||
| 168 | classInst := match component | ||
| 169 | 4494809 | case COMPONENT() then component.classInst; | |
| 170 | 1 | case ITERATOR(ty = Type.COMPLEX()) then Type.complexNode(component.ty); | |
| 171 | 3562 | case ITERATOR() then InstNode.ITERATOR_NODE(Expression.EMPTY(component.ty)); | |
| 172 | else InstNode.EMPTY_NODE(); | ||
| 173 | end match; | ||
| 174 | end classInstance; | ||
| 175 | |||
| 176 | function setClassInstance | ||
| 177 | input InstNode classInst; | ||
| 178 | input output Component component; | ||
| 179 | algorithm | ||
| 180 | () := match component | ||
| 181 | case COMPONENT() | ||
| 182 | algorithm | ||
| 183 | 1648968 | component.classInst := classInst; | |
| 184 | then | ||
| 185 | (); | ||
| 186 | |||
| 187 | end match; | ||
| 188 | end setClassInstance; | ||
| 189 | |||
| 190 | function getModifier | ||
| 191 | input Component component; | ||
| 192 | output Modifier modifier; | ||
| 193 | algorithm | ||
| 194 | modifier := match component | ||
| 195 | 5557 | case COMPONENT_DEF() then component.modifier; | |
| 196 | 2973339 | case TYPE_ATTRIBUTE() then component.modifier; | |
| 197 | else Modifier.NOMOD(); | ||
| 198 | end match; | ||
| 199 | end getModifier; | ||
| 200 | |||
| 201 | function setModifier | ||
| 202 | input Modifier modifier; | ||
| 203 | input output Component component; | ||
| 204 | algorithm | ||
| 205 | () := match component | ||
| 206 | case COMPONENT_DEF() | ||
| 207 | algorithm | ||
| 208 | ✗ | component.modifier := modifier; | |
| 209 | then | ||
| 210 | (); | ||
| 211 | case TYPE_ATTRIBUTE() | ||
| 212 | algorithm | ||
| 213 | ✗ | component.modifier := modifier; | |
| 214 | then | ||
| 215 | (); | ||
| 216 | end match; | ||
| 217 | end setModifier; | ||
| 218 | |||
| 219 | function mergeModifier | ||
| 220 | input Modifier modifier; | ||
| 221 | input output Component component; | ||
| 222 | algorithm | ||
| 223 | component := match component | ||
| 224 | case COMPONENT_DEF() | ||
| 225 | algorithm | ||
| 226 | 449244 | component.modifier := Modifier.merge(modifier, component.modifier); | |
| 227 | then | ||
| 228 | component; | ||
| 229 | |||
| 230 | case TYPE_ATTRIBUTE() | ||
| 231 | 1378677 | then TYPE_ATTRIBUTE(component.ty, Modifier.merge(modifier, component.modifier)); | |
| 232 | end match; | ||
| 233 | end mergeModifier; | ||
| 234 | |||
| 235 | function getType | ||
| 236 | input Component component; | ||
| 237 | output Type ty; | ||
| 238 | protected | ||
| 239 | Type t; | ||
| 240 | algorithm | ||
| 241 | ty := match component | ||
| 242 | case COMPONENT(ty = t as Type.UNTYPED()) | ||
| 243 | 677709 | then Type.liftArrayLeftList(InstNode.getType(component.classInst), arrayList(t.dimensions)); | |
| 244 | 1944105 | case COMPONENT() then component.ty; | |
| 245 | 5452 | case ITERATOR() then component.ty; | |
| 246 | ✗ | case TYPE_ATTRIBUTE() then component.ty; | |
| 247 | ✗ | case INVALID_COMPONENT() then getType(component.component); | |
| 248 | else Type.UNKNOWN(); | ||
| 249 | end match; | ||
| 250 | end getType; | ||
| 251 | |||
| 252 | function setType | ||
| 253 | input Type ty; | ||
| 254 | input output Component component; | ||
| 255 | algorithm | ||
| 256 | component := match component | ||
| 257 | case COMPONENT() | ||
| 258 | algorithm | ||
| 259 | 956559 | component.ty := ty; | |
| 260 | then | ||
| 261 | component; | ||
| 262 | |||
| 263 | case ITERATOR() | ||
| 264 | algorithm | ||
| 265 | ✗ | component.ty := ty; | |
| 266 | then | ||
| 267 | component; | ||
| 268 | |||
| 269 | end match; | ||
| 270 | end setType; | ||
| 271 | |||
| 272 | function isTyped | ||
| 273 | input Component component; | ||
| 274 | output Boolean isTyped; | ||
| 275 | algorithm | ||
| 276 | isTyped := match component | ||
| 277 | 9246 | case COMPONENT() then component.state >= ComponentState.Typed; | |
| 278 | case ITERATOR(ty = Type.UNKNOWN()) then false; | ||
| 279 | case ITERATOR() then true; | ||
| 280 | case TYPE_ATTRIBUTE() then true; | ||
| 281 | else false; | ||
| 282 | end match; | ||
| 283 | end isTyped; | ||
| 284 | |||
| 285 | function unliftType | ||
| 286 | input output Component component; | ||
| 287 | algorithm | ||
| 288 | () := match component | ||
| 289 | local | ||
| 290 | Type ty; | ||
| 291 | |||
| 292 | case COMPONENT(ty = Type.ARRAY(elementType = ty)) | ||
| 293 | algorithm | ||
| 294 | ✗ | component.ty := ty; | |
| 295 | then | ||
| 296 | (); | ||
| 297 | |||
| 298 | case ITERATOR(ty = Type.ARRAY(elementType = ty)) | ||
| 299 | algorithm | ||
| 300 | ✗ | component.ty := ty; | |
| 301 | then | ||
| 302 | (); | ||
| 303 | |||
| 304 | else (); | ||
| 305 | end match; | ||
| 306 | end unliftType; | ||
| 307 | |||
| 308 | function getAttributes | ||
| 309 | input Component component; | ||
| 310 | output Attributes attr; | ||
| 311 | algorithm | ||
| 312 | attr := match component | ||
| 313 | 201909 | case COMPONENT() then component.attributes; | |
| 314 | else NFAttributes.DEFAULT_ATTR; | ||
| 315 | end match; | ||
| 316 | end getAttributes; | ||
| 317 | |||
| 318 | function setAttributes | ||
| 319 | input Attributes attr; | ||
| 320 | input output Component component; | ||
| 321 | algorithm | ||
| 322 | () := match component | ||
| 323 | case COMPONENT() | ||
| 324 | algorithm | ||
| 325 | 101790 | component.attributes := attr; | |
| 326 | then | ||
| 327 | (); | ||
| 328 | end match; | ||
| 329 | end setAttributes; | ||
| 330 | |||
| 331 | function setComment | ||
| 332 | input SCode.Comment comment; | ||
| 333 | input output Component component; | ||
| 334 | algorithm | ||
| 335 | () := match component | ||
| 336 | case COMPONENT() | ||
| 337 | algorithm | ||
| 338 | 66 | component.comment := comment; | |
| 339 | then | ||
| 340 | (); | ||
| 341 | end match; | ||
| 342 | end setComment; | ||
| 343 | |||
| 344 | function getBinding | ||
| 345 | input Component component; | ||
| 346 | output Binding b; | ||
| 347 | algorithm | ||
| 348 | b := match component | ||
| 349 | 2779593 | case COMPONENT() then component.binding; | |
| 350 | 12503728 | case TYPE_ATTRIBUTE() then Modifier.binding(component.modifier); | |
| 351 | case WILD() then Binding.WILD(); | ||
| 352 | else NFBinding.EMPTY_BINDING; | ||
| 353 | end match; | ||
| 354 | end getBinding; | ||
| 355 | |||
| 356 | function getImplicitBinding | ||
| 357 | "Returns the component's binding. If the component does not have a binding | ||
| 358 | and is a record instance it will try to create a binding from the | ||
| 359 | component's children." | ||
| 360 | input Component component; | ||
| 361 | input InstNode scope; | ||
| 362 | output Binding binding; | ||
| 363 | protected | ||
| 364 | InstNode cls_node; | ||
| 365 | Expression record_exp; | ||
| 366 | algorithm | ||
| 367 | 100835 | binding := getBinding(component); | |
| 368 | |||
| 369 |
2/2✓ Branch 1 taken 66940 times.
✓ Branch 2 taken 33895 times.
|
100835 | if Binding.isUnbound(binding) then |
| 370 | 66940 | cls_node := classInstance(component); | |
| 371 | |||
| 372 |
2/2✓ Branch 1 taken 57715 times.
✓ Branch 2 taken 9225 times.
|
66940 | if InstNode.isRecord(cls_node) then |
| 373 | try | ||
| 374 |
2/2✓ Branch 1 taken 141 times.
✓ Branch 2 taken 9084 times.
|
9225 | if isTyped(component) then |
| 375 | 141 | record_exp := Class.makeRecordExp(cls_node, scope, typed = true); | |
| 376 | 66 | binding := Binding.makeTyped(record_exp, NFBinding.EachType.NOT_EACH, | |
| 377 | NFBinding.Source.GENERATED, info(component)); | ||
| 378 | else | ||
| 379 | 9084 | record_exp := Class.makeRecordExp(cls_node, scope, typed = false); | |
| 380 | 607 | binding := Binding.makeUntyped(record_exp, scope, NFBinding.EachType.NOT_EACH, | |
| 381 | NFBinding.Source.GENERATED, info(component)); | ||
| 382 | end if; | ||
| 383 | else | ||
| 384 | end try; | ||
| 385 | end if; | ||
| 386 | end if; | ||
| 387 | end getImplicitBinding; | ||
| 388 | |||
| 389 | function getTypeAttributeBinding | ||
| 390 | input Component component; | ||
| 391 | input String attrName; | ||
| 392 | output Binding binding; | ||
| 393 | protected | ||
| 394 | InstNode start_node; | ||
| 395 | Component start_comp; | ||
| 396 | algorithm | ||
| 397 | try | ||
| 398 | 25227 | start_node := Class.lookupElement(attrName, InstNode.getClass(classInstance(component))); | |
| 399 | 25216 | start_comp := InstNode.component(start_node); | |
| 400 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 25216 times.
|
25216 | true := Component.isTypeAttribute(start_comp); |
| 401 | 25216 | binding := Component.getBinding(start_comp); | |
| 402 | else | ||
| 403 | binding := NFBinding.EMPTY_BINDING; | ||
| 404 | end try; | ||
| 405 | end getTypeAttributeBinding; | ||
| 406 | |||
| 407 | function setBinding | ||
| 408 | input Binding binding; | ||
| 409 | input output Component component; | ||
| 410 | algorithm | ||
| 411 | () := match component | ||
| 412 | case COMPONENT() | ||
| 413 | algorithm | ||
| 414 | 49098 | component.binding := binding; | |
| 415 | then | ||
| 416 | (); | ||
| 417 | |||
| 418 | case TYPE_ATTRIBUTE() | ||
| 419 | algorithm | ||
| 420 | 41847 | component.modifier := Modifier.setBinding(binding, component.modifier); | |
| 421 | then | ||
| 422 | (); | ||
| 423 | end match; | ||
| 424 | end setBinding; | ||
| 425 | |||
| 426 | function hasBinding | ||
| 427 | input Component component; | ||
| 428 | input InstNode parent = InstNode.EMPTY_NODE(); | ||
| 429 | output Boolean b; | ||
| 430 | protected | ||
| 431 | Class cls; | ||
| 432 | |||
| 433 | function has_missing_binding | ||
| 434 | input InstNode component; | ||
| 435 | output Boolean noBinding; | ||
| 436 | algorithm | ||
| 437 |
3/4✓ Branch 1 taken 1384 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 548 times.
✓ Branch 6 taken 836 times.
|
1384 | noBinding := InstNode.isComponent(component) and not hasBinding(InstNode.component(component)); |
| 438 | end has_missing_binding; | ||
| 439 | |||
| 440 | algorithm | ||
| 441 |
2/2✓ Branch 2 taken 16747 times.
✓ Branch 3 taken 37445 times.
|
54192 | if Binding.isBound(getBinding(component)) then |
| 442 | // Simple case, component has normal binding equation. | ||
| 443 | b := true; | ||
| 444 | 16747 | return; | |
| 445 | end if; | ||
| 446 | |||
| 447 | // Complex case, component might be a record instance where each field has | ||
| 448 | // its own binding equation. | ||
| 449 | 37445 | cls := InstNode.getClass(classInstance(component)); | |
| 450 | |||
| 451 |
2/2✓ Branch 2 taken 37017 times.
✓ Branch 3 taken 428 times.
|
37445 | if not Restriction.isRecord(Class.restriction(cls)) then |
| 452 | // Not record. | ||
| 453 | b := false; | ||
| 454 | 37017 | return; | |
| 455 | end if; | ||
| 456 | |||
| 457 | // Check if any child of this component is missing a binding. | ||
| 458 |
3/4✗ Branch 2 not taken.
✓ Branch 3 taken 428 times.
✓ Branch 8 taken 418 times.
✓ Branch 9 taken 10 times.
|
428 | if isSome(ClassTree.findComponent(Class.classTree(cls), has_missing_binding)) then |
| 459 | b := false; | ||
| 460 | end if; | ||
| 461 | |||
| 462 | b := true; | ||
| 463 | end hasBinding; | ||
| 464 | |||
| 465 | function getCondition | ||
| 466 | input Component component; | ||
| 467 | output Binding cond; | ||
| 468 | algorithm | ||
| 469 | cond := match component | ||
| 470 | 1948179 | case COMPONENT() then component.condition; | |
| 471 | else NFBinding.EMPTY_BINDING; | ||
| 472 | end match; | ||
| 473 | end getCondition; | ||
| 474 | |||
| 475 | function hasCondition | ||
| 476 | input Component component; | ||
| 477 | output Boolean b; | ||
| 478 | algorithm | ||
| 479 | 1954092 | b := Binding.isBound(getCondition(component)); | |
| 480 | end hasCondition; | ||
| 481 | |||
| 482 | function direction | ||
| 483 | input Component component; | ||
| 484 | output Direction direction; | ||
| 485 | algorithm | ||
| 486 | direction := match component | ||
| 487 | case COMPONENT(attributes = Attributes.ATTRIBUTES(direction = direction)) then direction; | ||
| 488 | else Direction.NONE; | ||
| 489 | end match; | ||
| 490 | end direction; | ||
| 491 | |||
| 492 | function isInput | ||
| 493 | input Component component; | ||
| 494 | output Boolean isInput = direction(component) == Direction.INPUT; | ||
| 495 | end isInput; | ||
| 496 | |||
| 497 | function setDirection | ||
| 498 | input Direction direction; | ||
| 499 | input output Component component; | ||
| 500 | protected | ||
| 501 | Attributes attr; | ||
| 502 | algorithm | ||
| 503 | () := match component | ||
| 504 | case COMPONENT(attributes = attr) | ||
| 505 | algorithm | ||
| 506 | 24587 | attr.direction := direction; | |
| 507 | 24587 | component.attributes := attr; | |
| 508 | then | ||
| 509 | (); | ||
| 510 | |||
| 511 | else (); | ||
| 512 | end match; | ||
| 513 | end setDirection; | ||
| 514 | |||
| 515 | function isOutput | ||
| 516 | input Component component; | ||
| 517 | output Boolean isOutput = direction(component) == Direction.OUTPUT; | ||
| 518 | end isOutput; | ||
| 519 | |||
| 520 | function parallelism | ||
| 521 | input Component component; | ||
| 522 | output Parallelism parallelism; | ||
| 523 | algorithm | ||
| 524 | parallelism := match component | ||
| 525 | case COMPONENT(attributes = Attributes.ATTRIBUTES(parallelism = parallelism)) then parallelism; | ||
| 526 | else Parallelism.NON_PARALLEL; | ||
| 527 | end match; | ||
| 528 | end parallelism; | ||
| 529 | |||
| 530 | function variability | ||
| 531 | input Component component; | ||
| 532 | output Variability variability; | ||
| 533 | algorithm | ||
| 534 | variability := match component | ||
| 535 | case COMPONENT(attributes = Attributes.ATTRIBUTES(variability = variability)) then variability; | ||
| 536 | 29906 | case ITERATOR() then component.variability; | |
| 537 | case ENUM_LITERAL() then Variability.CONSTANT; | ||
| 538 | ✗ | case INVALID_COMPONENT() then variability(component.component); | |
| 539 | else Variability.CONTINUOUS; | ||
| 540 | end match; | ||
| 541 | end variability; | ||
| 542 | |||
| 543 | function setVariability | ||
| 544 | input Variability variability; | ||
| 545 | input output Component component; | ||
| 546 | algorithm | ||
| 547 | () := match component | ||
| 548 | local | ||
| 549 | Attributes attr; | ||
| 550 | |||
| 551 | case COMPONENT(attributes = attr) | ||
| 552 | algorithm | ||
| 553 | 58259 | attr.variability := variability; | |
| 554 | 58259 | component.attributes := attr; | |
| 555 | then | ||
| 556 | (); | ||
| 557 | |||
| 558 | else (); | ||
| 559 | end match; | ||
| 560 | end setVariability; | ||
| 561 | |||
| 562 | function isConst | ||
| 563 | input Component component; | ||
| 564 | output Boolean isConst = variability(component) == Variability.CONSTANT; | ||
| 565 | end isConst; | ||
| 566 | |||
| 567 | function isParameter | ||
| 568 | input Component component; | ||
| 569 | output Boolean b = variability(component) == Variability.PARAMETER; | ||
| 570 | end isParameter; | ||
| 571 | |||
| 572 | function isStructuralParameter | ||
| 573 | input Component component; | ||
| 574 | output Boolean b = variability(component) == Variability.STRUCTURAL_PARAMETER; | ||
| 575 | end isStructuralParameter; | ||
| 576 | |||
| 577 | function isVar | ||
| 578 | input Component component; | ||
| 579 | output Boolean isVar = variability(component) == Variability.CONTINUOUS; | ||
| 580 | end isVar; | ||
| 581 | |||
| 582 | function isRedeclare | ||
| 583 | input Component component; | ||
| 584 | output Boolean isRedeclare; | ||
| 585 | algorithm | ||
| 586 | isRedeclare := match component | ||
| 587 | 255578 | case COMPONENT_DEF() then SCodeUtil.isElementRedeclare(component.definition); | |
| 588 | else false; | ||
| 589 | end match; | ||
| 590 | end isRedeclare; | ||
| 591 | |||
| 592 | function isFinal | ||
| 593 | input Component component; | ||
| 594 | output Boolean isFinal; | ||
| 595 | algorithm | ||
| 596 | isFinal := match component | ||
| 597 | case COMPONENT_DEF() | ||
| 598 | ✗ | then SCodeUtil.finalBool(SCodeUtil.prefixesFinal(SCodeUtil.elementPrefixes(component.definition))); | |
| 599 | case COMPONENT(attributes = Attributes.ATTRIBUTES(isFinal = isFinal)) then isFinal; | ||
| 600 | else false; | ||
| 601 | end match; | ||
| 602 | end isFinal; | ||
| 603 | |||
| 604 | function setFinal | ||
| 605 | input output Component component; | ||
| 606 | input Boolean isFinal; | ||
| 607 | protected | ||
| 608 | Attributes attr; | ||
| 609 | algorithm | ||
| 610 | () := match component | ||
| 611 | case COMPONENT(attributes = attr) | ||
| 612 | algorithm | ||
| 613 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 33767 times.
|
33767 | attr.isFinal := isFinal; |
| 614 | 33767 | component.attributes := attr; | |
| 615 | then | ||
| 616 | (); | ||
| 617 | |||
| 618 | else (); | ||
| 619 | end match; | ||
| 620 | end setFinal; | ||
| 621 | |||
| 622 | function isResizable | ||
| 623 | input Component component; | ||
| 624 | output Boolean b; | ||
| 625 | algorithm | ||
| 626 | b := match component | ||
| 627 | case COMPONENT(attributes = Attributes.ATTRIBUTES(isResizable = b)) then b; | ||
| 628 | else false; | ||
| 629 | end match; | ||
| 630 | end isResizable; | ||
| 631 | |||
| 632 | function innerOuter | ||
| 633 | input Component component; | ||
| 634 | output InnerOuter io; | ||
| 635 | algorithm | ||
| 636 | io := match component | ||
| 637 | case COMPONENT(attributes = Attributes.ATTRIBUTES(innerOuter = io)) then io; | ||
| 638 | case COMPONENT_DEF() | ||
| 639 | 2363902 | then Prefixes.innerOuterFromSCode(SCodeUtil.prefixesInnerOuter( | |
| 640 | SCodeUtil.elementPrefixes(component.definition))); | ||
| 641 | else InnerOuter.NOT_INNER_OUTER; | ||
| 642 | end match; | ||
| 643 | end innerOuter; | ||
| 644 | |||
| 645 | function isInnerOuter | ||
| 646 | input Component component; | ||
| 647 | output Boolean isInnerOuter; | ||
| 648 | algorithm | ||
| 649 | ✗ | isInnerOuter := innerOuter(component) <> InnerOuter.NOT_INNER_OUTER; | |
| 650 | end isInnerOuter; | ||
| 651 | |||
| 652 | function isInner | ||
| 653 | input Component component; | ||
| 654 | output Boolean isInner; | ||
| 655 | protected | ||
| 656 | InnerOuter io = innerOuter(component); | ||
| 657 | algorithm | ||
| 658 | 2365 | isInner := io == InnerOuter.INNER or io == InnerOuter.INNER_OUTER; | |
| 659 | end isInner; | ||
| 660 | |||
| 661 | function isOuter | ||
| 662 | input Component component; | ||
| 663 | output Boolean isOuter; | ||
| 664 | protected | ||
| 665 | InnerOuter io = innerOuter(component); | ||
| 666 | algorithm | ||
| 667 | 952976 | isOuter := io == InnerOuter.OUTER or io == InnerOuter.INNER_OUTER; | |
| 668 | end isOuter; | ||
| 669 | |||
| 670 | function isOnlyOuter | ||
| 671 | input Component component; | ||
| 672 | output Boolean isOuter = innerOuter(component) == InnerOuter.OUTER; | ||
| 673 | end isOnlyOuter; | ||
| 674 | |||
| 675 | function connectorType | ||
| 676 | input Component component; | ||
| 677 | output ConnectorType.Type cty; | ||
| 678 | algorithm | ||
| 679 | cty := match component | ||
| 680 | case COMPONENT(attributes = Attributes.ATTRIBUTES(connectorType = cty)) then cty; | ||
| 681 | else ConnectorType.NON_CONNECTOR; | ||
| 682 | end match; | ||
| 683 | end connectorType; | ||
| 684 | |||
| 685 | function setConnectorType | ||
| 686 | input ConnectorType.Type cty; | ||
| 687 | input output Component component; | ||
| 688 | algorithm | ||
| 689 | () := match component | ||
| 690 | local | ||
| 691 | Attributes attr; | ||
| 692 | |||
| 693 | case COMPONENT(attributes = attr) | ||
| 694 | algorithm | ||
| 695 | 72 | attr.connectorType := cty; | |
| 696 | 72 | component.attributes := attr; | |
| 697 | then | ||
| 698 | (); | ||
| 699 | |||
| 700 | else (); | ||
| 701 | end match; | ||
| 702 | end setConnectorType; | ||
| 703 | |||
| 704 | function isFlow | ||
| 705 | input Component component; | ||
| 706 | output Boolean isFlow = ConnectorType.isFlow(connectorType(component)); | ||
| 707 | end isFlow; | ||
| 708 | |||
| 709 | function isConnector | ||
| 710 | input Component component; | ||
| 711 | output Boolean isConnector = ConnectorType.isConnectorType(connectorType(component)); | ||
| 712 | end isConnector; | ||
| 713 | |||
| 714 | function isExpandableConnector | ||
| 715 | input Component component; | ||
| 716 | output Boolean isConnector = ConnectorType.isExpandable(connectorType(component)); | ||
| 717 | end isExpandableConnector; | ||
| 718 | |||
| 719 | function isExternalObject | ||
| 720 | input Component component; | ||
| 721 | output Boolean isEO; | ||
| 722 | algorithm | ||
| 723 | isEO := match component | ||
| 724 | 40676 | case COMPONENT(ty = Type.UNTYPED()) then Class.isExternalObject(InstNode.getClass(component.classInst)); | |
| 725 | 1949 | case COMPONENT() then Type.isExternalObject(component.ty); | |
| 726 | else false; | ||
| 727 | end match; | ||
| 728 | end isExternalObject; | ||
| 729 | |||
| 730 | function isIdentical | ||
| 731 | input Component comp1; | ||
| 732 | input Component comp2; | ||
| 733 | output Boolean identical = false; | ||
| 734 | algorithm | ||
| 735 |
2/2✓ Branch 0 taken 32729 times.
✓ Branch 1 taken 42 times.
|
32771 | if referenceEq(comp1, comp2) then |
| 736 | identical := true; | ||
| 737 | else | ||
| 738 | identical := match (comp1, comp2) | ||
| 739 | case (COMPONENT(), COMPONENT()) | ||
| 740 | algorithm | ||
| 741 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 32672 times.
|
32672 | if not Class.isIdentical(InstNode.getClass(comp1.classInst), |
| 742 | InstNode.getClass(comp2.classInst)) then | ||
| 743 | ✗ | return; | |
| 744 | end if; | ||
| 745 | |||
| 746 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 32672 times.
|
32672 | if not Binding.isEqual(comp1.binding, comp2.binding) then |
| 747 | ✗ | return; | |
| 748 | end if; | ||
| 749 | then | ||
| 750 | true; | ||
| 751 | |||
| 752 | else true; | ||
| 753 | end match; | ||
| 754 | end if; | ||
| 755 | end isIdentical; | ||
| 756 | |||
| 757 | function toString | ||
| 758 | input String name; | ||
| 759 | input Component component; | ||
| 760 | output String str; | ||
| 761 | algorithm | ||
| 762 | str := match component | ||
| 763 | local | ||
| 764 | SCode.Element def; | ||
| 765 | |||
| 766 | case COMPONENT_DEF(definition = def as SCode.Element.COMPONENT()) | ||
| 767 | ✗ | then SCodeDump.unparseElementStr(def); | |
| 768 | |||
| 769 | case COMPONENT() | ||
| 770 | ✗ | then Attributes.toString(component.attributes, component.ty) + | |
| 771 | Type.toString(component.ty) + " " + name + | ||
| 772 | Binding.toString(component.binding, " = "); | ||
| 773 | |||
| 774 | case TYPE_ATTRIBUTE() | ||
| 775 | 92 | then name + Modifier.toString(component.modifier, printName = false); | |
| 776 | end match; | ||
| 777 | end toString; | ||
| 778 | |||
| 779 | function toFlatStream | ||
| 780 | input String name; | ||
| 781 | input Component component; | ||
| 782 | input BaseModelica.OutputFormat format; | ||
| 783 | input String indent; | ||
| 784 | input output IOStream.IOStream s; | ||
| 785 | protected | ||
| 786 | list<tuple<String, Binding>> ty_attrs; | ||
| 787 | list<Dimension> dims; | ||
| 788 | algorithm | ||
| 789 | () := match component | ||
| 790 | case COMPONENT() | ||
| 791 | algorithm | ||
| 792 | 108 | s := IOStream.append(s, indent); | |
| 793 | 108 | s := Attributes.toFlatStream(component.attributes, component.ty, s); | |
| 794 | 108 | s := IOStream.append(s, Type.toFlatString(Type.arrayElementType(component.ty), format)); | |
| 795 | 108 | s := IOStream.append(s, " "); | |
| 796 | 108 | s := IOStream.append(s, Util.makeQuotedIdentifier(name)); | |
| 797 | |||
| 798 | 108 | dims := Type.arrayDims(component.ty); | |
| 799 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 82 times.
|
108 | if not listEmpty(dims) then |
| 800 | 26 | s := IOStream.append(s, Dimension.toFlatStringList(dims, format)); | |
| 801 | end if; | ||
| 802 | |||
| 803 |
4/4✓ Branch 2 taken 2 times.
✓ Branch 3 taken 108 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 108 times.
|
110 | ty_attrs := list((Modifier.name(a), Modifier.binding(a)) for a in |
| 804 | Class.getTypeAttributes(InstNode.getClass(component.classInst))); | ||
| 805 | 108 | s := typeAttrsToFlatStream(ty_attrs, component.ty, format, s); | |
| 806 | |||
| 807 | 108 | s := IOStream.append(s, Binding.toFlatString(component.binding, format, " = ")); | |
| 808 | then | ||
| 809 | (); | ||
| 810 | |||
| 811 | case TYPE_ATTRIBUTE() | ||
| 812 | algorithm | ||
| 813 | ✗ | s := IOStream.append(s, name); | |
| 814 | ✗ | s := IOStream.append(s, Modifier.toFlatString(component.modifier, format, printName = false)); | |
| 815 | then | ||
| 816 | (); | ||
| 817 | end match; | ||
| 818 | end toFlatStream; | ||
| 819 | |||
| 820 | function typeAttrsToFlatStream | ||
| 821 | input list<tuple<String, Binding>> typeAttrs; | ||
| 822 | input Type componentType; | ||
| 823 | input BaseModelica.OutputFormat format; | ||
| 824 | input output IOStream.IOStream s; | ||
| 825 | protected | ||
| 826 | Integer var_dims, binding_dims; | ||
| 827 | list<tuple<String, Binding>> ty_attrs = typeAttrs; | ||
| 828 | String name; | ||
| 829 | Binding binding; | ||
| 830 | Expression bind_exp; | ||
| 831 | algorithm | ||
| 832 |
2/2✓ Branch 0 taken 106 times.
✓ Branch 1 taken 30 times.
|
136 | if listEmpty(ty_attrs) then |
| 833 | 106 | return; | |
| 834 | end if; | ||
| 835 | |||
| 836 | 30 | s := IOStream.append(s, "("); | |
| 837 | 30 | var_dims := Type.dimensionCount(componentType); | |
| 838 | |||
| 839 | 12 | while true loop | |
| 840 | 42 | (name, binding) := listHead(ty_attrs); | |
| 841 | 42 | bind_exp := Expression.expandSplitIndices(Binding.getExp(binding)); | |
| 842 | 42 | binding_dims := Type.dimensionCount(Expression.typeOf(bind_exp)); | |
| 843 | |||
| 844 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
|
42 | if var_dims > binding_dims then |
| 845 | ✗ | s := IOStream.append(s, "each "); | |
| 846 | end if; | ||
| 847 | |||
| 848 | 42 | s := IOStream.append(s, name); | |
| 849 | 42 | s := IOStream.append(s, " = "); | |
| 850 | 42 | s := IOStream.append(s, Expression.toFlatString(bind_exp, format)); | |
| 851 | |||
| 852 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 38 times.
|
42 | if format.showConfidence then |
| 853 | 4 | s := IOStream.append(s, " /* confidence = "); | |
| 854 | 4 | s := IOStream.append(s, String(Binding.actualConfidence(binding))); | |
| 855 | 4 | s := IOStream.append(s, "*/"); | |
| 856 | end if; | ||
| 857 | |||
| 858 | 42 | ty_attrs := listRest(ty_attrs); | |
| 859 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 30 times.
|
42 | if listEmpty(ty_attrs) then |
| 860 | break; | ||
| 861 | else | ||
| 862 | 12 | s := IOStream.append(s, ", "); | |
| 863 | end if; | ||
| 864 | end while; | ||
| 865 | |||
| 866 | 30 | s := IOStream.append(s, ")"); | |
| 867 | end typeAttrsToFlatStream; | ||
| 868 | |||
| 869 | function toFlatString | ||
| 870 | input String name; | ||
| 871 | input Component component; | ||
| 872 | input BaseModelica.OutputFormat format; | ||
| 873 | input String indent = ""; | ||
| 874 | output String str; | ||
| 875 | protected | ||
| 876 | IOStream.IOStream s; | ||
| 877 | algorithm | ||
| 878 | 108 | s := IOStream.create(name, IOStream.IOStreamType.LIST()); | |
| 879 | 108 | s := toFlatStream(name, component, format, indent, s); | |
| 880 | 108 | str := IOStream.string(s); | |
| 881 | 108 | IOStream.delete(s); | |
| 882 | end toFlatString; | ||
| 883 | |||
| 884 | function dimensionCount | ||
| 885 | input Component component; | ||
| 886 | output Integer count; | ||
| 887 | algorithm | ||
| 888 | count := match component | ||
| 889 | 722597 | case COMPONENT() then Type.dimensionCount(component.ty); | |
| 890 | else 0; | ||
| 891 | end match; | ||
| 892 | end dimensionCount; | ||
| 893 | |||
| 894 | function comment | ||
| 895 | input Component component; | ||
| 896 | output SCode.Comment comment; | ||
| 897 | algorithm | ||
| 898 | comment := match component | ||
| 899 | ✗ | case COMPONENT_DEF() then Util.getOption(SCodeUtil.getElementComment(component.definition)); | |
| 900 | 1817938 | case COMPONENT() then component.comment; | |
| 901 | 3 | case ENUM_LITERAL() then component.comment; | |
| 902 | else SCode.noComment; | ||
| 903 | end match; | ||
| 904 | end comment; | ||
| 905 | |||
| 906 | function getEvaluateAnnotation | ||
| 907 | input Component component; | ||
| 908 | output Option<Boolean> evaluate; | ||
| 909 | algorithm | ||
| 910 | 282775 | evaluate := SCodeUtil.getEvaluateAnnotation(comment(component)); | |
| 911 | end getEvaluateAnnotation; | ||
| 912 | |||
| 913 | function isFixed | ||
| 914 | input Component component; | ||
| 915 | output Boolean fixed; | ||
| 916 | protected | ||
| 917 | Binding binding; | ||
| 918 | algorithm | ||
| 919 | // for parameters the default is fixed = true | ||
| 920 |
4/4✓ Branch 1 taken 79 times.
✓ Branch 2 taken 44101 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 58 times.
|
44180 | fixed := isParameter(component) or isStructuralParameter(component); |
| 921 | |||
| 922 | 44180 | binding := Class.lookupAttributeBinding("fixed", InstNode.getClass(classInstance(component))); | |
| 923 | |||
| 924 | // no fixed attribute present | ||
| 925 |
2/2✓ Branch 1 taken 43561 times.
✓ Branch 2 taken 619 times.
|
44180 | if Binding.isUnbound(binding) then |
| 926 | 43561 | return; | |
| 927 | end if; | ||
| 928 | |||
| 929 |
2/2✓ Branch 1 taken 23 times.
✓ Branch 2 taken 596 times.
|
619 | if Binding.hasExp(binding) then |
| 930 |
2/4✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
|
23 | fixed := fixed and Expression.isTrue(Binding.getExp(binding)); |
| 931 | else | ||
| 932 | fixed := match binding | ||
| 933 | case Binding.RAW_BINDING(bindingExp = Absyn.Exp.BOOL(true)) | ||
| 934 | then true; | ||
| 935 | else false; | ||
| 936 | end match; | ||
| 937 | end if; | ||
| 938 | end isFixed; | ||
| 939 | |||
| 940 | function getUnitAttribute | ||
| 941 | input Component component; | ||
| 942 | input String defaultUnit = ""; | ||
| 943 | output String unitString; | ||
| 944 | protected | ||
| 945 | Binding binding; | ||
| 946 | Expression unit; | ||
| 947 | algorithm | ||
| 948 | 1468 | binding := Class.lookupAttributeBinding("unit", InstNode.getClass(classInstance(component))); | |
| 949 | |||
| 950 |
2/2✓ Branch 1 taken 1095 times.
✓ Branch 2 taken 373 times.
|
1468 | if Binding.isUnbound(binding) then |
| 951 | unitString := defaultUnit; | ||
| 952 | 1095 | return; | |
| 953 | end if; | ||
| 954 | |||
| 955 | 373 | unit := Binding.getExp(binding); | |
| 956 | |||
| 957 | unitString := match unit | ||
| 958 | 164 | case Expression.STRING() then unit.value; | |
| 959 | else defaultUnit; | ||
| 960 | end match; | ||
| 961 | end getUnitAttribute; | ||
| 962 | |||
| 963 | function isDeleted | ||
| 964 | input Component component; | ||
| 965 | output Boolean isDeleted; | ||
| 966 | algorithm | ||
| 967 | isDeleted := match component | ||
| 968 | local | ||
| 969 | Binding condition; | ||
| 970 | |||
| 971 | case COMPONENT(condition = condition) | ||
| 972 |
4/4✓ Branch 1 taken 18448 times.
✓ Branch 2 taken 1194116 times.
✓ Branch 5 taken 11084 times.
✓ Branch 6 taken 7364 times.
|
1212564 | then Binding.isTyped(condition) and Expression.isFalse(Binding.getTypedExp(condition)); |
| 973 | |||
| 974 | else false; | ||
| 975 | end match; | ||
| 976 | end isDeleted; | ||
| 977 | |||
| 978 | function isInvalid | ||
| 979 | input Component component; | ||
| 980 | output Boolean invalid; | ||
| 981 | algorithm | ||
| 982 | invalid := match component | ||
| 983 | case INVALID_COMPONENT() then true; | ||
| 984 | else false; | ||
| 985 | end match; | ||
| 986 | end isInvalid; | ||
| 987 | |||
| 988 | function isIterator | ||
| 989 | input Component component; | ||
| 990 | output Boolean iterator; | ||
| 991 | algorithm | ||
| 992 | iterator := match component | ||
| 993 | case ITERATOR() then true; | ||
| 994 | else false; | ||
| 995 | end match; | ||
| 996 | end isIterator; | ||
| 997 | |||
| 998 | function isTypeAttribute | ||
| 999 | input Component component; | ||
| 1000 | output Boolean isAttribute; | ||
| 1001 | algorithm | ||
| 1002 | isAttribute := match component | ||
| 1003 | case TYPE_ATTRIBUTE() then true; | ||
| 1004 | else false; | ||
| 1005 | end match; | ||
| 1006 | end isTypeAttribute; | ||
| 1007 | |||
| 1008 | function countConnectorVars | ||
| 1009 | "Returns the number of potential (neither constant, parameter, input, nor | ||
| 1010 | output), flow, and stream variables in the given connector." | ||
| 1011 | input Component component; | ||
| 1012 | input Boolean isRoot = true; | ||
| 1013 | output Integer potentials = 0; | ||
| 1014 | output Integer flows = 0; | ||
| 1015 | output Integer streams = 0; | ||
| 1016 | output Boolean knownSize = true; | ||
| 1017 | protected | ||
| 1018 | Type ty; | ||
| 1019 | ConnectorType.Type cty; | ||
| 1020 | Class cls; | ||
| 1021 | Option<InstNode> eq_node_opt; | ||
| 1022 | InstNode eq_node; | ||
| 1023 | Integer comp_size = 0, p, f, s; | ||
| 1024 | Function fn; | ||
| 1025 | Boolean known_size; | ||
| 1026 | algorithm | ||
| 1027 | 58162 | cls := InstNode.getClass(classInstance(component)); | |
| 1028 | 58162 | eq_node_opt := Class.tryLookupElement("equalityConstraint", cls); | |
| 1029 | |||
| 1030 |
4/6✗ Branch 0 not taken.
✓ Branch 1 taken 58162 times.
✓ Branch 2 taken 2775 times.
✓ Branch 3 taken 55387 times.
✓ Branch 7 taken 2775 times.
✗ Branch 8 not taken.
|
58162 | if isSome(eq_node_opt) and |
| 1031 | SCodeUtil.isFunction(InstNode.definition(Util.getOption(eq_node_opt))) then | ||
| 1032 | // If the type contains an equalityConstraint function then the size is | ||
| 1033 | // determined by the return type of it. | ||
| 1034 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 2775 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2775 times.
|
2775 | SOME(eq_node) := eq_node_opt; |
| 1035 | 2775 | Function.instFunctionNode(eq_node, NFInstContext.NO_CONTEXT, info(component)); | |
| 1036 | 2775 | fn := listHead(Function.typeNodeCache(eq_node)); | |
| 1037 | 2775 | ty := Function.returnType(fn); | |
| 1038 | |||
| 1039 |
1/2✓ Branch 1 taken 2775 times.
✗ Branch 2 not taken.
|
2775 | if Type.hasKnownSize(ty) then |
| 1040 | 2775 | comp_size := Type.sizeOf(ty); | |
| 1041 | else | ||
| 1042 | comp_size := 0; | ||
| 1043 | knownSize := false; | ||
| 1044 | end if; | ||
| 1045 | else | ||
| 1046 | 55387 | ty := getType(component); | |
| 1047 | |||
| 1048 | // Ignore dimensions for the root connector, i.e. an array of connectors | ||
| 1049 | // is treated as a scalar when balance checking it. | ||
| 1050 |
2/2✓ Branch 0 taken 36391 times.
✓ Branch 1 taken 18996 times.
|
55387 | if isRoot then |
| 1051 | comp_size := 1; | ||
| 1052 | elseif Type.hasKnownSize(ty) then | ||
| 1053 | 36390 | comp_size := Dimension.sizesProduct(Type.arrayDims(ty), false); | |
| 1054 | else | ||
| 1055 | comp_size := 0; | ||
| 1056 | knownSize := false; | ||
| 1057 | end if; | ||
| 1058 | |||
| 1059 | 55387 | ty := Type.arrayElementType(ty); | |
| 1060 |
2/2✓ Branch 1 taken 15342 times.
✓ Branch 2 taken 40045 times.
|
55387 | if Type.isComplex(ty) then |
| 1061 | // For complex types we only count elements in records, not in e.g. connectors. | ||
| 1062 | // (unless it's the connector that we're trying to count the variables in). | ||
| 1063 |
4/4✓ Branch 1 taken 14098 times.
✓ Branch 2 taken 1244 times.
✓ Branch 3 taken 12857 times.
✓ Branch 4 taken 1241 times.
|
15342 | if Type.isRecord(ty) or isRoot then |
| 1064 |
2/2✓ Branch 3 taken 39166 times.
✓ Branch 4 taken 14101 times.
|
67368 | for c in ClassTree.getComponents(Class.classTree(cls)) loop |
| 1065 | 39166 | (p, f, s, known_size) := countConnectorVars(InstNode.component(c), false); | |
| 1066 | 39166 | potentials := potentials + p * comp_size; | |
| 1067 | 39166 | flows := flows + f * comp_size; | |
| 1068 | 39166 | streams := streams + s * comp_size; | |
| 1069 |
3/4✓ Branch 0 taken 39165 times.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 39165 times.
|
39166 | knownSize := known_size and knownSize; |
| 1070 | end for; | ||
| 1071 | end if; | ||
| 1072 | |||
| 1073 | // Complex elements are not counted themselves. | ||
| 1074 | comp_size := 0; | ||
| 1075 | end if; | ||
| 1076 | end if; | ||
| 1077 | |||
| 1078 |
2/2✓ Branch 0 taken 16084 times.
✓ Branch 1 taken 42078 times.
|
58162 | if comp_size > 0 then |
| 1079 | 42078 | cty := connectorType(component); | |
| 1080 | |||
| 1081 |
2/2✓ Branch 1 taken 14662 times.
✓ Branch 2 taken 27416 times.
|
42078 | if ConnectorType.isFlow(cty) then |
| 1082 | 14662 | flows := flows + comp_size; | |
| 1083 | elseif ConnectorType.isStream(cty) then | ||
| 1084 | 454 | streams := streams + comp_size; | |
| 1085 | elseif variability(component) >= Variability.DISCRETE and | ||
| 1086 | direction(component) == Direction.NONE then | ||
| 1087 | 16642 | potentials := potentials + comp_size; | |
| 1088 | end if; | ||
| 1089 | end if; | ||
| 1090 | end countConnectorVars; | ||
| 1091 | |||
| 1092 | annotation(__OpenModelica_Interface="nf_frontend"); | ||
| 1093 | end NFComponent; | ||
| 1094 |