OMCompiler/Compiler/NFFrontEnd/NFVariable.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 NFVariable | ||
| 37 | import Attributes = NFAttributes; | ||
| 38 | import Binding = NFBinding; | ||
| 39 | import Class = NFClass; | ||
| 40 | import Component = NFComponent; | ||
| 41 | import ComponentRef = NFComponentRef; | ||
| 42 | import Dimension = NFDimension; | ||
| 43 | import Equation = NFEquation; | ||
| 44 | import Expression = NFExpression; | ||
| 45 | import NFInstNode.InstNode; | ||
| 46 | import NFPrefixes.Visibility; | ||
| 47 | import NFPrefixes.Variability; | ||
| 48 | import NFPrefixes.ConnectorType; | ||
| 49 | import NFPrefixes.Direction; | ||
| 50 | import NFPrefixes.AccessLevel; | ||
| 51 | import Type = NFType; | ||
| 52 | import NFBackendExtension.{BackendInfo, VariableKind, VariableAttributes}; | ||
| 53 | import BaseModelica; | ||
| 54 | |||
| 55 | protected | ||
| 56 | import Absyn; | ||
| 57 | import Ceval = NFCeval; | ||
| 58 | import ExpandExp = NFExpandExp; | ||
| 59 | import FlatModelicaUtil = NFFlatModelicaUtil; | ||
| 60 | import Inst = NFInst; | ||
| 61 | import IOStream; | ||
| 62 | import MetaModelica.Dangerous.listReverseInPlace; | ||
| 63 | import SCode; | ||
| 64 | import StringUtil; | ||
| 65 | import Typing = NFTyping; | ||
| 66 | import Util; | ||
| 67 | import Variable = NFVariable; | ||
| 68 | |||
| 69 | public | ||
| 70 | record VARIABLE | ||
| 71 | ComponentRef name; | ||
| 72 | Type ty; | ||
| 73 | Binding binding; | ||
| 74 | Visibility visibility; | ||
| 75 | Attributes attributes; | ||
| 76 | list<tuple<String, Binding>> typeAttributes; | ||
| 77 | list<Variable> children; | ||
| 78 | SCode.Comment comment; | ||
| 79 | SourceInfo info; | ||
| 80 | BackendInfo backendinfo "NFBackendExtension.DUMMY_BACKEND_INFO for all of frontend. Only used in Backend."; | ||
| 81 | end VARIABLE; | ||
| 82 | |||
| 83 | function fromCref | ||
| 84 | "creates a variable from a component reference. | ||
| 85 | Note: does not flatten, do not use for instantiated elements!" | ||
| 86 | input ComponentRef cref; | ||
| 87 | output Variable variable; | ||
| 88 | protected | ||
| 89 | InstNode node, class_node; | ||
| 90 | Component comp; | ||
| 91 | Type ty; | ||
| 92 | Binding binding; | ||
| 93 | Visibility vis; | ||
| 94 | Attributes attr; | ||
| 95 | SCode.Comment cmt; | ||
| 96 | SourceInfo info; | ||
| 97 | BackendInfo binfo = NFBackendExtension.DUMMY_BACKEND_INFO; | ||
| 98 | array<InstNode> child_nodes; | ||
| 99 | Type elem_ty; | ||
| 100 | list<Variable> children = {}; | ||
| 101 | algorithm | ||
| 102 | 8221 | node := ComponentRef.node(cref); | |
| 103 | 8221 | comp := InstNode.component(node); | |
| 104 | 8221 | ty := ComponentRef.getSubscriptedType(cref); | |
| 105 | 8221 | vis := InstNode.visibility(node); | |
| 106 | 8221 | attr := Component.getAttributes(comp); | |
| 107 | 8221 | cmt := Component.comment(comp); | |
| 108 | 8221 | info := InstNode.info(node); | |
| 109 | |||
| 110 | // kabdelhak: add dummy backend info, will be changed to actual value in | ||
| 111 | // conversion to backend process (except for iterators). NBackendDAE.lower | ||
| 112 |
2/2✓ Branch 1 taken 5553 times.
✓ Branch 2 taken 2668 times.
|
8221 | if ComponentRef.isIterator(cref) then |
| 113 | binding := NFBinding.EMPTY_BINDING; | ||
| 114 | 5553 | binfo.varKind := VariableKind.ITERATOR(); | |
| 115 | else | ||
| 116 | 2668 | binding := Component.getImplicitBinding(comp, InstNode.instanceParent(node)); | |
| 117 | end if; | ||
| 118 | |||
| 119 | // get the record children if the variable is a record | ||
| 120 |
1/2✓ Branch 1 taken 8221 times.
✗ Branch 2 not taken.
|
8221 | if not Type.isExternalObject(ty) then |
| 121 | children := match Type.arrayElementType(ty) | ||
| 122 | case elem_ty as Type.COMPLEX() algorithm | ||
| 123 | ✗ | class_node := Type.complexNode(elem_ty); | |
| 124 | ✗ | child_nodes := Class.getComponents(InstNode.getClass(class_node)); | |
| 125 | ✗ | children := list(fromCref(ComponentRef.prefixCref(c, InstNode.getType(c), {}, cref)) for c in child_nodes); | |
| 126 | then children; | ||
| 127 | else {}; | ||
| 128 | end match; | ||
| 129 | end if; | ||
| 130 | |||
| 131 | 8221 | variable := VARIABLE(cref, ty, binding, vis, attr, {}, children, cmt, info, binfo); | |
| 132 | end fromCref; | ||
| 133 | |||
| 134 | function name | ||
| 135 | input Variable var; | ||
| 136 | output ComponentRef name = var.name; | ||
| 137 | end name; | ||
| 138 | |||
| 139 | function size | ||
| 140 | input Variable var; | ||
| 141 | input Boolean resize = false; | ||
| 142 | output Integer s = Type.sizeOf(var.ty, resize); | ||
| 143 | end size; | ||
| 144 | |||
| 145 | function hash | ||
| 146 | input Variable var; | ||
| 147 | output Integer i = ComponentRef.hash(var.name); | ||
| 148 | end hash; | ||
| 149 | |||
| 150 | function equalName | ||
| 151 | input Variable var1; | ||
| 152 | input Variable var2; | ||
| 153 | output Boolean b = ComponentRef.isEqual(var1.name, var2.name); | ||
| 154 | end equalName; | ||
| 155 | |||
| 156 | function expand | ||
| 157 | "Expands an array variable into its scalar elements." | ||
| 158 | input Variable var; | ||
| 159 | input Boolean backend = false; | ||
| 160 | output list<Variable> vars; | ||
| 161 | protected | ||
| 162 | list<ComponentRef> crefs; | ||
| 163 | Variable v; | ||
| 164 | Binding binding; | ||
| 165 | Variability bind_var; | ||
| 166 | Binding.Source bind_src; | ||
| 167 | Expression bind_exp, exp; | ||
| 168 | list<Expression> expl; | ||
| 169 | Integer crefs_len, expl_len; | ||
| 170 | algorithm | ||
| 171 | ✗ | if Type.isArray(var.ty) then | |
| 172 | // Expand the name. | ||
| 173 | ✗ | exp := Expression.fromCref(var.name); | |
| 174 | ✗ | exp := ExpandExp.expandCref(exp, backend); | |
| 175 | ✗ | expl := Expression.arrayScalarElements(exp); | |
| 176 | ✗ | crefs := list(Expression.toCref(e) for e in expl); | |
| 177 | |||
| 178 | v := var; | ||
| 179 | ✗ | v.ty := Type.arrayElementType(v.ty); | |
| 180 | vars := {}; | ||
| 181 | ✗ | binding := var.binding; | |
| 182 | |||
| 183 | // If the variable has a binding we need to expand it too. | ||
| 184 | ✗ | if Binding.isBound(binding) then | |
| 185 | ✗ | bind_exp := Binding.getTypedExp(binding); | |
| 186 | ✗ | expl := Expression.arrayScalarElements(ExpandExp.expand(bind_exp)); | |
| 187 | |||
| 188 | ✗ | crefs_len := listLength(crefs); | |
| 189 | ✗ | expl_len := listLength(expl); | |
| 190 | |||
| 191 | // If the binding has fewer dimensions than the variable, 'multiply' the | ||
| 192 | // list of binding expression until they match. | ||
| 193 | ✗ | if expl_len < crefs_len then | |
| 194 | ✗ | if intMod(crefs_len, expl_len) <> 0 then | |
| 195 | ✗ | Error.terminate(getInstanceName() + " failed to expand " + | |
| 196 | ComponentRef.toString(var.name), sourceInfo()); | ||
| 197 | end if; | ||
| 198 | |||
| 199 | ✗ | expl := List.flatten(List.fill(expl, intDiv(crefs_len, expl_len))); | |
| 200 | end if; | ||
| 201 | |||
| 202 | ✗ | bind_var := Binding.variability(binding); | |
| 203 | ✗ | bind_src := Binding.source(binding); | |
| 204 | |||
| 205 | ✗ | for cr in crefs loop | |
| 206 | ✗ | v.name := cr; | |
| 207 | ✗ | exp :: expl := expl; | |
| 208 | ✗ | v.binding := Binding.makeFlat(exp, bind_var, bind_src); | |
| 209 | vars := v :: vars; | ||
| 210 | end for; | ||
| 211 | else | ||
| 212 | ✗ | for cr in crefs loop | |
| 213 | ✗ | v.name := cr; | |
| 214 | vars := v :: vars; | ||
| 215 | end for; | ||
| 216 | end if; | ||
| 217 | ✗ | vars := listReverseInPlace(vars); | |
| 218 | else | ||
| 219 | vars := {var}; | ||
| 220 | end if; | ||
| 221 | end expand; | ||
| 222 | |||
| 223 | function expandChildren | ||
| 224 | "Expands a variable into itself and its children if its complex." | ||
| 225 | input Variable var; | ||
| 226 | input list<Dimension> arrayDims = {}; | ||
| 227 | input Boolean addDimensions = true; | ||
| 228 | output list<Variable> children; | ||
| 229 | protected | ||
| 230 | list<Dimension> newArrayDims; | ||
| 231 | algorithm | ||
| 232 | // add dimensions of surrounding record | ||
| 233 |
4/4✓ Branch 0 taken 6708 times.
✓ Branch 1 taken 165 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 6680 times.
|
6873 | if addDimensions and not listEmpty(arrayDims) then |
| 234 | 28 | var.ty := Type.liftArrayLeftList(var.ty, arrayDims); | |
| 235 | end if; | ||
| 236 | 6873 | newArrayDims := Type.arrayDims(var.ty); | |
| 237 | |||
| 238 | // return all children and the variable itself | ||
| 239 |
4/4✓ Branch 0 taken 452 times.
✓ Branch 1 taken 6873 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 6873 times.
|
7325 | children := var :: List.flatten(list(expandChildren(v, newArrayDims, addDimensions) for v in var.children)); |
| 240 | end expandChildren; | ||
| 241 | |||
| 242 | function typeOf | ||
| 243 | input Variable var; | ||
| 244 | output Type ty = var.ty; | ||
| 245 | end typeOf; | ||
| 246 | |||
| 247 | function attributes | ||
| 248 | input Variable variable; | ||
| 249 | output Attributes attributes = variable.attributes; | ||
| 250 | end attributes; | ||
| 251 | |||
| 252 | function variability | ||
| 253 | input Variable variable; | ||
| 254 | output Variability variability = variable.attributes.variability; | ||
| 255 | end variability; | ||
| 256 | |||
| 257 | function setVariability | ||
| 258 | input output Variable variable; | ||
| 259 | input Variability variability; | ||
| 260 | protected | ||
| 261 | Attributes attr; | ||
| 262 | algorithm | ||
| 263 | 1168 | attr := variable.attributes; | |
| 264 | 1168 | attr.variability := variability; | |
| 265 | 1168 | variable.attributes := attr; | |
| 266 | end setVariability; | ||
| 267 | |||
| 268 | function visibility | ||
| 269 | input Variable variable; | ||
| 270 | output Visibility visibility = variable.visibility; | ||
| 271 | end visibility; | ||
| 272 | |||
| 273 | function isComplex | ||
| 274 | input Variable var; | ||
| 275 | output Boolean b = Type.isComplex(var.ty); | ||
| 276 | end isComplex; | ||
| 277 | |||
| 278 | function isComplexArray | ||
| 279 | input Variable var; | ||
| 280 | output Boolean b = Type.isComplexArray(var.ty); | ||
| 281 | end isComplexArray; | ||
| 282 | |||
| 283 | function isStructural | ||
| 284 | input Variable variable; | ||
| 285 | output Boolean structural = | ||
| 286 | variable.attributes.variability <= Variability.STRUCTURAL_PARAMETER; | ||
| 287 | end isStructural; | ||
| 288 | |||
| 289 | function isEmptyArray | ||
| 290 | input Variable variable; | ||
| 291 | output Boolean isEmpty = Type.isEmptyArray(variable.ty); | ||
| 292 | end isEmptyArray; | ||
| 293 | |||
| 294 | function isDeleted | ||
| 295 | input Variable variable; | ||
| 296 | output Boolean deleted; | ||
| 297 | protected | ||
| 298 | InstNode node; | ||
| 299 | algorithm | ||
| 300 | ✗ | node := ComponentRef.node(variable.name); | |
| 301 | ✗ | deleted := InstNode.isComponent(node) and Component.isDeleted(InstNode.component(node)); | |
| 302 | end isDeleted; | ||
| 303 | |||
| 304 | function isPresent | ||
| 305 | input Variable variable; | ||
| 306 | output Boolean present = not ConnectorType.isPotentiallyPresent(variable.attributes.connectorType); | ||
| 307 | end isPresent; | ||
| 308 | |||
| 309 | function isPotential | ||
| 310 | input Variable variable; | ||
| 311 | output Boolean potential = ConnectorType.isPotential(variable.attributes.connectorType); | ||
| 312 | end isPotential; | ||
| 313 | |||
| 314 | function isFlow | ||
| 315 | input Variable variable; | ||
| 316 | output Boolean potential = ConnectorType.isFlow(variable.attributes.connectorType); | ||
| 317 | end isFlow; | ||
| 318 | |||
| 319 | function isStream | ||
| 320 | input Variable variable; | ||
| 321 | output Boolean potential = ConnectorType.isStream(variable.attributes.connectorType); | ||
| 322 | end isStream; | ||
| 323 | |||
| 324 | function isInput | ||
| 325 | input Variable variable; | ||
| 326 | output Boolean b = variable.attributes.direction == Direction.INPUT; | ||
| 327 | end isInput; | ||
| 328 | |||
| 329 | function isOutput | ||
| 330 | input Variable variable; | ||
| 331 | output Boolean b = variable.attributes.direction == Direction.OUTPUT; | ||
| 332 | end isOutput; | ||
| 333 | |||
| 334 | function isTopLevelInput | ||
| 335 | input Variable variable; | ||
| 336 | output Boolean topInput = ComponentRef.isTopLevel(variable.name) and | ||
| 337 | variable.attributes.direction == Direction.INPUT; | ||
| 338 | end isTopLevelInput; | ||
| 339 | |||
| 340 | function isPublic | ||
| 341 | input Variable variable; | ||
| 342 | output Boolean isPublic = variable.visibility == Visibility.PUBLIC; | ||
| 343 | end isPublic; | ||
| 344 | |||
| 345 | function isProtected | ||
| 346 | input Variable variable; | ||
| 347 | output Boolean isProtected = variable.visibility == Visibility.PROTECTED; | ||
| 348 | end isProtected; | ||
| 349 | |||
| 350 | function isEncrypted | ||
| 351 | input Variable variable; | ||
| 352 | output Boolean isEncrypted = isEncryptedName(variable.name); | ||
| 353 | end isEncrypted; | ||
| 354 | |||
| 355 | function isEncryptedName | ||
| 356 | "Whether any part of the name is declared in an encrypted file." | ||
| 357 | input ComponentRef name; | ||
| 358 | output Boolean isEncrypted = false; | ||
| 359 | protected | ||
| 360 | ComponentRef cr = name; | ||
| 361 | algorithm | ||
| 362 |
2/2✓ Branch 1 taken 230056 times.
✓ Branch 2 taken 85908 times.
|
315964 | while ComponentRef.isCref(cr) loop |
| 363 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 230056 times.
|
230056 | if isEncryptedNode(ComponentRef.node(cr)) then |
| 364 | isEncrypted := true; | ||
| 365 | ✗ | return; | |
| 366 | end if; | ||
| 367 | |||
| 368 | 230056 | cr := ComponentRef.rest(cr); | |
| 369 | end while; | ||
| 370 | end isEncryptedName; | ||
| 371 | |||
| 372 | function isEncryptedNode | ||
| 373 | input InstNode node; | ||
| 374 | output Boolean isEncrypted; | ||
| 375 | protected | ||
| 376 | SourceInfo info = InstNode.info(node); | ||
| 377 | algorithm | ||
| 378 | 603365 | isEncrypted := StringUtil.endsWith(info.fileName, ".moc"); | |
| 379 | end isEncryptedNode; | ||
| 380 | |||
| 381 | function isAccessible | ||
| 382 | input Variable variable; | ||
| 383 | output Boolean isAccessible; | ||
| 384 | protected | ||
| 385 | Option<AccessLevel> oaccess; | ||
| 386 | AccessLevel access; | ||
| 387 | algorithm | ||
| 388 | 12330 | oaccess := InstNode.getAccessLevel(ComponentRef.node(variable.name)); | |
| 389 | |||
| 390 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 12330 times.
✓ Branch 2 taken 12330 times.
✗ Branch 3 not taken.
|
12330 | if isSome(oaccess) then |
| 391 | ✗ | SOME(access) := oaccess; | |
| 392 | else | ||
| 393 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 12330 times.
|
12330 | access := if isEncrypted(variable) then AccessLevel.DOCUMENTATION else AccessLevel.PACKAGE_DUPLICATE; |
| 394 | end if; | ||
| 395 | |||
| 396 | ✗ | if access < AccessLevel.ICON then | |
| 397 | isAccessible := false; | ||
| 398 | elseif access < AccessLevel.NON_PACKAGE_TEXT then | ||
| 399 | ✗ | isAccessible := not isProtected(variable); | |
| 400 | else | ||
| 401 | isAccessible := true; | ||
| 402 | end if; | ||
| 403 | end isAccessible; | ||
| 404 | |||
| 405 | function isFixed | ||
| 406 | input Variable var; | ||
| 407 | output Boolean fixed; | ||
| 408 | protected | ||
| 409 | Binding binding; | ||
| 410 | algorithm | ||
| 411 | 2 | fixed := if var.attributes.variability < Variability.DISCRETE then true else false; | |
| 412 | 2 | binding := lookupTypeAttribute("fixed", var); | |
| 413 | |||
| 414 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if Binding.hasExp(binding) then |
| 415 | 2 | fixed := Expression.isTrue(Binding.getExp(binding)); | |
| 416 | end if; | ||
| 417 | end isFixed; | ||
| 418 | |||
| 419 | function lookupTypeAttribute | ||
| 420 | input String name; | ||
| 421 | input Variable var; | ||
| 422 | output Binding binding; | ||
| 423 | algorithm | ||
| 424 |
2/2✓ Branch 0 taken 60861 times.
✓ Branch 1 taken 26274 times.
|
87135 | for attr in var.typeAttributes loop |
| 425 |
4/4✓ Branch 1 taken 34726 times.
✓ Branch 2 taken 26135 times.
✓ Branch 5 taken 32863 times.
✓ Branch 6 taken 1863 times.
|
60861 | if Util.tuple21(attr) == name then |
| 426 | 32863 | binding := Util.tuple22(attr); | |
| 427 | 32863 | return; | |
| 428 | end if; | ||
| 429 | end for; | ||
| 430 | |||
| 431 | binding := NFBinding.EMPTY_BINDING; | ||
| 432 | end lookupTypeAttribute; | ||
| 433 | |||
| 434 | function applyToType | ||
| 435 | input output Variable var; | ||
| 436 | input typeFunc func; | ||
| 437 | partial function typeFunc | ||
| 438 | input output Type ty; | ||
| 439 | end typeFunc; | ||
| 440 | algorithm | ||
| 441 |
1/2✓ Branch 0 taken 8348 times.
✗ Branch 1 not taken.
|
8348 | var.ty := func(var.ty); |
| 442 | var.name := ComponentRef.applyToType(var.name, func); | ||
| 443 | end applyToType; | ||
| 444 | |||
| 445 | function propagateAnnotation | ||
| 446 | input String name; | ||
| 447 | input Boolean overwrite; | ||
| 448 | input Boolean evaluate = false; | ||
| 449 | input output Variable var; | ||
| 450 | protected | ||
| 451 | InstNode node; | ||
| 452 | SCode.Mod mod; | ||
| 453 | Absyn.Exp aexp; | ||
| 454 | Expression exp; | ||
| 455 | protected | ||
| 456 | SCode.Annotation anno; | ||
| 457 | InstNode scope; | ||
| 458 | algorithm | ||
| 459 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 378211 times.
|
378211 | if ComponentRef.isCref(var.name) then |
| 460 | 378211 | node := ComponentRef.node(var.name); | |
| 461 | // InstNode.getAnnotation is recursive and returns the first annotation found. | ||
| 462 | // if the original is supposed to be overwritten, skip the node itself and look at the parent | ||
| 463 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 378211 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
378211 | if overwrite and InstNode.isComponent(node) then |
| 464 | ✗ | node := InstNode.parent(node); | |
| 465 | end if; | ||
| 466 | |||
| 467 | 378211 | (mod, scope) := InstNode.getAnnotation(name, node); | |
| 468 | |||
| 469 |
2/2✓ Branch 1 taken 373438 times.
✓ Branch 2 taken 4773 times.
|
378211 | if not SCodeUtil.isEmptyMod(mod) then |
| 470 |
1/2✓ Branch 0 taken 4773 times.
✗ Branch 1 not taken.
|
4773 | if evaluate then |
| 471 | () := matchcontinue mod | ||
| 472 | case SCode.Mod.MOD(binding = SOME(aexp)) | ||
| 473 | algorithm | ||
| 474 | 4773 | exp := Inst.instExp(aexp, scope, NFInstContext.ANNOTATION, mod.info); | |
| 475 | 4773 | exp := Typing.typeExp(exp, NFInstContext.ANNOTATION, mod.info); | |
| 476 | 4773 | exp := Ceval.evalExp(exp); | |
| 477 | 9546 | mod.binding := SOME(Expression.toAbsyn(exp)); | |
| 478 | then | ||
| 479 | (); | ||
| 480 | |||
| 481 | else (); | ||
| 482 | end matchcontinue; | ||
| 483 | end if; | ||
| 484 | |||
| 485 | 9546 | anno := SCode.ANNOTATION(modification = SCode.MOD( | |
| 486 | finalPrefix = SCode.NOT_FINAL(), | ||
| 487 | eachPrefix = SCode.NOT_EACH(), | ||
| 488 | subModLst = {SCode.SubMod.NAMEMOD(name, mod)}, | ||
| 489 | binding = NONE(), | ||
| 490 | comment = NONE(), | ||
| 491 | info = sourceInfo())); | ||
| 492 | 4773 | var.comment := SCodeUtil.appendAnnotationToComment(anno, var.comment, true); | |
| 493 | end if; | ||
| 494 | end if; | ||
| 495 | end propagateAnnotation; | ||
| 496 | |||
| 497 | function removeNonTopLevelDirection | ||
| 498 | "Removes input/output prefixes from a variable that's not a top-level | ||
| 499 | component, a component in a top-level connector, or a component in a | ||
| 500 | top-level input component." | ||
| 501 | input output Variable var; | ||
| 502 | protected | ||
| 503 | ComponentRef rest_name; | ||
| 504 | InstNode node; | ||
| 505 | Attributes attr; | ||
| 506 | algorithm | ||
| 507 |
2/2✓ Branch 0 taken 290160 times.
✓ Branch 1 taken 88058 times.
|
378218 | if var.attributes.direction == Direction.NONE then |
| 508 | 290160 | return; | |
| 509 | end if; | ||
| 510 | |||
| 511 | 88058 | rest_name := ComponentRef.rest(var.name); | |
| 512 |
2/2✓ Branch 1 taken 115865 times.
✓ Branch 2 taken 387 times.
|
116252 | while not ComponentRef.isEmpty(rest_name) loop |
| 513 | 115865 | node := ComponentRef.node(rest_name); | |
| 514 | |||
| 515 |
4/4✓ Branch 1 taken 113019 times.
✓ Branch 2 taken 2846 times.
✓ Branch 4 taken 87671 times.
✓ Branch 5 taken 25348 times.
|
115865 | if not (InstNode.isConnector(node) or InstNode.isInput(node)) then |
| 516 | 87671 | attr := var.attributes; | |
| 517 | 87671 | attr.direction := Direction.NONE; | |
| 518 | 87671 | var.attributes := attr; | |
| 519 | 87671 | return; | |
| 520 | end if; | ||
| 521 | |||
| 522 | 28194 | rest_name := ComponentRef.rest(rest_name); | |
| 523 | end while; | ||
| 524 | end removeNonTopLevelDirection; | ||
| 525 | |||
| 526 | partial function ApplyFn | ||
| 527 | input Expression exp; | ||
| 528 | end ApplyFn; | ||
| 529 | |||
| 530 | function applyExp | ||
| 531 | input Variable var; | ||
| 532 | input ApplyFn fn; | ||
| 533 | algorithm | ||
| 534 | ✗ | Binding.applyExp(var.binding, fn); | |
| 535 | |||
| 536 | ✗ | for ty_attr in var.typeAttributes loop | |
| 537 | ✗ | Binding.applyExp(Util.tuple22(ty_attr), fn); | |
| 538 | end for; | ||
| 539 | |||
| 540 | ✗ | for c in var.children loop | |
| 541 | ✗ | applyExp(c, fn); | |
| 542 | end for; | ||
| 543 | end applyExp; | ||
| 544 | |||
| 545 | function applyExpShallow | ||
| 546 | input Variable var; | ||
| 547 | input ApplyFn fn; | ||
| 548 | algorithm | ||
| 549 | 241182 | Binding.applyExpShallow(var.binding, fn); | |
| 550 | |||
| 551 |
2/2✓ Branch 0 taken 471577 times.
✓ Branch 1 taken 241182 times.
|
712759 | for ty_attr in var.typeAttributes loop |
| 552 | 471577 | Binding.applyExpShallow(Util.tuple22(ty_attr), fn); | |
| 553 | end for; | ||
| 554 | |||
| 555 |
2/2✓ Branch 0 taken 445 times.
✓ Branch 1 taken 241182 times.
|
241627 | for c in var.children loop |
| 556 | 445 | applyExpShallow(c, fn); | |
| 557 | end for; | ||
| 558 | end applyExpShallow; | ||
| 559 | |||
| 560 | partial function MapFn | ||
| 561 | input output Expression exp; | ||
| 562 | end MapFn; | ||
| 563 | |||
| 564 | function mapExp | ||
| 565 | input output Variable var; | ||
| 566 | input MapFn fn; | ||
| 567 | algorithm | ||
| 568 |
8/8✓ Branch 1 taken 29054 times.
✓ Branch 2 taken 21691 times.
✓ Branch 3 taken 29054 times.
✓ Branch 4 taken 21691 times.
✓ Branch 9 taken 1231 times.
✓ Branch 10 taken 21691 times.
✓ Branch 11 taken 1231 times.
✓ Branch 12 taken 21691 times.
|
51976 | var.binding := Binding.mapExp(var.binding, fn); |
| 569 | var.typeAttributes := list( | ||
| 570 | (Util.tuple21(a), Binding.mapExp(Util.tuple22(a), fn)) for a in var.typeAttributes); | ||
| 571 | var.children := list(mapExp(v, fn) for v in var.children); | ||
| 572 | var.backendinfo := BackendInfo.map(var.backendinfo, fn); | ||
| 573 | var.ty := Type.applyToDims(var.ty, func = function Dimension.mapExp(func = fn)); | ||
| 574 | var.name := ComponentRef.mapTypes(var.name, function Type.applyToDims(func = function Dimension.mapExp(func = fn))); | ||
| 575 | end mapExp; | ||
| 576 | |||
| 577 | function mapExpShallow | ||
| 578 | input output Variable var; | ||
| 579 | input MapFn fn; | ||
| 580 | algorithm | ||
| 581 |
8/8✓ Branch 1 taken 1318825 times.
✓ Branch 2 taken 762826 times.
✓ Branch 3 taken 1318825 times.
✓ Branch 4 taken 762826 times.
✓ Branch 9 taken 445 times.
✓ Branch 10 taken 762826 times.
✓ Branch 11 taken 445 times.
✓ Branch 12 taken 762826 times.
|
2082096 | var.binding := Binding.mapExpShallow(var.binding, fn); |
| 582 | var.typeAttributes := list( | ||
| 583 | (Util.tuple21(a), Binding.mapExpShallow(Util.tuple22(a), fn)) for a in var.typeAttributes); | ||
| 584 | var.children := list(mapExpShallow(v, fn) for v in var.children); | ||
| 585 | end mapExpShallow; | ||
| 586 | |||
| 587 | function toString | ||
| 588 | input Variable var; | ||
| 589 | input String indent = ""; | ||
| 590 | input Boolean printBindingType = false; | ||
| 591 | output String str; | ||
| 592 | protected | ||
| 593 | IOStream.IOStream s; | ||
| 594 | algorithm | ||
| 595 | 1086 | s := IOStream.create(getInstanceName(), IOStream.IOStreamType.LIST()); | |
| 596 | 1086 | s := toStream(var, indent, printBindingType, s); | |
| 597 | 1086 | str := IOStream.string(s); | |
| 598 | 1086 | IOStream.delete(s); | |
| 599 | end toString; | ||
| 600 | |||
| 601 | function toStream | ||
| 602 | input Variable var; | ||
| 603 | input String indent = ""; | ||
| 604 | input Boolean printBindingType = false; | ||
| 605 | input output IOStream.IOStream s; | ||
| 606 | protected | ||
| 607 | Boolean first; | ||
| 608 | Binding b; | ||
| 609 | algorithm | ||
| 610 | 1118 | s := IOStream.append(s, indent); | |
| 611 | |||
| 612 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1118 times.
|
1118 | if var.visibility == Visibility.PROTECTED then |
| 613 | ✗ | s := IOStream.append(s, "protected "); | |
| 614 | end if; | ||
| 615 | |||
| 616 | 1118 | s := IOStream.append(s, Attributes.toString(var.attributes, var.ty)); | |
| 617 | 1118 | s := IOStream.append(s, Type.toString(var.ty)); | |
| 618 | 1118 | s := IOStream.append(s, " "); | |
| 619 | 1118 | s := IOStream.append(s, ComponentRef.toString(var.name)); | |
| 620 | |||
| 621 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1118 times.
|
1118 | if not listEmpty(var.typeAttributes) then |
| 622 | ✗ | s := IOStream.append(s, "("); | |
| 623 | |||
| 624 | first := true; | ||
| 625 | ✗ | for a in var.typeAttributes loop | |
| 626 | ✗ | if first then | |
| 627 | first := false; | ||
| 628 | else | ||
| 629 | ✗ | s := IOStream.append(s, ", "); | |
| 630 | end if; | ||
| 631 | |||
| 632 | ✗ | b := Util.tuple22(a); | |
| 633 | |||
| 634 | ✗ | if Binding.isEach(b) then | |
| 635 | ✗ | s := IOStream.append(s, "each "); | |
| 636 | end if; | ||
| 637 | |||
| 638 | ✗ | s := IOStream.append(s, Util.tuple21(a)); | |
| 639 | ✗ | s := IOStream.append(s, " = "); | |
| 640 | ✗ | s := IOStream.append(s, Binding.toString(b)); | |
| 641 | end for; | ||
| 642 | |||
| 643 | ✗ | s := IOStream.append(s, ")"); | |
| 644 | end if; | ||
| 645 | |||
| 646 |
2/2✓ Branch 1 taken 1117 times.
✓ Branch 2 taken 1 time.
|
1118 | if Binding.isBound(var.binding) then |
| 647 | 1 | s := IOStream.append(s, " = "); | |
| 648 | |||
| 649 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1 | if printBindingType then |
| 650 | ✗ | s := IOStream.append(s, "("); | |
| 651 | ✗ | s := IOStream.append(s, Type.toString(Binding.getType(var.binding))); | |
| 652 | ✗ | s := IOStream.append(s, ") "); | |
| 653 | end if; | ||
| 654 | |||
| 655 | 1 | s := IOStream.append(s, Binding.toString(var.binding)); | |
| 656 | end if; | ||
| 657 | end toStream; | ||
| 658 | |||
| 659 | function toFlatStream | ||
| 660 | input Variable var; | ||
| 661 | input BaseModelica.OutputFormat format; | ||
| 662 | input String indent = ""; | ||
| 663 | input Boolean printBindingType = false; | ||
| 664 | input output IOStream.IOStream s; | ||
| 665 | protected | ||
| 666 | list<Dimension> dims; | ||
| 667 | algorithm | ||
| 668 | 847 | s := IOStream.append(s, indent); | |
| 669 | |||
| 670 | 847 | s := Attributes.toFlatStream(var.attributes, var.ty, s, ComponentRef.isSimple(var.name)); | |
| 671 | 847 | s := IOStream.append(s, Type.toFlatString(Type.arrayElementType(var.ty), format)); | |
| 672 | 847 | s := IOStream.append(s, " "); | |
| 673 | 847 | s := IOStream.append(s, ComponentRef.toFlatString(var.name, format)); | |
| 674 | |||
| 675 | 847 | dims := Type.arrayDims(var.ty); | |
| 676 |
2/2✓ Branch 0 taken 197 times.
✓ Branch 1 taken 650 times.
|
847 | if not listEmpty(dims) then |
| 677 | 197 | s := IOStream.append(s, Dimension.toFlatStringList(dims, format)); | |
| 678 | end if; | ||
| 679 | |||
| 680 |
2/2✓ Branch 0 taken 23 times.
✓ Branch 1 taken 824 times.
|
847 | if not listEmpty(var.typeAttributes) then |
| 681 | 23 | s := Component.typeAttrsToFlatStream(var.typeAttributes, var.ty, format, s); | |
| 682 | elseif not listEmpty(var.children) then | ||
| 683 |
3/4✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 26 times.
✓ Branch 4 taken 89 times.
|
141 | s := toFlatStreamModifier(var.children, format.moveBindings or Binding.isBound(var.binding), printBindingType, format, s); |
| 684 | end if; | ||
| 685 | |||
| 686 | 847 | s := toFlatStreamBinding(var.binding, printBindingType, format, s); | |
| 687 | 847 | s := FlatModelicaUtil.appendComment(var.comment, NFFlatModelicaUtil.ElementType.COMPONENT, s); | |
| 688 | end toFlatStream; | ||
| 689 | |||
| 690 | function toFlatStreamBinding | ||
| 691 | input Binding binding; | ||
| 692 | input Boolean printBindingType; | ||
| 693 | input BaseModelica.OutputFormat format; | ||
| 694 | input output IOStream.IOStream s; | ||
| 695 | algorithm | ||
| 696 |
2/2✓ Branch 1 taken 655 times.
✓ Branch 2 taken 205 times.
|
860 | if Binding.isBound(binding) then |
| 697 | 205 | s := IOStream.append(s, " = "); | |
| 698 | |||
| 699 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 205 times.
|
205 | if printBindingType then |
| 700 | ✗ | s := IOStream.append(s, "("); | |
| 701 | ✗ | s := IOStream.append(s, Type.toFlatString(Binding.getType(binding), format)); | |
| 702 | ✗ | s := IOStream.append(s, ") "); | |
| 703 | end if; | ||
| 704 | |||
| 705 | 205 | s := IOStream.append(s, Binding.toFlatString(binding, format)); | |
| 706 | end if; | ||
| 707 | end toFlatStreamBinding; | ||
| 708 | |||
| 709 | function toFlatStreamModifier | ||
| 710 | input list<Variable> children; | ||
| 711 | input Boolean overwrittenBinding; | ||
| 712 | input Boolean printBindingType; | ||
| 713 | input BaseModelica.OutputFormat format; | ||
| 714 | input output IOStream.IOStream s; | ||
| 715 | protected | ||
| 716 | Boolean empty = true; | ||
| 717 | Boolean overwritten_binding; | ||
| 718 | IOStream.IOStream ss; | ||
| 719 | Binding.Source src; | ||
| 720 | algorithm | ||
| 721 |
2/2✓ Branch 0 taken 394 times.
✓ Branch 1 taken 133 times.
|
527 | for child in children loop |
| 722 | 394 | ss := IOStream.create(getInstanceName(), IOStream.IOStreamType.LIST()); | |
| 723 | |||
| 724 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 389 times.
|
394 | if not listEmpty(child.typeAttributes) then |
| 725 | 5 | ss := Component.typeAttrsToFlatStream(child.typeAttributes, child.ty, format, ss); | |
| 726 | elseif not listEmpty(child.children) then | ||
| 727 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
|
18 | overwritten_binding := overwrittenBinding or Binding.isBound(child.binding); |
| 728 | 18 | ss := toFlatStreamModifier(child.children, overwritten_binding, printBindingType, format, ss); | |
| 729 | end if; | ||
| 730 | |||
| 731 |
2/2✓ Branch 0 taken 298 times.
✓ Branch 1 taken 96 times.
|
394 | if not overwrittenBinding then |
| 732 | 298 | src := Binding.source(child.binding); | |
| 733 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 285 times.
|
298 | if src == NFBinding.Source.MODIFIER or src == NFBinding.Source.GENERATED then |
| 734 | 13 | ss := toFlatStreamBinding(child.binding, printBindingType, format, ss); | |
| 735 | end if; | ||
| 736 | end if; | ||
| 737 | |||
| 738 |
2/2✓ Branch 1 taken 17 times.
✓ Branch 2 taken 377 times.
|
394 | if not IOStream.empty(ss) then |
| 739 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 4 times.
|
17 | if empty then |
| 740 | 13 | s := IOStream.append(s, "("); | |
| 741 | empty := false; | ||
| 742 | else | ||
| 743 | 4 | s := IOStream.append(s, ", "); | |
| 744 | end if; | ||
| 745 | |||
| 746 | 17 | s := IOStream.append(s, Util.makeQuotedIdentifier(ComponentRef.firstName(child.name))); | |
| 747 | 17 | s := IOStream.appendListStream(ss, s); | |
| 748 | end if; | ||
| 749 | end for; | ||
| 750 | |||
| 751 |
2/2✓ Branch 0 taken 120 times.
✓ Branch 1 taken 13 times.
|
133 | if not empty then |
| 752 | 13 | s := IOStream.append(s, ")"); | |
| 753 | end if; | ||
| 754 | end toFlatStreamModifier; | ||
| 755 | |||
| 756 | function moveBinding | ||
| 757 | "Removes the binding of the variable, if it has one and it has at least | ||
| 758 | discrete variability, and creates an equation from it." | ||
| 759 | input output Variable var; | ||
| 760 | input output list<Equation> equations; | ||
| 761 | algorithm | ||
| 762 | ✗ | if variability(var) >= Variability.DISCRETE and Binding.isBound(var.binding) then | |
| 763 | ✗ | equations := Equation.makeEquality(Expression.fromCref(var.name), | |
| 764 | Binding.getExp(var.binding), var.ty, | ||
| 765 | ElementSource.createElementSource(var.info)) :: equations; | ||
| 766 | ✗ | var.binding := NFBinding.EMPTY_BINDING; | |
| 767 | end if; | ||
| 768 | end moveBinding; | ||
| 769 | |||
| 770 | function getVariableAttributes | ||
| 771 | input Variable var; | ||
| 772 | output VariableAttributes variableAttributes = var.backendinfo.attributes; | ||
| 773 | end getVariableAttributes; | ||
| 774 | |||
| 775 | function getNominal | ||
| 776 | input Variable var; | ||
| 777 | output Option<Expression> nominal = VariableAttributes.getNominal(getVariableAttributes(var)); | ||
| 778 | end getNominal; | ||
| 779 | |||
| 780 | function asBinding | ||
| 781 | input Variable var; | ||
| 782 | input Binding.Source source = NFBinding.Source.GENERATED; | ||
| 783 | output Binding binding; | ||
| 784 | algorithm | ||
| 785 | 11 | binding := Binding.makeFlat(Expression.fromTypedCref(var.name, var.ty), variability(var), source); | |
| 786 | end asBinding; | ||
| 787 | |||
| 788 | annotation(__OpenModelica_Interface="nf_frontend"); | ||
| 789 | end NFVariable; | ||
| 790 |