OMCompiler/Compiler/FFrontEnd/FGraph.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 FGraph | ||
| 37 | " file: FGraph.mo | ||
| 38 | package: FGraph | ||
| 39 | description: Graph of program | ||
| 40 | |||
| 41 | |||
| 42 | " | ||
| 43 | |||
| 44 | // public imports | ||
| 45 | public | ||
| 46 | import Absyn; | ||
| 47 | import AbsynUtil; | ||
| 48 | import SCode; | ||
| 49 | import DAE; | ||
| 50 | import ClassInf; | ||
| 51 | import FCore; | ||
| 52 | import FNode; | ||
| 53 | import InnerOuter; | ||
| 54 | import FCore.RefTree; | ||
| 55 | |||
| 56 | protected | ||
| 57 | import List; | ||
| 58 | import Util; | ||
| 59 | import System; | ||
| 60 | import Debug; | ||
| 61 | import FGraphBuildEnv; | ||
| 62 | import Global; | ||
| 63 | import Config; | ||
| 64 | import PrefixUtil; | ||
| 65 | import Flags; | ||
| 66 | import SCodeDump; | ||
| 67 | import MetaModelica.Dangerous; | ||
| 68 | import Mod; | ||
| 69 | import Error; | ||
| 70 | import ComponentReference; | ||
| 71 | import Types; | ||
| 72 | import SCodeUtil; | ||
| 73 | |||
| 74 | public | ||
| 75 | type Name = FCore.Name; | ||
| 76 | type Id = FCore.Id; | ||
| 77 | type Seq = FCore.Seq; | ||
| 78 | type Next = FCore.Next; | ||
| 79 | type Node = FCore.Node; | ||
| 80 | type Data = FCore.Data; | ||
| 81 | type Kind = FCore.Kind; | ||
| 82 | type Ref = FCore.Ref; | ||
| 83 | type Refs = FCore.Refs; | ||
| 84 | type Children = FCore.Children; | ||
| 85 | type Parents = FCore.Parents; | ||
| 86 | type Scope = FCore.Scope; | ||
| 87 | type Top = FCore.Top; | ||
| 88 | type Graph = FCore.Graph; | ||
| 89 | type Extra = FCore.Extra; | ||
| 90 | type Visited = FCore.Visited; | ||
| 91 | type Status = FCore.Status; | ||
| 92 | |||
| 93 | constant FCore.Graph emptyGraph = FCore.EG("empty"); | ||
| 94 | |||
| 95 | public function top | ||
| 96 | "get the top node ref from the graph" | ||
| 97 | input Graph inGraph; | ||
| 98 | output Ref outRef; | ||
| 99 | algorithm | ||
| 100 | outRef := match inGraph | ||
| 101 | 49812 | case FCore.G() then inGraph.top.node; | |
| 102 | end match; | ||
| 103 | end top; | ||
| 104 | |||
| 105 | public function extra | ||
| 106 | "get the extra from the graph" | ||
| 107 | input Graph inGraph; | ||
| 108 | output Extra outExtra; | ||
| 109 | algorithm | ||
| 110 | outExtra := match inGraph | ||
| 111 | ✗ | case FCore.G() then inGraph.top.extra; | |
| 112 | end match; | ||
| 113 | end extra; | ||
| 114 | |||
| 115 | public function currentScope | ||
| 116 | "get the top current scope from the graph" | ||
| 117 | input Graph inGraph; | ||
| 118 | output Scope outScope; | ||
| 119 | algorithm | ||
| 120 | outScope := match inGraph | ||
| 121 | case FCore.G(scope = outScope) then outScope; | ||
| 122 | case FCore.EG(_) then {}; | ||
| 123 | end match; | ||
| 124 | end currentScope; | ||
| 125 | |||
| 126 | public function lastScopeRef | ||
| 127 | "get the last ref from the current scope the graph" | ||
| 128 | input Graph inGraph; | ||
| 129 | output Ref outRef; | ||
| 130 | algorithm | ||
| 131 | 37999851 | outRef := listHead(currentScope(inGraph)); | |
| 132 | end lastScopeRef; | ||
| 133 | |||
| 134 | public function setLastScopeRef | ||
| 135 | input Ref inRef; | ||
| 136 | input Graph inGraph; | ||
| 137 | output Graph outGraph = inGraph; | ||
| 138 | algorithm | ||
| 139 | outGraph := match outGraph | ||
| 140 | case FCore.G() | ||
| 141 | algorithm | ||
| 142 | ✗ | outGraph.scope := inRef :: listRest(outGraph.scope); | |
| 143 | then | ||
| 144 | outGraph; | ||
| 145 | |||
| 146 | else outGraph; | ||
| 147 | end match; | ||
| 148 | end setLastScopeRef; | ||
| 149 | |||
| 150 | public function stripLastScopeRef | ||
| 151 | "remove the last ref from the current scope the graph" | ||
| 152 | input Graph inGraph; | ||
| 153 | output Graph outGraph; | ||
| 154 | output Ref outRef; | ||
| 155 | protected | ||
| 156 | Top t; | ||
| 157 | Scope s; | ||
| 158 | algorithm | ||
| 159 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 5792092 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5792092 times.
|
5792092 | FCore.G(t, outRef::s) := inGraph; |
| 160 | // strip the last scope ref | ||
| 161 | 5792092 | outGraph := FCore.G(t, s); | |
| 162 | end stripLastScopeRef; | ||
| 163 | |||
| 164 | public function topScope | ||
| 165 | "remove all the scopes, leave just the top one from the graph scopes" | ||
| 166 | input Graph inGraph; | ||
| 167 | output Graph outGraph; | ||
| 168 | algorithm | ||
| 169 | // leave only the top scope | ||
| 170 | outGraph := match inGraph | ||
| 171 | 466614 | case FCore.G() then FCore.G(inGraph.top, {inGraph.top.node}); | |
| 172 | end match; | ||
| 173 | end topScope; | ||
| 174 | |||
| 175 | public function empty | ||
| 176 | "make an empty graph" | ||
| 177 | output Graph outGraph; | ||
| 178 | algorithm | ||
| 179 | outGraph := emptyGraph; | ||
| 180 | end empty; | ||
| 181 | |||
| 182 | public function new | ||
| 183 | "make a new graph" | ||
| 184 | input Name inGraphName; | ||
| 185 | input Absyn.Path inPath; | ||
| 186 | output Graph outGraph; | ||
| 187 | protected | ||
| 188 | Node n; | ||
| 189 | Scope s; | ||
| 190 | Ref nr; | ||
| 191 | Id id; | ||
| 192 | Top top; | ||
| 193 | algorithm | ||
| 194 | 3423 | id := System.tmpTickIndex(Global.fgraph_nextId); | |
| 195 | 3423 | n := FNode.new(FNode.topNodeName, id, {}, FCore.TOP()); | |
| 196 | 3423 | nr := FNode.toRef(n); | |
| 197 | s := {nr}; | ||
| 198 | 3423 | top := FCore.GTOP(inGraphName,nr,FCore.EXTRA(inPath)); | |
| 199 | 3423 | outGraph := FCore.G(top,s); | |
| 200 | end new; | ||
| 201 | |||
| 202 | public function node | ||
| 203 | "make a new node in the graph" | ||
| 204 | input Graph inGraph; | ||
| 205 | input Name inName; | ||
| 206 | input Parents inParents; | ||
| 207 | input Data inData; | ||
| 208 | output Graph outGraph; | ||
| 209 | output Node outNode; | ||
| 210 | algorithm | ||
| 211 | (outGraph, outNode) := match inGraph | ||
| 212 | local | ||
| 213 | Integer i; | ||
| 214 | Graph g; | ||
| 215 | Node n; | ||
| 216 | |||
| 217 | case g | ||
| 218 | algorithm | ||
| 219 | 12301446 | i := System.tmpTickIndex(Global.fgraph_nextId); | |
| 220 | 12301446 | n := FNode.new(inName, i, inParents, inData); | |
| 221 | // uncomment this if unique node id's are not unique! | ||
| 222 | /* | ||
| 223 | b = (id == i); | ||
| 224 | Debug.bcall1(true, print, "Next: " + intString(id) + " <-> " + intString(i) + " node: " + FNode.toStr(n) + "\n"); | ||
| 225 | // true = b; | ||
| 226 | */ | ||
| 227 | then | ||
| 228 | (g, n); | ||
| 229 | |||
| 230 | end match; | ||
| 231 | end node; | ||
| 232 | |||
| 233 | public function clone | ||
| 234 | "@author: adrpo | ||
| 235 | clone a graph. everything is copied except visited information and refs (which will be new)" | ||
| 236 | input Graph inGraph; | ||
| 237 | output Graph outGraph; | ||
| 238 | algorithm | ||
| 239 | outGraph := match inGraph | ||
| 240 | local | ||
| 241 | Graph g; | ||
| 242 | Top t; | ||
| 243 | Ref nt; | ||
| 244 | Scope s; | ||
| 245 | case FCore.G(t, s) | ||
| 246 | algorithm | ||
| 247 | // make a new top | ||
| 248 | 29048 | nt := FNode.toRef(FNode.fromRef(t.node)); | |
| 249 | // make new graph | ||
| 250 | // g = FCore.G(t, s); | ||
| 251 | // deep copy the top, clone the entire subtree, update references | ||
| 252 | 29048 | (g, nt) := FNode.copyRef(nt, inGraph); | |
| 253 | // update scope references | ||
| 254 | 29048 | s := List.map1r(s, FNode.lookupRefFromRef, nt); | |
| 255 | 29048 | t := FCore.GTOP(t.name, nt, t.extra); | |
| 256 | 29048 | g := FCore.G(t, s); | |
| 257 | then g; | ||
| 258 | |||
| 259 | end match; | ||
| 260 | end clone; | ||
| 261 | |||
| 262 | public function updateComp | ||
| 263 | "This function updates a component already added to the graph, but | ||
| 264 | that prior to the update did not have any binding. I.e this function is | ||
| 265 | called in the second stage of instantiation with declare before use." | ||
| 266 | input Graph inGraph; | ||
| 267 | input DAE.Var inVar; | ||
| 268 | input FCore.Status instStatus; | ||
| 269 | input Graph inTargetGraph; | ||
| 270 | output Graph outGraph; | ||
| 271 | algorithm | ||
| 272 | outGraph := matchcontinue (inGraph, inVar) | ||
| 273 | local | ||
| 274 | Ref pr, r; | ||
| 275 | Name n; | ||
| 276 | Id id; | ||
| 277 | FCore.WeakParents p; | ||
| 278 | Children c; | ||
| 279 | SCode.Element e; | ||
| 280 | DAE.Var v; | ||
| 281 | DAE.Mod m; | ||
| 282 | Kind k; | ||
| 283 | Graph g; | ||
| 284 | |||
| 285 | // update in the current frame | ||
| 286 | case (g, v as DAE.TYPES_VAR(name = n)) | ||
| 287 | algorithm | ||
| 288 | 709602 | pr := lastScopeRef(g); | |
| 289 | 709602 | r := FNode.child(pr, n); | |
| 290 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 616965 times.
|
616965 | FCore.N(n, id, p, c, FCore.CO(e, m, k, _)) := FNode.fromRef(r); |
| 291 | 616965 | r := FNode.updateRef(r, FCore.N(n, id, p, c, FCore.CO(e, m, k, instStatus))); | |
| 292 | // update the target scope | ||
| 293 | 616965 | r := updateSourceTargetScope(r, currentScope(inTargetGraph)); | |
| 294 | 616965 | r := updateInstance(r, v); | |
| 295 | then | ||
| 296 | g; | ||
| 297 | |||
| 298 | // if not found update in the parent frame | ||
| 299 | case (g, v) | ||
| 300 | algorithm | ||
| 301 | 92637 | pr := lastScopeRef(g); | |
| 302 |
1/2✓ Branch 1 taken 92637 times.
✗ Branch 2 not taken.
|
92637 | true := FNode.isImplicitRefName(pr); |
| 303 | ✗ | (g, _) := stripLastScopeRef(g); | |
| 304 | ✗ | g := updateComp(g, v, instStatus, inTargetGraph); | |
| 305 | then | ||
| 306 | g; | ||
| 307 | |||
| 308 | // do NOT fail! | ||
| 309 | else inGraph; | ||
| 310 | |||
| 311 | end matchcontinue; | ||
| 312 | end updateComp; | ||
| 313 | |||
| 314 | public function updateSourceTargetScope | ||
| 315 | "update the class scope in the source" | ||
| 316 | input Ref inRef; | ||
| 317 | input Scope inTargetScope; | ||
| 318 | output Ref outRef; | ||
| 319 | algorithm | ||
| 320 | outRef := matchcontinue inRef | ||
| 321 | local | ||
| 322 | Ref r; | ||
| 323 | |||
| 324 | // update the target scope of the node, hopefully existing | ||
| 325 | case r | ||
| 326 | algorithm | ||
| 327 | 1829551 | r := FNode.refRef(r); | |
| 328 | 1829551 | r := FNode.updateRef(r, FNode.setData(FNode.fromRef(r), FCore.REF(inTargetScope))); | |
| 329 | then | ||
| 330 | inRef; | ||
| 331 | |||
| 332 | // create one and update it | ||
| 333 | case r | ||
| 334 | algorithm | ||
| 335 | ✗ | Error.addCompilerWarning("FNode.updateSourceTargetScope: node does not yet have a reference child: " + FNode.toPathStr(FNode.fromRef(r)) + | |
| 336 | " target scope: " + FNode.scopeStr(inTargetScope) + "\n"); | ||
| 337 | then | ||
| 338 | inRef; | ||
| 339 | |||
| 340 | end matchcontinue; | ||
| 341 | end updateSourceTargetScope; | ||
| 342 | |||
| 343 | public function updateInstance | ||
| 344 | "update the class scope in the source" | ||
| 345 | input Ref inRef; | ||
| 346 | input DAE.Var inVar; | ||
| 347 | output Ref outRef; | ||
| 348 | algorithm | ||
| 349 | outRef := matchcontinue inRef | ||
| 350 | local | ||
| 351 | Ref r; | ||
| 352 | |||
| 353 | // update the instance node | ||
| 354 | case r | ||
| 355 | algorithm | ||
| 356 | 1808836 | r := FNode.refInstance(r); | |
| 357 | 1808836 | r := FNode.updateRef(r, FNode.setData(FNode.fromRef(r), FCore.IT(inVar))); | |
| 358 | then | ||
| 359 | inRef; | ||
| 360 | |||
| 361 | else | ||
| 362 | algorithm | ||
| 363 | ✗ | Error.addCompilerError("FGraph.updateInstance failed for node: " + FNode.toPathStr(FNode.fromRef(inRef)) + " variable:" + TypesDump.printVarStr(inVar)); | |
| 364 | ✗ | then | |
| 365 | fail(); | ||
| 366 | |||
| 367 | end matchcontinue; | ||
| 368 | end updateInstance; | ||
| 369 | |||
| 370 | protected function updateVarAndMod | ||
| 371 | "update the component data" | ||
| 372 | input Graph inGraph; | ||
| 373 | input DAE.Var inVar; | ||
| 374 | input DAE.Mod inMod; | ||
| 375 | input FCore.Status instStatus; | ||
| 376 | input Graph inTargetGraph; | ||
| 377 | output Graph outGraph; | ||
| 378 | algorithm | ||
| 379 | outGraph := matchcontinue (inGraph, inVar) | ||
| 380 | local | ||
| 381 | Ref pr, r; | ||
| 382 | Name n; | ||
| 383 | Id id; | ||
| 384 | FCore.WeakParents p; | ||
| 385 | Children c; | ||
| 386 | SCode.Element e; | ||
| 387 | DAE.Var v; | ||
| 388 | Kind k; | ||
| 389 | Graph g; | ||
| 390 | |||
| 391 | // update in the current frame | ||
| 392 | case (g, v as DAE.TYPES_VAR(name = n)) | ||
| 393 | algorithm | ||
| 394 | 1191871 | pr := lastScopeRef(g); | |
| 395 | 1191871 | r := FNode.child(pr, n); | |
| 396 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1191871 times.
|
1191871 | FCore.N(n, id, p, c, FCore.CO(e, _, k, _)) := FNode.fromRef(r); |
| 397 | 1191871 | r := FNode.updateRef(r, FCore.N(n, id, p, c, FCore.CO(e, inMod, k, instStatus))); | |
| 398 | 1191871 | r := updateSourceTargetScope(r, currentScope(inTargetGraph)); | |
| 399 | 1191871 | r := updateInstance(r, v); | |
| 400 | then | ||
| 401 | g; | ||
| 402 | |||
| 403 | // if not found update in the parent frame | ||
| 404 | case (g, v) | ||
| 405 | algorithm | ||
| 406 | ✗ | pr := lastScopeRef(g); | |
| 407 | ✗ | true := FNode.isImplicitRefName(pr); | |
| 408 | ✗ | (g, _) := stripLastScopeRef(g); | |
| 409 | ✗ | g := updateVarAndMod(g, v, inMod, instStatus, inTargetGraph); | |
| 410 | then | ||
| 411 | g; | ||
| 412 | |||
| 413 | // do NOT fail! | ||
| 414 | else inGraph; | ||
| 415 | |||
| 416 | end matchcontinue; | ||
| 417 | end updateVarAndMod; | ||
| 418 | |||
| 419 | public function updateClass | ||
| 420 | "This function updates a class element in the graph" | ||
| 421 | input Graph inGraph; | ||
| 422 | input SCode.Element inElement; | ||
| 423 | input DAE.Prefix inPrefix; | ||
| 424 | input DAE.Mod inMod; | ||
| 425 | input FCore.Status instStatus; | ||
| 426 | input Graph inTargetGraph; | ||
| 427 | output Graph outGraph; | ||
| 428 | algorithm | ||
| 429 | outGraph := matchcontinue (inGraph, inElement) | ||
| 430 | local | ||
| 431 | Ref pr, r; | ||
| 432 | Name n; | ||
| 433 | Id id; | ||
| 434 | FCore.WeakParents p; | ||
| 435 | Children c; | ||
| 436 | SCode.Element e; | ||
| 437 | Kind k; | ||
| 438 | Graph g; | ||
| 439 | |||
| 440 | // update in the current frame | ||
| 441 | case (g, e as SCode.CLASS(name = n)) | ||
| 442 | algorithm | ||
| 443 | 8304 | pr := lastScopeRef(g); | |
| 444 | 8304 | r := FNode.child(pr, n); | |
| 445 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8304 times.
|
8304 | FCore.N(n, id, p, c, FCore.CL(_, _, _, k, _)) := FNode.fromRef(r); |
| 446 | 8304 | r := FNode.updateRef(r, FCore.N(n, id, p, c, FCore.CL(e, inPrefix, inMod, k, instStatus))); | |
| 447 | // r = updateSourceTargetScope(r, currentScope(inTargetGraph)); | ||
| 448 | then | ||
| 449 | g; | ||
| 450 | |||
| 451 | // if not found update in the parent frame | ||
| 452 | case (g, e) | ||
| 453 | algorithm | ||
| 454 | ✗ | pr := lastScopeRef(g); | |
| 455 | ✗ | true := FNode.isImplicitRefName(pr); | |
| 456 | ✗ | (g, _) := stripLastScopeRef(g); | |
| 457 | ✗ | g := updateClass(g, e, inPrefix, inMod, instStatus, inTargetGraph); | |
| 458 | then | ||
| 459 | g; | ||
| 460 | end matchcontinue; | ||
| 461 | end updateClass; | ||
| 462 | |||
| 463 | public function updateClassElement | ||
| 464 | "This function updates a class element in the given parent ref" | ||
| 465 | input Ref inRef; | ||
| 466 | input SCode.Element inElement; | ||
| 467 | input DAE.Prefix inPrefix; | ||
| 468 | input DAE.Mod inMod; | ||
| 469 | input FCore.Status instStatus; | ||
| 470 | input Graph inTargetGraph; | ||
| 471 | output Ref outRef; | ||
| 472 | algorithm | ||
| 473 | outRef := match (inRef, inElement) | ||
| 474 | local | ||
| 475 | Ref r; | ||
| 476 | Name n; | ||
| 477 | Id id; | ||
| 478 | FCore.WeakParents p; | ||
| 479 | Children c; | ||
| 480 | SCode.Element e; | ||
| 481 | Kind k; | ||
| 482 | |||
| 483 | case (r, e as SCode.CLASS(name = n)) | ||
| 484 | algorithm | ||
| 485 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20715 times.
|
20715 | FCore.N(_, id, p, c, FCore.CL(_, _, _, k, _)) := FNode.fromRef(r); |
| 486 | 20715 | r := FNode.updateRef(r, FCore.N(n, id, p, c, FCore.CL(e, inPrefix, inMod, k, instStatus))); | |
| 487 | then | ||
| 488 | r; | ||
| 489 | |||
| 490 | end match; | ||
| 491 | end updateClassElement; | ||
| 492 | |||
| 493 | public function addForIterator | ||
| 494 | "Adds a for loop iterator to the graph." | ||
| 495 | input Graph inGraph; | ||
| 496 | input String name; | ||
| 497 | input DAE.Type ty; | ||
| 498 | input DAE.Binding binding; | ||
| 499 | input SCode.Variability variability; | ||
| 500 | input Option<DAE.Const> constOfForIteratorRange; | ||
| 501 | output Graph outGraph; | ||
| 502 | algorithm | ||
| 503 | outGraph := match inGraph | ||
| 504 | local | ||
| 505 | Graph g; | ||
| 506 | Ref r; | ||
| 507 | SCode.Element c; | ||
| 508 | DAE.Var v; | ||
| 509 | |||
| 510 | case g | ||
| 511 | algorithm | ||
| 512 | 7544 | c := SCode.COMPONENT( | |
| 513 | name, | ||
| 514 | SCode.defaultPrefixes, | ||
| 515 | SCode.ATTR({}, SCode.POTENTIAL(), SCode.NON_PARALLEL(), SCode.CONST(), Absyn.BIDIR(), Absyn.NONFIELD()), | ||
| 516 | Absyn.TPATH(Absyn.IDENT(""), NONE()), SCode.NOMOD(), | ||
| 517 | SCode.noComment, NONE(), Absyn.dummyInfo); | ||
| 518 | 7544 | v := DAE.TYPES_VAR( | |
| 519 | name, | ||
| 520 | DAE.ATTR(DAE.NON_CONNECTOR(), SCode.NON_PARALLEL(), variability, Absyn.BIDIR(), Absyn.NOT_INNER_OUTER(), SCode.PUBLIC()), | ||
| 521 | ty, | ||
| 522 | binding, | ||
| 523 | false, | ||
| 524 | constOfForIteratorRange); | ||
| 525 | 7544 | r := lastScopeRef(g); | |
| 526 | 7544 | g := FGraphBuildEnv.mkCompNode(c, r, FCore.BUILTIN(), g); | |
| 527 | // update the var too! | ||
| 528 | 7544 | g := updateVarAndMod(g, v, DAE.NOMOD(), FCore.VAR_UNTYPED(), empty()); | |
| 529 | then | ||
| 530 | g; | ||
| 531 | |||
| 532 | end match; | ||
| 533 | end addForIterator; | ||
| 534 | |||
| 535 | public function printGraphPathStr "Retrive the graph current scope path as a string" | ||
| 536 | input Graph inGraph; | ||
| 537 | output String outString; | ||
| 538 | algorithm | ||
| 539 | outString := matchcontinue inGraph | ||
| 540 | local | ||
| 541 | String str; | ||
| 542 | Scope s; | ||
| 543 | |||
| 544 | case FCore.G(scope = s as _::_::_) | ||
| 545 | algorithm | ||
| 546 | // remove top | ||
| 547 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 188184 times.
|
188184 | _::s := listReverse(s); |
| 548 | 188184 | str := stringDelimitList(List.map(s, FNode.refName), "."); | |
| 549 | then | ||
| 550 | str; | ||
| 551 | |||
| 552 | else "<global scope>"; | ||
| 553 | |||
| 554 | end matchcontinue; | ||
| 555 | end printGraphPathStr; | ||
| 556 | |||
| 557 | public function openNewScope | ||
| 558 | "Opening a new scope in the graph means adding a new node in the current scope." | ||
| 559 | input Graph inGraph; | ||
| 560 | input SCode.Encapsulated encapsulatedPrefix; | ||
| 561 | input Option<Name> inName; | ||
| 562 | input Option<FCore.ScopeType> inScopeType; | ||
| 563 | output Graph outGraph; | ||
| 564 | algorithm | ||
| 565 | outGraph := matchcontinue(inGraph, inName) | ||
| 566 | local | ||
| 567 | Graph g; | ||
| 568 | Name n; | ||
| 569 | Node no; | ||
| 570 | Ref r, p; | ||
| 571 | |||
| 572 | // else open a new scope! | ||
| 573 | case (g, SOME(n)) | ||
| 574 | algorithm | ||
| 575 | 5164 | p := lastScopeRef(g); | |
| 576 | 5164 | (g, no) := node(g, n, {p}, FCore.ND(inScopeType)); | |
| 577 | 5164 | r := FNode.toRef(no); | |
| 578 | // FNode.addChildRef(p, n, r); | ||
| 579 | 5164 | g := pushScopeRef(g, r); | |
| 580 | then | ||
| 581 | g; | ||
| 582 | |||
| 583 | else | ||
| 584 | algorithm | ||
| 585 | ✗ | Error.addCompilerError("FGraph.openNewScope: failed to open new scope in scope: " + getGraphNameStr(inGraph) + " name: " + Util.getOptionOrDefault(inName, "") + "\n"); | |
| 586 | ✗ | then | |
| 587 | fail(); | ||
| 588 | |||
| 589 | end matchcontinue; | ||
| 590 | end openNewScope; | ||
| 591 | |||
| 592 | public function openScope | ||
| 593 | "Opening a new scope in the graph means adding a new node in the current scope." | ||
| 594 | input Graph inGraph; | ||
| 595 | input SCode.Encapsulated encapsulatedPrefix; | ||
| 596 | input Name inName; | ||
| 597 | input Option<FCore.ScopeType> inScopeType; | ||
| 598 | output Graph outGraph; | ||
| 599 | protected | ||
| 600 | Ref p; | ||
| 601 | algorithm | ||
| 602 | 2689483 | p := lastScopeRef(inGraph); | |
| 603 | outGraph := matchcontinue(inGraph, inName) | ||
| 604 | local | ||
| 605 | Graph g; | ||
| 606 | Name n; | ||
| 607 | Node no; | ||
| 608 | Ref r; | ||
| 609 | |||
| 610 | // see if we have it as a class instance | ||
| 611 | case (g, n) | ||
| 612 | algorithm | ||
| 613 | 2689483 | r := FNode.child(p, n); | |
| 614 |
4/4✓ Branch 1 taken 1781 times.
✓ Branch 2 taken 2450044 times.
✓ Branch 3 taken 2424230 times.
✓ Branch 4 taken 25814 times.
|
2451825 | FCore.CL(status = FCore.CLS_INSTANCE(_)) := FNode.refData(r); |
| 615 | 25814 | FNode.addChildRef(p, n, r); | |
| 616 | 25814 | g := pushScopeRef(g, r); | |
| 617 | then | ||
| 618 | g; | ||
| 619 | |||
| 620 | // see if we have a child with the same name! | ||
| 621 | case (g, n) | ||
| 622 | algorithm | ||
| 623 | 2663669 | r := FNode.child(p, n); | |
| 624 | 2426011 | r := FNode.copyRefNoUpdate(r); | |
| 625 | // FNode.addChildRef(p, n, r); | ||
| 626 | 2426011 | g := pushScopeRef(g, r); | |
| 627 | then | ||
| 628 | g; | ||
| 629 | |||
| 630 | // else open a new scope! | ||
| 631 | case (g, n) | ||
| 632 | algorithm | ||
| 633 | 237658 | (g, no) := node(g, n, {p}, FCore.ND(inScopeType)); | |
| 634 | 237658 | r := FNode.toRef(no); | |
| 635 | // FNode.addChildRef(p, n, r); | ||
| 636 | 237658 | g := pushScopeRef(g, r); | |
| 637 | then | ||
| 638 | g; | ||
| 639 | |||
| 640 | else | ||
| 641 | algorithm | ||
| 642 | ✗ | Error.addCompilerError("FGraph.openScope: failed to open new scope in scope: " + getGraphNameStr(inGraph) + " name: " + inName + "\n"); | |
| 643 | ✗ | then | |
| 644 | fail(); | ||
| 645 | |||
| 646 | end matchcontinue; | ||
| 647 | end openScope; | ||
| 648 | |||
| 649 | public function inForLoopScope "returns true if environment has a frame that is a for loop" | ||
| 650 | input Graph inGraph; | ||
| 651 | output Boolean res; | ||
| 652 | algorithm | ||
| 653 | res := matchcontinue inGraph | ||
| 654 | local | ||
| 655 | String name; | ||
| 656 | |||
| 657 | case _ | ||
| 658 | algorithm | ||
| 659 | 1797 | name := FNode.refName(listHead(currentScope(inGraph))); | |
| 660 |
4/4✓ Branch 0 taken 823 times.
✓ Branch 1 taken 974 times.
✓ Branch 3 taken 771 times.
✓ Branch 4 taken 52 times.
|
1797 | true := stringEq(name, FCore.forScopeName); |
| 661 | then true; | ||
| 662 | |||
| 663 | else false; | ||
| 664 | |||
| 665 | end matchcontinue; | ||
| 666 | end inForLoopScope; | ||
| 667 | |||
| 668 | public function inForOrParforIterLoopScope "returns true if environment has a frame that is a for iterator 'loop'" | ||
| 669 | input Graph inGraph; | ||
| 670 | output Boolean res; | ||
| 671 | algorithm | ||
| 672 | res := matchcontinue inGraph | ||
| 673 | local String name; | ||
| 674 | |||
| 675 | case _ | ||
| 676 | algorithm | ||
| 677 | 82316 | name := FNode.refName(listHead(currentScope(inGraph))); | |
| 678 |
7/8✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 80972 times.
✓ Branch 3 taken 135 times.
✓ Branch 4 taken 1209 times.
✓ Branch 5 taken 26 times.
✓ Branch 6 taken 81081 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 26 times.
|
82316 | true := stringEq(name, FCore.forIterScopeName) or stringEq(name, FCore.parForIterScopeName); |
| 679 | then true; | ||
| 680 | |||
| 681 | else false; | ||
| 682 | end matchcontinue; | ||
| 683 | end inForOrParforIterLoopScope; | ||
| 684 | |||
| 685 | public function getScopePath | ||
| 686 | "get the current scope as a path from the graph" | ||
| 687 | input Graph inGraph; | ||
| 688 | output Option<Absyn.Path> outPath; | ||
| 689 | algorithm | ||
| 690 | outPath := matchcontinue inGraph | ||
| 691 | local | ||
| 692 | Absyn.Path p; | ||
| 693 | Ref r; | ||
| 694 | |||
| 695 | case _ | ||
| 696 | algorithm | ||
| 697 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 3168060 times.
✓ Branch 3 taken 2586115 times.
✓ Branch 4 taken 581945 times.
|
3168060 | {r} := currentScope(inGraph); |
| 698 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 581945 times.
|
581945 | true := FNode.isRefTop(r); |
| 699 | then | ||
| 700 | NONE(); | ||
| 701 | |||
| 702 | case _ | ||
| 703 | algorithm | ||
| 704 | 2586115 | p := getGraphName(inGraph); | |
| 705 | then | ||
| 706 | SOME(p); | ||
| 707 | |||
| 708 | end matchcontinue; | ||
| 709 | end getScopePath; | ||
| 710 | |||
| 711 | public function getGraphNameStr | ||
| 712 | "Returns the FQ name of the environment." | ||
| 713 | input Graph inGraph; | ||
| 714 | output String outString; | ||
| 715 | algorithm | ||
| 716 | outString := matchcontinue inGraph | ||
| 717 | case _ | ||
| 718 | 114335 | then | |
| 719 | AbsynUtil.pathString(getGraphName(inGraph)); | ||
| 720 | else "."; | ||
| 721 | end matchcontinue; | ||
| 722 | end getGraphNameStr; | ||
| 723 | |||
| 724 | public function getGraphName | ||
| 725 | "Returns the FQ name of the environment." | ||
| 726 | input Graph inGraph; | ||
| 727 | output Absyn.Path outPath; | ||
| 728 | protected | ||
| 729 | Absyn.Path p; | ||
| 730 | Scope s; | ||
| 731 | Ref r; | ||
| 732 | algorithm | ||
| 733 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7483349 times.
|
7483351 | r::s := currentScope(inGraph); |
| 734 | 7483349 | p := AbsynUtil.makeIdentPathFromString(FNode.refName(r)); | |
| 735 |
2/2✓ Branch 0 taken 19416705 times.
✓ Branch 1 taken 7483349 times.
|
26900054 | for r in s loop |
| 736 | 19416705 | p := Absyn.QUALIFIED(FNode.refName(r), p); | |
| 737 | end for; | ||
| 738 |
2/2✓ Branch 0 taken 24221 times.
✓ Branch 1 taken 7459128 times.
|
7483349 | Absyn.QUALIFIED(_, outPath) := p; |
| 739 | end getGraphName; | ||
| 740 | |||
| 741 | public function getGraphNameNoImplicitScopes | ||
| 742 | "Returns the FQ name of the environment." | ||
| 743 | input Graph inGraph; | ||
| 744 | output Absyn.Path outPath; | ||
| 745 | protected | ||
| 746 | Scope s; | ||
| 747 | algorithm | ||
| 748 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
|
5 | _::s := listReverse(currentScope(inGraph)); |
| 749 |
10/10✓ Branch 0 taken 18 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 5 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 10 times.
✓ Branch 8 taken 18 times.
✓ Branch 9 taken 5 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 5 times.
|
41 | outPath := AbsynUtil.stringListPath(list(str for str guard stringGet(str,1)<>36 /* "$" */ in list(FNode.refName(n) for n in s))); |
| 750 | end getGraphNameNoImplicitScopes; | ||
| 751 | |||
| 752 | public function pushScopeRef | ||
| 753 | "@author:adrpo | ||
| 754 | push the given ref as first element in the graph scope list" | ||
| 755 | input output Graph graph; | ||
| 756 | input Ref inRef; | ||
| 757 | algorithm | ||
| 758 | () := match graph | ||
| 759 | case FCore.G() | ||
| 760 | algorithm | ||
| 761 | 7081500 | graph.scope := inRef::graph.scope; | |
| 762 | then (); | ||
| 763 | end match; | ||
| 764 | end pushScopeRef; | ||
| 765 | |||
| 766 | public function pushScope | ||
| 767 | "@author:adrpo | ||
| 768 | put the given scope in the graph scope at the begining (listAppend(inScope, currentScope(graph)))" | ||
| 769 | input output Graph graph; | ||
| 770 | input Scope inScope; | ||
| 771 | algorithm | ||
| 772 | () := match graph | ||
| 773 | case FCore.G() | ||
| 774 | algorithm | ||
| 775 | 2794 | graph.scope := listAppend(inScope, graph.scope); | |
| 776 | then (); | ||
| 777 | end match; | ||
| 778 | end pushScope; | ||
| 779 | |||
| 780 | public function setScope | ||
| 781 | "@author:adrpo | ||
| 782 | replaces the graph scope with the given scope" | ||
| 783 | input output Graph graph; | ||
| 784 | input Scope inScope; | ||
| 785 | algorithm | ||
| 786 | () := match graph | ||
| 787 | case FCore.G() | ||
| 788 | algorithm | ||
| 789 | 8210222 | graph.scope := inScope; | |
| 790 | then (); | ||
| 791 | end match; | ||
| 792 | end setScope; | ||
| 793 | |||
| 794 | public function restrictionToScopeType | ||
| 795 | input SCode.Restriction inRestriction; | ||
| 796 | output Option<FCore.ScopeType> outType; | ||
| 797 | algorithm | ||
| 798 | outType := match inRestriction | ||
| 799 | case SCode.R_FUNCTION(SCode.FR_PARALLEL_FUNCTION()) then SOME(FCore.PARALLEL_SCOPE()); | ||
| 800 | case SCode.R_FUNCTION(SCode.FR_KERNEL_FUNCTION()) then SOME(FCore.PARALLEL_SCOPE()); | ||
| 801 | case SCode.R_FUNCTION(_) then SOME(FCore.FUNCTION_SCOPE()); | ||
| 802 | else SOME(FCore.CLASS_SCOPE()); | ||
| 803 | end match; | ||
| 804 | end restrictionToScopeType; | ||
| 805 | |||
| 806 | public function scopeTypeToRestriction | ||
| 807 | "Converts a ScopeType to a Restriction. Restriction is much more expressive | ||
| 808 | than ScopeType, so the returned Restriction is more of a rough indication of | ||
| 809 | what the original Restriction was." | ||
| 810 | input FCore.ScopeType inScopeType; | ||
| 811 | output SCode.Restriction outRestriction; | ||
| 812 | algorithm | ||
| 813 | outRestriction := match inScopeType | ||
| 814 | case FCore.PARALLEL_SCOPE() then SCode.R_FUNCTION(SCode.FR_PARALLEL_FUNCTION()); | ||
| 815 | case FCore.FUNCTION_SCOPE() then SCode.R_FUNCTION(SCode.FR_NORMAL_FUNCTION(Absyn.FunctionPurity.NO_PURITY())); | ||
| 816 | else SCode.R_CLASS(); | ||
| 817 | end match; | ||
| 818 | end scopeTypeToRestriction; | ||
| 819 | |||
| 820 | public function isTopScope "Returns true if we are in the top-most scope" | ||
| 821 | input Graph graph; | ||
| 822 | output Boolean isTop; | ||
| 823 | algorithm | ||
| 824 | isTop := matchcontinue graph | ||
| 825 | |||
| 826 | case _ | ||
| 827 | algorithm | ||
| 828 |
2/2✓ Branch 2 taken 60005 times.
✓ Branch 3 taken 469 times.
|
60474 | true := FNode.isRefTop(lastScopeRef(graph)); |
| 829 | then | ||
| 830 | true; | ||
| 831 | |||
| 832 | else false; | ||
| 833 | |||
| 834 | end matchcontinue; | ||
| 835 | end isTopScope; | ||
| 836 | |||
| 837 | public function crefStripGraphScopePrefix | ||
| 838 | "Removes the entire environment prefix from the given component reference, or | ||
| 839 | returns the unchanged reference. This is done because models might import | ||
| 840 | local packages, for example: | ||
| 841 | |||
| 842 | package P | ||
| 843 | import myP = InsideP; | ||
| 844 | |||
| 845 | package InsideP | ||
| 846 | function f end f; | ||
| 847 | end InsideP; | ||
| 848 | |||
| 849 | constant c = InsideP.f(); | ||
| 850 | end P; | ||
| 851 | |||
| 852 | package P2 | ||
| 853 | extends P; | ||
| 854 | end P2; | ||
| 855 | |||
| 856 | When P2 is instantiated all elements from P will be brought into P2's scope | ||
| 857 | due to the extends. The binding of c will still point to P.InsideP.f though, so | ||
| 858 | the lookup will try to instantiate P which might fail if P is a partial | ||
| 859 | package or for other reasons. This is really a bug in Lookup (it shouldn't | ||
| 860 | need to instantiate the whole package just to find a function), but to work | ||
| 861 | around this problem for now this function will remove the environment prefix | ||
| 862 | when InsideP.f is looked up in P, so that it resolves to InsideP.f and not | ||
| 863 | P.InsideP.f. This allows P2 to find it in the local scope instead, since the | ||
| 864 | InsideP package has been inherited from P." | ||
| 865 | input Absyn.ComponentRef inCref; | ||
| 866 | input Graph inEnv; | ||
| 867 | input Boolean stripPartial; | ||
| 868 | output Absyn.ComponentRef outCref; | ||
| 869 | algorithm | ||
| 870 | outCref := matchcontinue stripPartial | ||
| 871 | local | ||
| 872 | Absyn.Path env_path; | ||
| 873 | Absyn.ComponentRef cref1, cref2; | ||
| 874 | |||
| 875 | case _ | ||
| 876 | algorithm | ||
| 877 |
1/2✓ Branch 1 taken 451394 times.
✗ Branch 2 not taken.
|
451394 | false := Flags.isSet(Flags.STRIP_PREFIX); |
| 878 | then | ||
| 879 | inCref; | ||
| 880 | |||
| 881 | case _ | ||
| 882 | algorithm | ||
| 883 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 451394 times.
✓ Branch 3 taken 5591 times.
✓ Branch 4 taken 445803 times.
|
451394 | SOME(env_path) := getScopePath(inEnv); |
| 884 | 445803 | cref1 := AbsynUtil.unqualifyCref(inCref); | |
| 885 | 445803 | env_path := AbsynUtil.makeNotFullyQualified(env_path); | |
| 886 | // try to strip as much as possible | ||
| 887 | 445803 | cref2 := crefStripGraphScopePrefix2(cref1, env_path, stripPartial); | |
| 888 | // check if we really did anything, fail if we did nothing! | ||
| 889 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1135 times.
|
1135 | false := AbsynUtil.crefEqual(cref1, cref2); |
| 890 | then | ||
| 891 | cref2; | ||
| 892 | |||
| 893 | else inCref; | ||
| 894 | end matchcontinue; | ||
| 895 | end crefStripGraphScopePrefix; | ||
| 896 | |||
| 897 | protected function crefStripGraphScopePrefix2 | ||
| 898 | input Absyn.ComponentRef inCref; | ||
| 899 | input Absyn.Path inEnvPath; | ||
| 900 | input Boolean stripPartial; | ||
| 901 | output Absyn.ComponentRef outCref; | ||
| 902 | algorithm | ||
| 903 | outCref := matchcontinue(inCref, inEnvPath, stripPartial) | ||
| 904 | local | ||
| 905 | Absyn.Ident id1, id2; | ||
| 906 | Absyn.ComponentRef cref; | ||
| 907 | Absyn.Path env_path; | ||
| 908 | |||
| 909 | case (Absyn.CREF_QUAL(name = id1, subscripts = {}, componentRef = cref), | ||
| 910 | Absyn.QUALIFIED(name = id2, path = env_path), _) | ||
| 911 | algorithm | ||
| 912 |
4/4✓ Branch 0 taken 105963 times.
✓ Branch 1 taken 39480 times.
✓ Branch 3 taken 93862 times.
✓ Branch 4 taken 12101 times.
|
145443 | true := stringEqual(id1, id2); |
| 913 | 93862 | then | |
| 914 | crefStripGraphScopePrefix2(cref, env_path, stripPartial); | ||
| 915 | |||
| 916 | case (Absyn.CREF_QUAL(name = id1, subscripts = {}, componentRef = cref), | ||
| 917 | Absyn.IDENT(name = id2), _) | ||
| 918 | algorithm | ||
| 919 |
4/4✓ Branch 0 taken 2270 times.
✓ Branch 1 taken 355 times.
✓ Branch 3 taken 1135 times.
✓ Branch 4 taken 1135 times.
|
2625 | true := stringEqual(id1, id2); |
| 920 | then | ||
| 921 | cref; | ||
| 922 | |||
| 923 | // adrpo: leave it as stripped as you can if you can't match it above and we have true for stripPartial | ||
| 924 | case (Absyn.CREF_QUAL(name = id1, subscripts = {}), | ||
| 925 | env_path, true) | ||
| 926 | algorithm | ||
| 927 | ✗ | false := stringEqual(id1, AbsynUtil.pathFirstIdent(env_path)); | |
| 928 | then | ||
| 929 | inCref; | ||
| 930 | end matchcontinue; | ||
| 931 | end crefStripGraphScopePrefix2; | ||
| 932 | |||
| 933 | public function pathStripGraphScopePrefix | ||
| 934 | "same as pathStripGraphScopePrefix" | ||
| 935 | input Absyn.Path inPath; | ||
| 936 | input Graph inEnv; | ||
| 937 | input Boolean stripPartial; | ||
| 938 | output Absyn.Path outPath; | ||
| 939 | algorithm | ||
| 940 | outPath := matchcontinue stripPartial | ||
| 941 | local | ||
| 942 | Absyn.Path env_path; | ||
| 943 | Absyn.Path path1, path2; | ||
| 944 | |||
| 945 | case _ | ||
| 946 | algorithm | ||
| 947 |
1/2✓ Branch 1 taken 335341 times.
✗ Branch 2 not taken.
|
335341 | false := Flags.isSet(Flags.STRIP_PREFIX); |
| 948 | then inPath; | ||
| 949 | |||
| 950 | case _ | ||
| 951 | algorithm | ||
| 952 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 335341 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 335341 times.
|
335341 | SOME(env_path) := getScopePath(inEnv); |
| 953 | 335341 | path1 := AbsynUtil.makeNotFullyQualified(inPath); | |
| 954 | 335341 | env_path := AbsynUtil.makeNotFullyQualified(env_path); | |
| 955 | // try to strip as much as possible | ||
| 956 | 335341 | path2 := pathStripGraphScopePrefix2(path1, env_path, stripPartial); | |
| 957 | // check if we really did anything, fail if we did nothing! | ||
| 958 | ✗ | false := AbsynUtil.pathEqual(path1, path2); | |
| 959 | then | ||
| 960 | path2; | ||
| 961 | |||
| 962 | else inPath; | ||
| 963 | end matchcontinue; | ||
| 964 | end pathStripGraphScopePrefix; | ||
| 965 | |||
| 966 | protected function pathStripGraphScopePrefix2 | ||
| 967 | input Absyn.Path inPath; | ||
| 968 | input Absyn.Path inEnvPath; | ||
| 969 | input Boolean stripPartial; | ||
| 970 | output Absyn.Path outPath; | ||
| 971 | algorithm | ||
| 972 | outPath := match(inPath, inEnvPath, stripPartial) | ||
| 973 | local | ||
| 974 | Absyn.Ident id1, id2; | ||
| 975 | Absyn.Path path; | ||
| 976 | Absyn.Path env_path; | ||
| 977 | |||
| 978 | case (Absyn.QUALIFIED(name = id1, path = path), | ||
| 979 | Absyn.QUALIFIED(name = id2, path = env_path), _) guard stringEqual(id1, id2) | ||
| 980 | 87809 | then | |
| 981 | pathStripGraphScopePrefix2(path, env_path, stripPartial); | ||
| 982 | |||
| 983 | case (Absyn.QUALIFIED(name = id1, path = path), | ||
| 984 | Absyn.IDENT(name = id2), _) guard stringEqual(id1, id2) | ||
| 985 | then | ||
| 986 | path; | ||
| 987 | |||
| 988 | // adrpo: leave it as stripped as you can if you can't match it above and stripPartial is true | ||
| 989 | case (Absyn.QUALIFIED(name = id1), env_path, true) guard not stringEqual(id1, AbsynUtil.pathFirstIdent(env_path)) | ||
| 990 | then | ||
| 991 | inPath; | ||
| 992 | end match; | ||
| 993 | end pathStripGraphScopePrefix2; | ||
| 994 | |||
| 995 | public function mkComponentNode "This function adds a component to the graph." | ||
| 996 | input Graph inGraph; | ||
| 997 | input DAE.Var inVar; | ||
| 998 | input SCode.Element inVarEl; | ||
| 999 | input DAE.Mod inMod; | ||
| 1000 | input Status instStatus; | ||
| 1001 | input Graph inCompGraph; | ||
| 1002 | output Graph outGraph; | ||
| 1003 | algorithm | ||
| 1004 | outGraph := matchcontinue (inGraph,inVar,inVarEl,inMod,instStatus,inCompGraph) | ||
| 1005 | local | ||
| 1006 | DAE.Var v; | ||
| 1007 | Name n; | ||
| 1008 | SCode.Element c; | ||
| 1009 | Graph g, cg; | ||
| 1010 | DAE.Mod m; | ||
| 1011 | Ref r; | ||
| 1012 | FCore.Status i; | ||
| 1013 | |||
| 1014 | // Graph of component | ||
| 1015 | case (_, DAE.TYPES_VAR(name = n),c,_,_,_) | ||
| 1016 | algorithm | ||
| 1017 | // maks sure the element name and the DAE.TYPES_VAR name is the same! | ||
| 1018 |
2/4✓ Branch 1 taken 1184327 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1184327 times.
✗ Branch 6 not taken.
|
1184327 | false := stringEq(n, SCodeUtil.elementName(c)); |
| 1019 | ✗ | Error.addCompilerError("FGraph.mkComponentNode: The component name: " + SCodeUtil.elementName(c) + " is not the same as its DAE.TYPES_VAR: " + n + "\n"); | |
| 1020 | ✗ | then | |
| 1021 | fail(); | ||
| 1022 | |||
| 1023 | // Graph of component | ||
| 1024 | case (g, v as DAE.TYPES_VAR(name = n),c,m,i,cg) | ||
| 1025 | algorithm | ||
| 1026 | // make sure the element name and the DAE.TYPES_VAR name is the same! | ||
| 1027 |
2/4✓ Branch 1 taken 1184327 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1184327 times.
|
1184327 | true := stringEq(n, SCodeUtil.elementName(c)); |
| 1028 | 1184327 | r := lastScopeRef(g); | |
| 1029 | 1184327 | g := FGraphBuildEnv.mkCompNode(c, r, FCore.USERDEFINED(), g); | |
| 1030 | // update the var too! | ||
| 1031 | 1184327 | g := updateVarAndMod(g, v, m, i, cg); | |
| 1032 | then | ||
| 1033 | g; | ||
| 1034 | |||
| 1035 | end matchcontinue; | ||
| 1036 | end mkComponentNode; | ||
| 1037 | |||
| 1038 | public function mkClassNode | ||
| 1039 | "This function adds a class definition to the environment. | ||
| 1040 | Enumeration are expanded from a list into a class with components" | ||
| 1041 | input Graph inGraph; | ||
| 1042 | input SCode.Element inClass; | ||
| 1043 | input DAE.Prefix inPrefix; | ||
| 1044 | input DAE.Mod inMod; | ||
| 1045 | input Boolean checkDuplicate = false; | ||
| 1046 | output Graph outGraph; | ||
| 1047 | algorithm | ||
| 1048 | outGraph := matchcontinue (inGraph, inClass) | ||
| 1049 | local | ||
| 1050 | Name n; | ||
| 1051 | Graph g; | ||
| 1052 | Ref r; | ||
| 1053 | |||
| 1054 | // already there as class instance, do nothing! | ||
| 1055 | case (g, SCode.CLASS(name = n)) | ||
| 1056 | algorithm | ||
| 1057 | 8065015 | r := lastScopeRef(g); | |
| 1058 | 8065015 | r := FNode.child(r, n); | |
| 1059 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 26137 times.
✓ Branch 3 taken 26137 times.
✗ Branch 4 not taken.
|
26137 | FCore.CL(status = FCore.CLS_INSTANCE(_)) := FNode.refData(r); |
| 1060 | then | ||
| 1061 | g; | ||
| 1062 | |||
| 1063 | case (g, SCode.CLASS()) | ||
| 1064 | algorithm | ||
| 1065 | 8065015 | r := lastScopeRef(g); | |
| 1066 | 8065015 | g := FGraphBuildEnv.mkClassNode(inClass, inPrefix, inMod, r, | |
| 1067 | FCore.USERDEFINED(), g, checkDuplicate); | ||
| 1068 | then | ||
| 1069 | g; | ||
| 1070 | |||
| 1071 | end matchcontinue; | ||
| 1072 | end mkClassNode; | ||
| 1073 | |||
| 1074 | public function mkTypeNode | ||
| 1075 | "This function adds a class definition to the environment. | ||
| 1076 | Enumeration are expanded from a list into a class with components" | ||
| 1077 | input Graph inGraph; | ||
| 1078 | input Name inName; | ||
| 1079 | input DAE.Type inType; | ||
| 1080 | output Graph outGraph; | ||
| 1081 | algorithm | ||
| 1082 | outGraph := match inGraph | ||
| 1083 | local | ||
| 1084 | Graph g; | ||
| 1085 | Ref r; | ||
| 1086 | |||
| 1087 | case g | ||
| 1088 | algorithm | ||
| 1089 | 69018 | r := lastScopeRef(g); | |
| 1090 | 69018 | g := FGraphBuildEnv.mkTypeNode({inType}, r, inName, g); | |
| 1091 | then | ||
| 1092 | g; | ||
| 1093 | |||
| 1094 | end match; | ||
| 1095 | end mkTypeNode; | ||
| 1096 | |||
| 1097 | public function mkImportNode | ||
| 1098 | "This function adds a class definition to the environment. | ||
| 1099 | Enumeration are expanded from a list into a class with components" | ||
| 1100 | input Graph inGraph; | ||
| 1101 | input SCode.Element inImport; | ||
| 1102 | output Graph outGraph; | ||
| 1103 | algorithm | ||
| 1104 | outGraph := match inGraph | ||
| 1105 | local | ||
| 1106 | Graph g; | ||
| 1107 | Ref r; | ||
| 1108 | |||
| 1109 | case g | ||
| 1110 | algorithm | ||
| 1111 | 76638 | r := lastScopeRef(g); | |
| 1112 | 76638 | g := FGraphBuildEnv.mkElementNode(inImport, r, FCore.USERDEFINED(), g); | |
| 1113 | then | ||
| 1114 | g; | ||
| 1115 | |||
| 1116 | end match; | ||
| 1117 | end mkImportNode; | ||
| 1118 | |||
| 1119 | public function mkDefunitNode | ||
| 1120 | "This function adds a class definition to the environment. | ||
| 1121 | Enumeration are expanded from a list into a class with components" | ||
| 1122 | input Graph inGraph; | ||
| 1123 | input SCode.Element inDu; | ||
| 1124 | output Graph outGraph; | ||
| 1125 | algorithm | ||
| 1126 | outGraph := match inGraph | ||
| 1127 | local | ||
| 1128 | Graph g; | ||
| 1129 | Ref r; | ||
| 1130 | |||
| 1131 | case g | ||
| 1132 | algorithm | ||
| 1133 | ✗ | r := lastScopeRef(g); | |
| 1134 | ✗ | g := FGraphBuildEnv.mkElementNode(inDu, r, FCore.USERDEFINED(), g); | |
| 1135 | then | ||
| 1136 | g; | ||
| 1137 | |||
| 1138 | end match; | ||
| 1139 | end mkDefunitNode; | ||
| 1140 | |||
| 1141 | public function classInfToScopeType | ||
| 1142 | input ClassInf.State inState; | ||
| 1143 | output Option<FCore.ScopeType> outType; | ||
| 1144 | algorithm | ||
| 1145 | outType := match inState | ||
| 1146 | case ClassInf.FUNCTION() then SOME(FCore.FUNCTION_SCOPE()); | ||
| 1147 | else SOME(FCore.CLASS_SCOPE()); | ||
| 1148 | end match; | ||
| 1149 | end classInfToScopeType; | ||
| 1150 | |||
| 1151 | public function isEmpty | ||
| 1152 | "returns true if empty graph" | ||
| 1153 | input Graph inGraph; | ||
| 1154 | output Boolean b; | ||
| 1155 | algorithm | ||
| 1156 | b := match inGraph | ||
| 1157 | case FCore.EG(_) then true; | ||
| 1158 | else false; | ||
| 1159 | end match; | ||
| 1160 | end isEmpty; | ||
| 1161 | |||
| 1162 | public function isNotEmpty | ||
| 1163 | "returns true if not empty graph" | ||
| 1164 | input Graph inGraph; | ||
| 1165 | output Boolean b; | ||
| 1166 | algorithm | ||
| 1167 | 75525 | b := not isEmpty(inGraph); | |
| 1168 | end isNotEmpty; | ||
| 1169 | |||
| 1170 | public function isEmptyScope | ||
| 1171 | input Graph graph; | ||
| 1172 | output Boolean isEmpty; | ||
| 1173 | algorithm | ||
| 1174 | try | ||
| 1175 | 220723 | isEmpty := RefTree.isEmpty(FNode.children(FNode.fromRef(lastScopeRef(graph)))); | |
| 1176 | else | ||
| 1177 | isEmpty := true; | ||
| 1178 | end try; | ||
| 1179 | end isEmptyScope; | ||
| 1180 | |||
| 1181 | public function printGraphStr | ||
| 1182 | "prints the graph" | ||
| 1183 | input Graph inGraph; | ||
| 1184 | output String s; | ||
| 1185 | algorithm | ||
| 1186 | s := "NOT IMPLEMENTED YET"; | ||
| 1187 | end printGraphStr; | ||
| 1188 | |||
| 1189 | public function inFunctionScope | ||
| 1190 | input Graph inGraph; | ||
| 1191 | output Boolean inFunction; | ||
| 1192 | algorithm | ||
| 1193 | inFunction := match inGraph | ||
| 1194 | local | ||
| 1195 | Scope s; | ||
| 1196 | |||
| 1197 | case FCore.G(scope = s) guard checkScopeType(s, SOME(FCore.FUNCTION_SCOPE())) or | ||
| 1198 | checkScopeType(s, SOME(FCore.PARALLEL_SCOPE())) | ||
| 1199 | then | ||
| 1200 | true; | ||
| 1201 | |||
| 1202 | else false; | ||
| 1203 | |||
| 1204 | end match; | ||
| 1205 | end inFunctionScope; | ||
| 1206 | |||
| 1207 | public function getScopeName " Returns the name of a scope, if no name exist, the function fails." | ||
| 1208 | input Graph inGraph; | ||
| 1209 | output Name name; | ||
| 1210 | algorithm | ||
| 1211 | name := match inGraph | ||
| 1212 | local Ref r; | ||
| 1213 | case _ | ||
| 1214 | algorithm | ||
| 1215 | ✗ | r := lastScopeRef(inGraph); | |
| 1216 | // not top | ||
| 1217 | ✗ | false := FNode.isRefTop(r); | |
| 1218 | ✗ | name := FNode.refName(r); | |
| 1219 | then | ||
| 1220 | name; | ||
| 1221 | end match; | ||
| 1222 | end getScopeName; | ||
| 1223 | |||
| 1224 | public function checkScopeType | ||
| 1225 | input Scope inScope; | ||
| 1226 | input Option<FCore.ScopeType> inScopeType; | ||
| 1227 | output Boolean yes; | ||
| 1228 | algorithm | ||
| 1229 | yes := matchcontinue inScope | ||
| 1230 | local | ||
| 1231 | Ref r; | ||
| 1232 | Scope rest; | ||
| 1233 | SCode.Restriction restr; | ||
| 1234 | Option<FCore.ScopeType> st; | ||
| 1235 | |||
| 1236 | case {} then false; | ||
| 1237 | |||
| 1238 | // classes | ||
| 1239 | case r::_ | ||
| 1240 | algorithm | ||
| 1241 |
2/2✓ Branch 1 taken 821712 times.
✓ Branch 2 taken 1981288 times.
|
2803000 | true := FNode.isRefClass(r); |
| 1242 | 1981288 | restr := SCodeUtil.getClassRestriction(FNode.getElement(FNode.fromRef(r))); | |
| 1243 |
2/2✓ Branch 2 taken 1632744 times.
✓ Branch 3 taken 348544 times.
|
1981288 | true := valueEq(restrictionToScopeType(restr), inScopeType); |
| 1244 | then | ||
| 1245 | true; | ||
| 1246 | |||
| 1247 | // FCore.ND(scopeType) | ||
| 1248 | case r::_ | ||
| 1249 | algorithm | ||
| 1250 |
2/2✓ Branch 1 taken 2247891 times.
✓ Branch 2 taken 206565 times.
|
2454456 | FCore.N(data = FCore.ND(st)) := FNode.fromRef(r); |
| 1251 |
1/2✓ Branch 1 taken 206565 times.
✗ Branch 2 not taken.
|
206565 | true := valueEq(st, inScopeType); |
| 1252 | then | ||
| 1253 | true; | ||
| 1254 | |||
| 1255 | case _::rest | ||
| 1256 | 2454456 | then | |
| 1257 | checkScopeType(rest, inScopeType); | ||
| 1258 | |||
| 1259 | end matchcontinue; | ||
| 1260 | end checkScopeType; | ||
| 1261 | |||
| 1262 | public function lastScopeRestriction | ||
| 1263 | input Graph inGraph; | ||
| 1264 | output SCode.Restriction outRestriction; | ||
| 1265 | protected | ||
| 1266 | Scope s; | ||
| 1267 | algorithm | ||
| 1268 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1028 times.
|
1028 | FCore.G(scope = s) := inGraph; |
| 1269 | 1028 | outRestriction := getScopeRestriction(s); | |
| 1270 | end lastScopeRestriction; | ||
| 1271 | |||
| 1272 | public function getScopeRestriction | ||
| 1273 | input Scope inScope; | ||
| 1274 | output SCode.Restriction outRestriction; | ||
| 1275 | algorithm | ||
| 1276 | outRestriction := matchcontinue inScope | ||
| 1277 | local | ||
| 1278 | Ref r; | ||
| 1279 | FCore.ScopeType st; | ||
| 1280 | |||
| 1281 | case r :: _ guard(FNode.isRefClass(r)) | ||
| 1282 | 963 | then SCodeUtil.getClassRestriction(FNode.getElement(FNode.fromRef(r))); | |
| 1283 | |||
| 1284 | case r :: _ | ||
| 1285 | algorithm | ||
| 1286 |
4/6✓ Branch 1 taken 65 times.
✓ Branch 2 taken 188 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 188 times.
✓ Branch 5 taken 188 times.
✗ Branch 6 not taken.
|
253 | FCore.N(data = FCore.ND(SOME(st))) := FNode.fromRef(r); |
| 1287 | ✗ | then | |
| 1288 | scopeTypeToRestriction(st); | ||
| 1289 | |||
| 1290 | 318 | else getScopeRestriction(listRest(inScope)); | |
| 1291 | |||
| 1292 | end matchcontinue; | ||
| 1293 | end getScopeRestriction; | ||
| 1294 | |||
| 1295 | public function getGraphPathNoImplicitScope | ||
| 1296 | "This function returns all partially instantiated parents as an Absyn.Path | ||
| 1297 | option I.e. it collects all identifiers of each frame until it reaches | ||
| 1298 | the topmost unnamed frame. If the environment is only the topmost frame, | ||
| 1299 | NONE() is returned." | ||
| 1300 | input Graph inGraph; | ||
| 1301 | output Option<Absyn.Path> outAbsynPathOption; | ||
| 1302 | algorithm | ||
| 1303 | 123062 | outAbsynPathOption := getGraphPathNoImplicitScope_dispatch(currentScope(inGraph)); | |
| 1304 | end getGraphPathNoImplicitScope; | ||
| 1305 | |||
| 1306 | protected function getGraphPathNoImplicitScope_dispatch | ||
| 1307 | "This function returns all partially instantiated parents as an Absyn.Path | ||
| 1308 | option I.e. it collects all identifiers of each frame until it reaches | ||
| 1309 | the topmost unnamed frame. If the environment is only the topmost frame, | ||
| 1310 | NONE() is returned." | ||
| 1311 | input Scope inScope; | ||
| 1312 | output Option<Absyn.Path> outAbsynPathOption; | ||
| 1313 | protected | ||
| 1314 | Option<Absyn.Path> opath; | ||
| 1315 | algorithm | ||
| 1316 | outAbsynPathOption := matchcontinue inScope | ||
| 1317 | local | ||
| 1318 | Name id; | ||
| 1319 | Absyn.Path path,path_1; | ||
| 1320 | Scope rest; | ||
| 1321 | Ref ref; | ||
| 1322 | |||
| 1323 | case ref :: rest | ||
| 1324 | guard | ||
| 1325 | not FNode.isRefTop(ref) | ||
| 1326 | algorithm | ||
| 1327 | 368823 | id := FNode.refName(ref); | |
| 1328 |
2/2✓ Branch 1 taken 48629 times.
✓ Branch 2 taken 320194 times.
|
368823 | if isImplicitScope(id) then |
| 1329 | 48629 | opath := getGraphPathNoImplicitScope_dispatch(rest); | |
| 1330 | else | ||
| 1331 | 320194 | opath := getGraphPathNoImplicitScope_dispatch(rest); | |
| 1332 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 320194 times.
✓ Branch 2 taken 108217 times.
✓ Branch 3 taken 211977 times.
|
320194 | if isSome(opath) then |
| 1333 | 211977 | SOME(path) := opath; | |
| 1334 | 211977 | path_1 := AbsynUtil.joinPaths(path, Absyn.IDENT(id)); | |
| 1335 | opath := SOME(path_1); | ||
| 1336 | else | ||
| 1337 | 108217 | opath := SOME(Absyn.IDENT(id)); | |
| 1338 | end if; | ||
| 1339 | end if; | ||
| 1340 | then | ||
| 1341 | opath; | ||
| 1342 | |||
| 1343 | else NONE(); | ||
| 1344 | |||
| 1345 | end matchcontinue; | ||
| 1346 | end getGraphPathNoImplicitScope_dispatch; | ||
| 1347 | |||
| 1348 | public function isImplicitScope | ||
| 1349 | input Name inName; | ||
| 1350 | output Boolean isImplicit; | ||
| 1351 | algorithm | ||
| 1352 | 368823 | isImplicit := FCore.isImplicitScope(inName); | |
| 1353 | end isImplicitScope; | ||
| 1354 | |||
| 1355 | public function joinScopePath "Used to join an Graph scope with an Absyn.Path (probably an IDENT)" | ||
| 1356 | input Graph inGraph; | ||
| 1357 | input Absyn.Path inPath; | ||
| 1358 | output Absyn.Path outPath; | ||
| 1359 | protected | ||
| 1360 | Option<Absyn.Path> opath; | ||
| 1361 | Absyn.Path envPath; | ||
| 1362 | algorithm | ||
| 1363 | 37420 | opath := getScopePath(inGraph); | |
| 1364 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 37420 times.
✓ Branch 2 taken 36273 times.
✓ Branch 3 taken 1147 times.
|
37420 | if isSome(opath) then |
| 1365 | 36273 | SOME(envPath) := opath; | |
| 1366 | 36273 | outPath := AbsynUtil.joinPaths(envPath,inPath); | |
| 1367 | else | ||
| 1368 | outPath := inPath; | ||
| 1369 | end if; | ||
| 1370 | end joinScopePath; | ||
| 1371 | |||
| 1372 | public function splitGraphScope | ||
| 1373 | "splits out the for loop scope from the graph scope" | ||
| 1374 | input Graph inGraph; | ||
| 1375 | output Graph outRealGraph; | ||
| 1376 | output Scope outForScope; | ||
| 1377 | algorithm | ||
| 1378 | 2794 | (outRealGraph, outForScope) := splitGraphScope_dispatch(inGraph, {}); | |
| 1379 | end splitGraphScope; | ||
| 1380 | |||
| 1381 | public function splitGraphScope_dispatch | ||
| 1382 | "splits out the for loop scope from the graph scope" | ||
| 1383 | input Graph inGraph; | ||
| 1384 | input Scope inAcc; | ||
| 1385 | output Graph outRealGraph; | ||
| 1386 | output Scope outForScope; | ||
| 1387 | algorithm | ||
| 1388 | (outRealGraph, outForScope) := match inGraph | ||
| 1389 | local | ||
| 1390 | Graph g; | ||
| 1391 | Ref r; | ||
| 1392 | Scope s; | ||
| 1393 | |||
| 1394 | ✗ | case FCore.EG(_) then (inGraph, listReverse(inAcc)); | |
| 1395 | |||
| 1396 | case FCore.G(scope = r::_) | ||
| 1397 | algorithm | ||
| 1398 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2794 times.
|
2794 | if FNode.isImplicitRefName(r) then |
| 1399 | ✗ | (g, _) := stripLastScopeRef(inGraph); | |
| 1400 | ✗ | (g, s) := splitGraphScope_dispatch(g, r::inAcc); | |
| 1401 | else | ||
| 1402 | g := inGraph; | ||
| 1403 | 2794 | s := listReverse(inAcc); | |
| 1404 | end if; | ||
| 1405 | 2794 | then | |
| 1406 | (g, s); | ||
| 1407 | |||
| 1408 | end match; | ||
| 1409 | end splitGraphScope_dispatch; | ||
| 1410 | |||
| 1411 | public function getVariablesFromGraphScope | ||
| 1412 | "@author: adrpo | ||
| 1413 | returns the a list with all the variables names in the given graph from the last graph scope" | ||
| 1414 | input Graph inGraph; | ||
| 1415 | output list<Name> variables; | ||
| 1416 | algorithm | ||
| 1417 | variables := match inGraph | ||
| 1418 | local | ||
| 1419 | list<Name> lst; | ||
| 1420 | Ref r; | ||
| 1421 | |||
| 1422 | // empty case | ||
| 1423 | case FCore.EG(_) then {}; | ||
| 1424 | |||
| 1425 | // some graph, no scope | ||
| 1426 | case FCore.G(scope = {}) then {}; | ||
| 1427 | |||
| 1428 | // some graph | ||
| 1429 | case FCore.G(scope = r::_) | ||
| 1430 | algorithm | ||
| 1431 | 3750 | lst := List.map(FNode.filter(r, FNode.isRefComponent), FNode.refName); | |
| 1432 | then | ||
| 1433 | lst; | ||
| 1434 | |||
| 1435 | end match; | ||
| 1436 | end getVariablesFromGraphScope; | ||
| 1437 | |||
| 1438 | public function removeComponentsFromScope | ||
| 1439 | "@author:adrpo | ||
| 1440 | remove the children of the last ref" | ||
| 1441 | input Graph inGraph; | ||
| 1442 | output Graph outGraph; | ||
| 1443 | protected | ||
| 1444 | Ref r; | ||
| 1445 | Node n; | ||
| 1446 | algorithm | ||
| 1447 | 1692 | r := lastScopeRef(inGraph); | |
| 1448 | 1692 | r := FNode.copyRefNoUpdate(r); | |
| 1449 | 1692 | n := FNode.fromRef(r); | |
| 1450 | 1692 | n := FNode.setChildren(n, RefTree.new()); | |
| 1451 | 1692 | r := FNode.updateRef(r, n); | |
| 1452 | 1692 | (outGraph, _) := stripLastScopeRef(inGraph); | |
| 1453 | 1692 | outGraph := pushScopeRef(outGraph, r); | |
| 1454 | end removeComponentsFromScope; | ||
| 1455 | |||
| 1456 | public function cloneLastScopeRef | ||
| 1457 | input Graph inGraph; | ||
| 1458 | output Graph outGraph; | ||
| 1459 | protected | ||
| 1460 | Ref r; | ||
| 1461 | algorithm | ||
| 1462 | ✗ | (outGraph, r) := stripLastScopeRef(inGraph); | |
| 1463 | ✗ | r := FNode.copyRefNoUpdate(r); | |
| 1464 | ✗ | outGraph := pushScopeRef(outGraph, r); | |
| 1465 | end cloneLastScopeRef; | ||
| 1466 | |||
| 1467 | public function updateScope | ||
| 1468 | input Graph inGraph; | ||
| 1469 | output Graph outGraph; | ||
| 1470 | algorithm | ||
| 1471 | outGraph := match inGraph | ||
| 1472 | case _ then inGraph; | ||
| 1473 | end match; | ||
| 1474 | end updateScope; | ||
| 1475 | |||
| 1476 | public function mkVersionNode | ||
| 1477 | "@author: adrpo | ||
| 1478 | THE MOST IMPORTANT FUNCTION IN THE COMPILER :) | ||
| 1479 | This function works like this: | ||
| 1480 | From source scope: | ||
| 1481 | A.B.C.D | ||
| 1482 | we lookup a target scope | ||
| 1483 | X.Y.Z.W | ||
| 1484 | to be used for a component, derived class, or extends | ||
| 1485 | We get back X.Y.Z + CLASS(W) via lookup. | ||
| 1486 | We build X.Y.Z.W_newVersion and return it. | ||
| 1487 | The newVersion name is generated by mkVersionName based on | ||
| 1488 | the source scope, the element name, prefix and modifiers. | ||
| 1489 | The newVersion scope is only created if there are non emtpy | ||
| 1490 | modifiers given to this functions" | ||
| 1491 | input Graph inSourceEnv; | ||
| 1492 | input Name inSourceName; | ||
| 1493 | input DAE.Prefix inPrefix; | ||
| 1494 | input DAE.Mod inMod; | ||
| 1495 | input Graph inTargetClassEnv; | ||
| 1496 | input SCode.Element inTargetClass; | ||
| 1497 | input InnerOuter.InstHierarchy inIH; | ||
| 1498 | output Graph outVersionedTargetClassEnv; | ||
| 1499 | output SCode.Element outVersionedTargetClass; | ||
| 1500 | output InnerOuter.InstHierarchy outIH; | ||
| 1501 | algorithm | ||
| 1502 | (outVersionedTargetClassEnv, outVersionedTargetClass, outIH) := matchcontinue inIH | ||
| 1503 | local | ||
| 1504 | Graph gclass; | ||
| 1505 | Ref classRef, sourceRef, targetClassParentRef; | ||
| 1506 | DAE.Prefix crefPrefix; | ||
| 1507 | SCode.Element c; | ||
| 1508 | Name targetClassName, newTargetClassName; | ||
| 1509 | InnerOuter.InstHierarchy ih; | ||
| 1510 | |||
| 1511 | /* | ||
| 1512 | case (_, _, _, _, _, _, _) | ||
| 1513 | algorithm | ||
| 1514 | c = inTargetClass; | ||
| 1515 | gclass = inTargetClassEnv; | ||
| 1516 | targetClassName = SCodeUtil.elementName(c); | ||
| 1517 | |||
| 1518 | (newTargetClassName, crefPrefix) = mkVersionName(inSourceEnv, inSourceName, inPrefix, inMod, inTargetClassEnv, targetClassName); | ||
| 1519 | |||
| 1520 | // get the last scope from target | ||
| 1521 | targetClassParentRef = lastScopeRef(inTargetClassEnv); | ||
| 1522 | classRef = FNode.child(targetClassParentRef, newTargetClassName); | ||
| 1523 | c = FNode.getElementFromRef(classRef); | ||
| 1524 | then | ||
| 1525 | (inTargetClassEnv, c, inIH);*/ | ||
| 1526 | |||
| 1527 | case _ | ||
| 1528 | algorithm | ||
| 1529 | c := inTargetClass; | ||
| 1530 | gclass := inTargetClassEnv; | ||
| 1531 | 20715 | targetClassName := SCodeUtil.elementName(c); | |
| 1532 | |||
| 1533 | 20715 | (newTargetClassName, crefPrefix) := mkVersionName(inSourceEnv, inSourceName, inPrefix, inMod, inTargetClassEnv, targetClassName); | |
| 1534 | |||
| 1535 | // get the last item in the source env | ||
| 1536 | 20715 | sourceRef := FNode.child(lastScopeRef(inSourceEnv), inSourceName); | |
| 1537 | |||
| 1538 | // get the last scope from target | ||
| 1539 | 20715 | targetClassParentRef := lastScopeRef(inTargetClassEnv); | |
| 1540 | // get the class from class env | ||
| 1541 | 20715 | classRef := FNode.child(targetClassParentRef, targetClassName); | |
| 1542 | // clone the class | ||
| 1543 | 20715 | classRef := FNode.copyRefNoUpdate(classRef); | |
| 1544 | |||
| 1545 | // check if the name of the class already exists! | ||
| 1546 | // failure(_ = FNode.child(targetClassParentRef, newTargetClassName)); | ||
| 1547 | |||
| 1548 | // change class name (so unqualified references to the same class reach the original element | ||
| 1549 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20715 times.
|
20715 | FCore.CL(e = c) := FNode.refData(classRef); |
| 1550 | 20715 | c := SCodeUtil.setClassName(newTargetClassName, c); | |
| 1551 | 20715 | classRef := updateClassElement(classRef, c, crefPrefix, inMod, FCore.CLS_INSTANCE(targetClassName) /* FCore.CLS_UNTYPED() */, empty()); | |
| 1552 | // parent the classRef | ||
| 1553 | 20715 | FNode.addChildRef(targetClassParentRef, newTargetClassName, classRef); | |
| 1554 | // update the source target scope | ||
| 1555 | 41430 | sourceRef := updateSourceTargetScope(sourceRef, classRef :: currentScope(gclass)); | |
| 1556 | |||
| 1557 | // we never need to add the instance as inner! | ||
| 1558 | ih := inIH; // ih = InnerOuter.addClassIfInner(c, crefPrefix, gclass, inIH); | ||
| 1559 | |||
| 1560 | /* | ||
| 1561 | print("Instance1: CL(" + getGraphNameStr(inSourceEnv) + ").CO(" + | ||
| 1562 | inSourceName + ").CL(" + getGraphNameStr(inTargetClassEnv) + "." + | ||
| 1563 | targetClassName + SCodeDump.printModStr(Mod.unelabMod(inMod), SCodeDump.defaultOptions) + ")\n\t" + | ||
| 1564 | newTargetClassName + "\n");*/ | ||
| 1565 | then | ||
| 1566 | (gclass, c, ih); | ||
| 1567 | |||
| 1568 | else | ||
| 1569 | algorithm | ||
| 1570 | c := inTargetClass; | ||
| 1571 | ✗ | targetClassName := SCodeUtil.elementName(c); | |
| 1572 | ✗ | (newTargetClassName,_) := mkVersionName(inSourceEnv, inSourceName, inPrefix, inMod, inTargetClassEnv, targetClassName); | |
| 1573 | |||
| 1574 | ✗ | Error.addCompilerWarning( | |
| 1575 | "FGraph.mkVersionNode: failed to create version node:\n" + | ||
| 1576 | "Instance: CL(" + getGraphNameStr(inSourceEnv) + ").CO(" + | ||
| 1577 | inSourceName + ").CL(" + getGraphNameStr(inTargetClassEnv) + "." + | ||
| 1578 | targetClassName + SCodeDump.printModStr(Mod.unelabMod(inMod), SCodeDump.defaultOptions) + ")\n\t" + | ||
| 1579 | newTargetClassName + "\n"); | ||
| 1580 | then | ||
| 1581 | (inTargetClassEnv, inTargetClass, inIH); | ||
| 1582 | |||
| 1583 | end matchcontinue; | ||
| 1584 | end mkVersionNode; | ||
| 1585 | |||
| 1586 | public function createVersionScope | ||
| 1587 | input Graph inSourceEnv; | ||
| 1588 | input Name inSourceName; | ||
| 1589 | input DAE.Prefix inPrefix; | ||
| 1590 | input DAE.Mod inMod; | ||
| 1591 | input Graph inTargetClassEnv; | ||
| 1592 | input SCode.Element inTargetClass; | ||
| 1593 | input InnerOuter.InstHierarchy inIH; | ||
| 1594 | output Graph outVersionedTargetClassEnv; | ||
| 1595 | output SCode.Element outVersionedTargetClass; | ||
| 1596 | output InnerOuter.InstHierarchy outIH; | ||
| 1597 | algorithm | ||
| 1598 | (outVersionedTargetClassEnv, outVersionedTargetClass, outIH) := matchcontinue inMod | ||
| 1599 | local | ||
| 1600 | Graph gclass; | ||
| 1601 | SCode.Element c; | ||
| 1602 | |||
| 1603 | /* | ||
| 1604 | case (_, _, _, _, _, _, _) | ||
| 1605 | algorithm | ||
| 1606 | print(AbsynUtil.pathString(PrefixUtil.prefixToPath(inPrefix)) + " S:" + getGraphNameStr(inSourceEnv) + "/" + inSourceName + " ||| " + "T:" + getGraphNameStr(inTargetClassEnv) + "/" + SCodeUtil.elementName(inTargetClass) + "\n"); | ||
| 1607 | then | ||
| 1608 | fail();*/ | ||
| 1609 | |||
| 1610 | // case (_, _, _, _, _, _, _) then (inTargetClassEnv, inTargetClass, inIH); | ||
| 1611 | |||
| 1612 | // don't do this if there is no modifications on the class | ||
| 1613 | // TODO! FIXME! wonder if we can skip this if it has only a binding, not an actual type modifier | ||
| 1614 | 301894 | case DAE.NOMOD() then (inTargetClassEnv, inTargetClass, inIH); | |
| 1615 | 218830 | case DAE.MOD(subModLst={}) then (inTargetClassEnv, inTargetClass, inIH); | |
| 1616 | |||
| 1617 | // don't do this for MetaModelica, target class is builtin or builtin type, functions | ||
| 1618 | case _ | ||
| 1619 | algorithm | ||
| 1620 |
7/8✓ Branch 1 taken 40331 times.
✓ Branch 2 taken 24 times.
✓ Branch 4 taken 23324 times.
✓ Branch 5 taken 17007 times.
✓ Branch 7 taken 20715 times.
✓ Branch 8 taken 2609 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 20715 times.
|
40355 | true := Config.acceptMetaModelicaGrammar() or |
| 1621 | isTargetClassBuiltin(inTargetClassEnv, inTargetClass) or | ||
| 1622 | inFunctionScope(inSourceEnv) or | ||
| 1623 | SCodeUtil.isOperatorRecord(inTargetClass); | ||
| 1624 | 19640 | then | |
| 1625 | (inTargetClassEnv, inTargetClass, inIH); | ||
| 1626 | |||
| 1627 | // or OpenModelica scripting stuff | ||
| 1628 | case _ | ||
| 1629 | algorithm | ||
| 1630 |
3/4✓ Branch 2 taken 1268 times.
✓ Branch 3 taken 19348 times.
✓ Branch 7 taken 1268 times.
✗ Branch 8 not taken.
|
20715 | true := stringEq(AbsynUtil.pathFirstIdent(getGraphName(inTargetClassEnv)), "OpenModelica"); |
| 1631 | ✗ | then | |
| 1632 | (inTargetClassEnv, inTargetClass, inIH); | ||
| 1633 | |||
| 1634 | // need to create a new version of the class | ||
| 1635 | case _ | ||
| 1636 | algorithm | ||
| 1637 | 20715 | (gclass, c, outIH) := mkVersionNode(inSourceEnv, inSourceName, inPrefix, inMod, inTargetClassEnv, inTargetClass, inIH); | |
| 1638 | then | ||
| 1639 | (gclass, c, outIH); | ||
| 1640 | |||
| 1641 | end matchcontinue; | ||
| 1642 | end createVersionScope; | ||
| 1643 | |||
| 1644 | public function isTargetClassBuiltin | ||
| 1645 | input Graph inGraph; | ||
| 1646 | input SCode.Element inClass; | ||
| 1647 | output Boolean yes; | ||
| 1648 | algorithm | ||
| 1649 | yes := matchcontinue inClass | ||
| 1650 | local Ref r; | ||
| 1651 | case _ | ||
| 1652 | algorithm | ||
| 1653 | 40331 | r := FNode.child(lastScopeRef(inGraph), SCodeUtil.elementName(inClass)); | |
| 1654 |
4/4✓ Branch 1 taken 23325 times.
✓ Branch 2 taken 17006 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 23324 times.
|
40331 | yes := FNode.isRefBasicType(r) or FNode.isRefBuiltin(r); |
| 1655 | then | ||
| 1656 | yes; | ||
| 1657 | |||
| 1658 | else false; | ||
| 1659 | end matchcontinue; | ||
| 1660 | end isTargetClassBuiltin; | ||
| 1661 | |||
| 1662 | public function mkVersionName | ||
| 1663 | input Graph inSourceEnv; | ||
| 1664 | input Name inSourceName; | ||
| 1665 | input DAE.Prefix inPrefix; | ||
| 1666 | input DAE.Mod inMod; | ||
| 1667 | input Graph inTargetClassEnv; | ||
| 1668 | input Name inTargetClassName; | ||
| 1669 | output Name outName; | ||
| 1670 | output DAE.Prefix outCrefPrefix; | ||
| 1671 | algorithm | ||
| 1672 | (outName, outCrefPrefix) := match inTargetClassName | ||
| 1673 | local | ||
| 1674 | DAE.Prefix crefPrefix; | ||
| 1675 | Name name; | ||
| 1676 | |||
| 1677 | case _ | ||
| 1678 | algorithm | ||
| 1679 | 20715 | crefPrefix := PrefixUtil.prefixAdd(inSourceName,{},{},inPrefix,SCode.CONST(),ClassInf.UNKNOWN(Absyn.IDENT("")), Absyn.dummyInfo); // variability doesn't matter | |
| 1680 | |||
| 1681 | // name = inTargetClassName + "$" + ComponentReferenceBasics.printComponentRefStr(PrefixUtil.prefixToCref(crefPrefix)); | ||
| 1682 | 20715 | name := inTargetClassName + "$" + AbsynUtil.pathString(AbsynUtil.stringListPath(listReverse(AbsynUtil.pathToStringList(PrefixUtil.prefixToPath(crefPrefix)))), "$", usefq=false) | |
| 1683 | ; // + "$" + AbsynUtil.pathString2NoLeadingDot(getGraphName(inSourceEnv), "$"); | ||
| 1684 | // name = "'$" + inTargetClassName + "@" + AbsynUtil.pathString(AbsynUtil.stringListPath(listReverse(AbsynUtil.pathToStringList(PrefixUtil.prefixToPath(crefPrefix))))) + "'"; | ||
| 1685 | // name = "'$" + getGraphNameStr(inSourceEnv) + "." + AbsynUtil.pathString(AbsynUtil.stringListPath(listReverse(AbsynUtil.pathToStringList(PrefixUtil.prefixToPath(crefPrefix))))) + "'"; | ||
| 1686 | // name = "$'" + getGraphNameStr(inSourceEnv) + "." + | ||
| 1687 | // AbsynUtil.pathString(AbsynUtil.stringListPath(listReverse(AbsynUtil.pathToStringList(PrefixUtil.prefixToPath(crefPrefix))))) + | ||
| 1688 | // SCodeDump.printModStr(Mod.unelabMod(inMod), SCodeDump.defaultOptions); | ||
| 1689 | then | ||
| 1690 | (name, crefPrefix); | ||
| 1691 | |||
| 1692 | end match; | ||
| 1693 | end mkVersionName; | ||
| 1694 | |||
| 1695 | public function getClassPrefix | ||
| 1696 | input FCore.Graph inEnv; | ||
| 1697 | input Name inClassName; | ||
| 1698 | output DAE.Prefix outPrefix; | ||
| 1699 | algorithm | ||
| 1700 | outPrefix := matchcontinue inClassName | ||
| 1701 | local | ||
| 1702 | DAE.Prefix p; | ||
| 1703 | Ref r; | ||
| 1704 | |||
| 1705 | case _ | ||
| 1706 | algorithm | ||
| 1707 | ✗ | r := FNode.child(lastScopeRef(inEnv), inClassName); | |
| 1708 | ✗ | FCore.CL(pre = p) := FNode.refData(r); | |
| 1709 | then | ||
| 1710 | p; | ||
| 1711 | |||
| 1712 | else DAE.NOPRE(); | ||
| 1713 | |||
| 1714 | end matchcontinue; | ||
| 1715 | end getClassPrefix; | ||
| 1716 | |||
| 1717 | public function isInstance | ||
| 1718 | input FCore.Graph inEnv; | ||
| 1719 | input FCore.Name inName; | ||
| 1720 | output Boolean yes; | ||
| 1721 | algorithm | ||
| 1722 | yes := matchcontinue inName | ||
| 1723 | |||
| 1724 | case _ | ||
| 1725 | algorithm | ||
| 1726 | ✗ | FCore.CL(status = FCore.CLS_INSTANCE(_)) := FNode.refData(FNode.child(lastScopeRef(inEnv), inName)); | |
| 1727 | then | ||
| 1728 | true; | ||
| 1729 | |||
| 1730 | else false; | ||
| 1731 | |||
| 1732 | end matchcontinue; | ||
| 1733 | end isInstance; | ||
| 1734 | |||
| 1735 | public function getInstanceOriginalName | ||
| 1736 | input FCore.Graph inEnv; | ||
| 1737 | input FCore.Name inName; | ||
| 1738 | output FCore.Name outName; | ||
| 1739 | algorithm | ||
| 1740 | outName := matchcontinue inName | ||
| 1741 | |||
| 1742 | case _ | ||
| 1743 | algorithm | ||
| 1744 |
3/4✗ Branch 3 not taken.
✓ Branch 4 taken 3514 times.
✓ Branch 5 taken 992 times.
✓ Branch 6 taken 2522 times.
|
3514 | FCore.CL(status = FCore.CLS_INSTANCE(outName)) := FNode.refData(FNode.child(lastScopeRef(inEnv), inName)); |
| 1745 | then | ||
| 1746 | outName; | ||
| 1747 | |||
| 1748 | else inName; | ||
| 1749 | |||
| 1750 | end matchcontinue; | ||
| 1751 | end getInstanceOriginalName; | ||
| 1752 | |||
| 1753 | public function graphPrefixOf | ||
| 1754 | "note that A.B.C is not prefix of A.B.C, | ||
| 1755 | only A.B is a prefix of A.B.C" | ||
| 1756 | input Graph inPrefixEnv; | ||
| 1757 | input Graph inEnv; | ||
| 1758 | output Boolean outIsPrefix; | ||
| 1759 | algorithm | ||
| 1760 | 1 | outIsPrefix := graphPrefixOf2(listReverse(currentScope(inPrefixEnv)), listReverse(currentScope(inEnv))); | |
| 1761 | end graphPrefixOf; | ||
| 1762 | |||
| 1763 | public function graphPrefixOf2 | ||
| 1764 | "Checks if one environment is a prefix of another. | ||
| 1765 | note that A.B.C is not prefix of A.B.C, | ||
| 1766 | only A.B is a prefix of A.B.C" | ||
| 1767 | input Scope inPrefixEnv; | ||
| 1768 | input Scope inEnv; | ||
| 1769 | output Boolean outIsPrefix; | ||
| 1770 | algorithm | ||
| 1771 | outIsPrefix := match(inPrefixEnv, inEnv) | ||
| 1772 | local | ||
| 1773 | Scope rest1, rest2; | ||
| 1774 | Ref r1, r2; | ||
| 1775 | |||
| 1776 | case ({}, _::_) then true; | ||
| 1777 | |||
| 1778 | case (r1 :: rest1, r2 :: rest2) guard stringEq(FNode.refName(r1), FNode.refName(r2)) | ||
| 1779 | 2 | then | |
| 1780 | graphPrefixOf2(rest1, rest2); | ||
| 1781 | |||
| 1782 | else false; | ||
| 1783 | |||
| 1784 | end match; | ||
| 1785 | end graphPrefixOf2; | ||
| 1786 | |||
| 1787 | public function setStatus | ||
| 1788 | input Graph inEnv; | ||
| 1789 | input Name inName; | ||
| 1790 | input FCore.Data inStatus; | ||
| 1791 | output Graph outEnv; | ||
| 1792 | algorithm | ||
| 1793 | outEnv := matchcontinue inEnv | ||
| 1794 | local | ||
| 1795 | Graph g; | ||
| 1796 | Node n; | ||
| 1797 | Ref ref, refParent; | ||
| 1798 | |||
| 1799 | case g | ||
| 1800 | algorithm | ||
| 1801 | ✗ | refParent := lastScopeRef(g); | |
| 1802 | ✗ | if FNode.refHasChild(refParent, inName) then | |
| 1803 | ✗ | ref := FNode.child(refParent, inName); | |
| 1804 | ✗ | if FNode.refHasChild(ref, FNode.statusNodeName) then | |
| 1805 | // child exists and has a status node | ||
| 1806 | ✗ | ref := FNode.child(ref, FNode.statusNodeName); | |
| 1807 | ✗ | n := FNode.setData(FNode.fromRef(ref), inStatus); | |
| 1808 | ✗ | ref := FNode.updateRef(ref, n); | |
| 1809 | else | ||
| 1810 | // child exists but has no status node | ||
| 1811 | ✗ | (g, n) := node(g, FNode.statusNodeName, {ref}, inStatus); | |
| 1812 | ✗ | FNode.addChildRef(ref, FNode.statusNodeName, FNode.toRef(n)); | |
| 1813 | end if; | ||
| 1814 | //else child does not exist, do nothing, is an import or extends | ||
| 1815 | end if; | ||
| 1816 | then | ||
| 1817 | g; | ||
| 1818 | |||
| 1819 | // did we fail for some weird reson? | ||
| 1820 | case g | ||
| 1821 | algorithm | ||
| 1822 | ✗ | print("FGraph.setStatus failed on: " + getGraphNameStr(g) + " element: " + inName + "\n"); | |
| 1823 | then | ||
| 1824 | g; | ||
| 1825 | |||
| 1826 | end matchcontinue; | ||
| 1827 | end setStatus; | ||
| 1828 | |||
| 1829 | public function getStatus | ||
| 1830 | input Graph inEnv; | ||
| 1831 | input Name inName; | ||
| 1832 | output FCore.Data outStatus; | ||
| 1833 | algorithm | ||
| 1834 | outStatus := match inEnv | ||
| 1835 | local | ||
| 1836 | Graph g; | ||
| 1837 | Ref ref, refParent; | ||
| 1838 | FCore.Data s; | ||
| 1839 | |||
| 1840 | // child exists and has a status node | ||
| 1841 | case g | ||
| 1842 | algorithm | ||
| 1843 | ✗ | refParent := lastScopeRef(g); | |
| 1844 | ✗ | true := FNode.refHasChild(refParent, inName); | |
| 1845 | ✗ | ref := FNode.child(refParent, inName); | |
| 1846 | ✗ | true := FNode.refHasChild(ref, FNode.statusNodeName); | |
| 1847 | ✗ | ref := FNode.child(ref, FNode.statusNodeName); | |
| 1848 | ✗ | s := FNode.refData(ref); | |
| 1849 | then | ||
| 1850 | s; | ||
| 1851 | |||
| 1852 | // we can fail here with no problem, there is no status node! | ||
| 1853 | case _ | ||
| 1854 | algorithm | ||
| 1855 | // print("FGraph.getStatus failed on: " + getGraphNameStr(g) + " element: " + inName + "\n"); | ||
| 1856 | then | ||
| 1857 | fail(); | ||
| 1858 | |||
| 1859 | end match; | ||
| 1860 | end getStatus; | ||
| 1861 | |||
| 1862 | public function selectScope | ||
| 1863 | "return the environment pointed by the path if it exists, else fails" | ||
| 1864 | input Graph inEnv; | ||
| 1865 | input Absyn.Path inPath; | ||
| 1866 | output Graph outEnv; | ||
| 1867 | algorithm | ||
| 1868 | outEnv := match inPath | ||
| 1869 | local | ||
| 1870 | Graph env; | ||
| 1871 | list<String> pl; | ||
| 1872 | Integer lp, le, diff; | ||
| 1873 | Scope cs; | ||
| 1874 | Absyn.Path p; | ||
| 1875 | |||
| 1876 | case _ | ||
| 1877 | algorithm | ||
| 1878 | 74956 | p := AbsynUtil.stripLast(inPath); | |
| 1879 |
2/2✓ Branch 2 taken 20830 times.
✓ Branch 3 taken 233 times.
|
45187 | true := AbsynUtil.pathPrefixOf(p, getGraphName(inEnv)); |
| 1880 | 233 | pl := AbsynUtil.pathToStringList(p); | |
| 1881 | 233 | lp := listLength(pl); | |
| 1882 | 233 | cs := currentScope(inEnv); | |
| 1883 | 233 | le := listLength(cs) - 1; | |
| 1884 | 233 | diff := le - lp; | |
| 1885 | 233 | cs := List.stripN(cs, diff); | |
| 1886 | 233 | env := setScope(inEnv, cs); | |
| 1887 | // print("F: " + AbsynUtil.pathString(inPath) + "\n"); print("E: " + getGraphNameStr(inEnv) + "\n"); print("R: " + getGraphNameStr(env) + "\n"); | ||
| 1888 | then | ||
| 1889 | env; | ||
| 1890 | |||
| 1891 | end match; | ||
| 1892 | end selectScope; | ||
| 1893 | |||
| 1894 | public function makeScopePartial | ||
| 1895 | input Graph inEnv; | ||
| 1896 | output Graph outEnv = inEnv; | ||
| 1897 | protected | ||
| 1898 | Node node; | ||
| 1899 | Data data; | ||
| 1900 | SCode.Element el; | ||
| 1901 | algorithm | ||
| 1902 | try | ||
| 1903 | ✗ | node := FNode.fromRef(lastScopeRef(inEnv)); | |
| 1904 | node := match node | ||
| 1905 | case FCore.N(data = data as FCore.CL(e = el)) | ||
| 1906 | algorithm | ||
| 1907 | ✗ | el := SCodeUtil.makeClassPartial(el); | |
| 1908 | ✗ | data.e := el; | |
| 1909 | ✗ | node.data := data; | |
| 1910 | then | ||
| 1911 | node; | ||
| 1912 | |||
| 1913 | else node; | ||
| 1914 | end match; | ||
| 1915 | ✗ | outEnv := setLastScopeRef(FNode.toRef(node), outEnv); | |
| 1916 | else | ||
| 1917 | end try; | ||
| 1918 | end makeScopePartial; | ||
| 1919 | |||
| 1920 | public function isPartialScope | ||
| 1921 | input Graph inEnv; | ||
| 1922 | output Boolean outIsPartial; | ||
| 1923 | protected | ||
| 1924 | SCode.Element el; | ||
| 1925 | algorithm | ||
| 1926 | try | ||
| 1927 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 403750 times.
|
403750 | FCore.N(data = FCore.CL(e = el)) := FNode.fromRef(lastScopeRef(inEnv)); |
| 1928 | 403750 | outIsPartial := SCodeUtil.isPartial(el); | |
| 1929 | else | ||
| 1930 | outIsPartial := false; | ||
| 1931 | end try; | ||
| 1932 | end isPartialScope; | ||
| 1933 | |||
| 1934 | annotation(__OpenModelica_Interface="frontend"); | ||
| 1935 | end FGraph; | ||
| 1936 |