OMCompiler/Compiler/FrontEnd/InstExtends.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 InstExtends | ||
| 37 | " file: InstExtends.mo | ||
| 38 | package: InstExtends | ||
| 39 | description: Model instantiation | ||
| 40 | |||
| 41 | |||
| 42 | This module is responsible for instantiation of the extends and | ||
| 43 | class extends constructs in Modelica models. | ||
| 44 | |||
| 45 | " | ||
| 46 | |||
| 47 | // public imports | ||
| 48 | public import Absyn; | ||
| 49 | public import AbsynUtil; | ||
| 50 | public import ClassInf; | ||
| 51 | public import DAE; | ||
| 52 | public import FCore; | ||
| 53 | public import InnerOuter; | ||
| 54 | public import SCode; | ||
| 55 | |||
| 56 | // protected imports | ||
| 57 | protected import AvlSetString; | ||
| 58 | protected import Config; | ||
| 59 | protected import ClassInfUtil; | ||
| 60 | protected import Debug; | ||
| 61 | protected import Dump; | ||
| 62 | protected import Error; | ||
| 63 | protected import ErrorExt; | ||
| 64 | protected import FGraph; | ||
| 65 | protected import Flags; | ||
| 66 | protected import Global; | ||
| 67 | protected import Inst; | ||
| 68 | protected import InstUtil; | ||
| 69 | protected import List; | ||
| 70 | protected import Lookup; | ||
| 71 | protected import Mod; | ||
| 72 | protected import SCodeDump; | ||
| 73 | protected import SCodeInstUtil; | ||
| 74 | protected import SCodeUtil; | ||
| 75 | protected import Util; | ||
| 76 | |||
| 77 | protected type InstanceHierarchy = InnerOuter.InstHierarchy "an instance hierarchy"; | ||
| 78 | |||
| 79 | protected function instExtendsList | ||
| 80 | "This function flattens out the inheritance structure of a class. It takes an | ||
| 81 | SCode.Element list and flattens out the extends nodes of that list. The | ||
| 82 | result is a list of components and lists of equations and algorithms." | ||
| 83 | input FCore.Cache inCache; | ||
| 84 | input FCore.Graph inEnv; | ||
| 85 | input InnerOuter.InstHierarchy inIH; | ||
| 86 | input DAE.Mod inMod; | ||
| 87 | input DAE.Prefix inPrefix; | ||
| 88 | input list<SCode.Element> inLocalElements; | ||
| 89 | input list<SCode.Element> inElementsFromExtendsScope; | ||
| 90 | input ClassInf.State inState; | ||
| 91 | input String inClassName "The class whose elements are getting instantiated"; | ||
| 92 | input Boolean inImpl; | ||
| 93 | input Boolean inPartialInst; | ||
| 94 | output FCore.Cache outCache = inCache; | ||
| 95 | output FCore.Graph outEnv = inEnv; | ||
| 96 | output InnerOuter.InstHierarchy outIH = inIH; | ||
| 97 | output DAE.Mod outMod = inMod; | ||
| 98 | output list<tuple<SCode.Element, DAE.Mod, Boolean>> outElements = {}; | ||
| 99 | output list<SCode.Equation> outNormalEqs = {}; | ||
| 100 | output list<SCode.Equation> outInitialEqs = {}; | ||
| 101 | output list<SCode.AlgorithmSection> outNormalAlgs = {}; | ||
| 102 | output list<SCode.AlgorithmSection> outInitialAlgs = {}; | ||
| 103 | output list<SCode.Comment> outComments = {}; | ||
| 104 | protected | ||
| 105 | list<SCode.Element> duplicates = {}; | ||
| 106 | list<String> duplicateUnparseStrings = {}; | ||
| 107 | algorithm | ||
| 108 | /* | ||
| 109 | Variables can be duplicated after inheritance not before. | ||
| 110 | */ | ||
| 111 | 264944 | duplicates := List.sortedDuplicates(List.sort(inElementsFromExtendsScope, | |
| 112 | SCodeUtil.elementEqual), SCodeUtil.elementEqual); | ||
| 113 | /* | ||
| 114 | For MetaModelica grammar we allow a special instance of this rule. | ||
| 115 | We only keep duplicate that are not restricted to TypeVar. | ||
| 116 | */ | ||
| 117 |
2/2✓ Branch 1 taken 56094 times.
✓ Branch 2 taken 208850 times.
|
264944 | if Config.acceptMetaModelicaGrammar() then |
| 118 | 56094 | duplicates := List.filterOnFalse(duplicates, SCodeUtil.isTypeVar); | |
| 119 | end if; | ||
| 120 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 264944 times.
|
264944 | if not listEmpty(duplicates) then |
| 121 | ✗ | duplicateUnparseStrings := list(SCodeDump.unparseElementStr(i) for i in duplicates); | |
| 122 | ✗ | if listLength(duplicates) > 1 then | |
| 123 | ✗ | Error.addMultiSourceMessage(Error.DUPLICATE_VARIABLE_ERROR, | |
| 124 | duplicateUnparseStrings, | ||
| 125 | List.map(duplicates, SCodeUtil.elementInfo)); | ||
| 126 | else | ||
| 127 | ✗ | Error.addSourceMessage(Error.DUPLICATE_VARIABLE_ERROR, | |
| 128 | duplicateUnparseStrings, | ||
| 129 | SCodeUtil.elementInfo(listHead(duplicates))); | ||
| 130 | end if; | ||
| 131 | ✗ | fail(); | |
| 132 | end if; | ||
| 133 |
2/2✓ Branch 1 taken 133653 times.
✓ Branch 2 taken 264942 times.
|
398595 | for el in listReverse(inLocalElements) loop |
| 134 | () := matchcontinue el | ||
| 135 | local | ||
| 136 | String cn, bc_str, scope_str, base_first_id; | ||
| 137 | SCode.Mod emod; | ||
| 138 | Boolean eq_name; | ||
| 139 | Option<SCode.Element> ocls; | ||
| 140 | SCode.Element cls; | ||
| 141 | FCore.Graph cenv; | ||
| 142 | SCode.Encapsulated encf; | ||
| 143 | list<SCode.Element> els1, rest_els, import_els, cdef_els, clsext_els; | ||
| 144 | list<tuple<SCode.Element, DAE.Mod, Boolean>> els2; | ||
| 145 | list<SCode.Equation> eq1, ieq1, eq2, ieq2; | ||
| 146 | list<SCode.AlgorithmSection> alg1, ialg1, alg2, ialg2; | ||
| 147 | list<SCode.Comment> comments1, comments2; | ||
| 148 | SCode.Comment cmt; | ||
| 149 | DAE.Mod mod; | ||
| 150 | AvlSetString.Tree tree; | ||
| 151 | array<FCore.Cache> cacheArr; | ||
| 152 | Boolean htHasEntries; | ||
| 153 | |||
| 154 | // Instantiate a basic type base class. | ||
| 155 | case SCode.EXTENDS() | ||
| 156 | algorithm | ||
| 157 |
2/2✓ Branch 1 taken 28857 times.
✓ Branch 2 taken 12646 times.
|
41503 | Absyn.IDENT(cn) := AbsynUtil.makeNotFullyQualified(el.baseClassPath); |
| 158 |
2/2✓ Branch 1 taken 8642 times.
✓ Branch 2 taken 4004 times.
|
12646 | true := InstUtil.isBuiltInClass(cn); |
| 159 | then | ||
| 160 | (); | ||
| 161 | |||
| 162 | // Instantiate a base class. | ||
| 163 | case SCode.EXTENDS() | ||
| 164 | algorithm | ||
| 165 | 37499 | emod := InstUtil.chainRedeclares(outMod, el.modifications); | |
| 166 | |||
| 167 | // Check if the extends is referencing the class we're instantiating. | ||
| 168 | 37499 | base_first_id := AbsynUtil.pathFirstIdent(el.baseClassPath); | |
| 169 |
5/6✓ Branch 0 taken 1301 times.
✓ Branch 1 taken 36198 times.
✓ Branch 3 taken 298 times.
✓ Branch 4 taken 1003 times.
✓ Branch 10 taken 298 times.
✗ Branch 11 not taken.
|
37499 | eq_name := stringEq(inClassName, base_first_id) and AbsynUtil.pathEqual( |
| 170 | ClassInfUtil.getStateName(inState), | ||
| 171 | AbsynUtil.joinPaths(FGraph.getGraphName(outEnv), | ||
| 172 | AbsynUtil.makeIdentPathFromString(base_first_id))); | ||
| 173 | |||
| 174 | // Look up the base class. | ||
| 175 | 37499 | (outCache, ocls, cenv) := | |
| 176 | lookupBaseClass(el.baseClassPath, eq_name, inClassName, outEnv, outCache); | ||
| 177 | |||
| 178 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 37499 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 37499 times.
|
37499 | if isSome(ocls) then |
| 179 | 37499 | SOME(cls) := ocls; | |
| 180 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 37499 times.
|
37499 | SCode.CLASS(name = cn, encapsulatedPrefix = encf, cmt=cmt) := cls; |
| 181 | else | ||
| 182 | // Base class could not be found, print an error unless --permissive | ||
| 183 | // is used. | ||
| 184 | ✗ | if Flags.getConfigBool(Flags.PERMISSIVE) then | |
| 185 | ✗ | bc_str := AbsynUtil.pathString(el.baseClassPath); | |
| 186 | ✗ | scope_str := FGraph.printGraphPathStr(inEnv); | |
| 187 | ✗ | Error.addSourceMessage(Error.LOOKUP_BASECLASS_ERROR, | |
| 188 | {bc_str, scope_str}, el.info); | ||
| 189 | end if; | ||
| 190 | ✗ | fail(); | |
| 191 | end if; | ||
| 192 | |||
| 193 | 37499 | (outCache, cenv, outIH, els1, eq1, ieq1, alg1, ialg1, mod, comments1) := | |
| 194 | instDerivedClasses(outCache, cenv, outIH, outMod, inPrefix, cls, inImpl, el.info); | ||
| 195 | 37499 | els1 := updateElementListVisibility(els1, el.visibility); | |
| 196 | |||
| 197 | // Build a set with the constant elements from the extends scope. | ||
| 198 | 37499 | tree := AvlSetString.new(); | |
| 199 | 37499 | tree := getLocalIdentList(InstUtil.constantAndParameterEls(inElementsFromExtendsScope), | |
| 200 | tree, getLocalIdentElement); | ||
| 201 | 37499 | tree := getLocalIdentList(InstUtil.constantAndParameterEls(els1), tree, getLocalIdentElement); | |
| 202 | |||
| 203 | // Fully qualify modifiers in extends in the extends environment. | ||
| 204 | 37499 | cacheArr := arrayCreate(1, outCache); | |
| 205 | 37499 | emod := fixModifications(cacheArr, inEnv, emod, tree); | |
| 206 | |||
| 207 | 37499 | cenv := FGraph.openScope(cenv, encf, cn, FGraph.classInfToScopeType(inState)); | |
| 208 | |||
| 209 | // Add classdefs and imports to env, so e.g. imports from baseclasses can be found. | ||
| 210 | 37499 | (import_els, cdef_els, clsext_els, rest_els) := | |
| 211 | InstUtil.splitEltsNoComponents(els1); | ||
| 212 | 37499 | (outCache, cenv, outIH) := InstUtil.addClassdefsToEnv(outCache, cenv, | |
| 213 | outIH, inPrefix, import_els, inImpl, NONE()); | ||
| 214 | 37499 | (outCache, cenv, outIH) := InstUtil.addClassdefsToEnv(outCache, cenv, | |
| 215 | outIH, inPrefix, cdef_els, inImpl, SOME(mod)); | ||
| 216 | |||
| 217 |
6/6✓ Branch 1 taken 97387 times.
✓ Branch 2 taken 3548 times.
✓ Branch 3 taken 100935 times.
✓ Branch 4 taken 37499 times.
✓ Branch 5 taken 3548 times.
✓ Branch 6 taken 37499 times.
|
138434 | rest_els := SCodeInstUtil.addRedeclareAsElementsToExtends(rest_els, |
| 218 | list(e for e guard(SCodeUtil.isRedeclareElement(e)) in rest_els)); | ||
| 219 | |||
| 220 | 37499 | outMod := Mod.elabUntypedMod(emod, Mod.EXTENDS(el.baseClassPath)); | |
| 221 | 37497 | outMod := Mod.merge(mod, outMod, "", false); | |
| 222 | |||
| 223 | 37497 | (outCache, _, outIH, _, els2, eq2, ieq2, alg2, ialg2, comments2) := | |
| 224 | instExtendsAndClassExtendsList2(outCache, cenv, outIH, outMod, inPrefix, | ||
| 225 | rest_els, clsext_els, els1, inState, inClassName, inImpl, inPartialInst); | ||
| 226 | |||
| 227 | 37497 | tree := AvlSetString.new(); | |
| 228 | 37497 | tree := getLocalIdentList(els2, tree, getLocalIdentElementTpl); | |
| 229 | 37497 | tree := getLocalIdentList(cdef_els, tree, getLocalIdentElement); | |
| 230 | 37497 | tree := getLocalIdentList(import_els, tree, getLocalIdentElement); | |
| 231 | 37497 | htHasEntries := not AvlSetString.isEmpty(tree); | |
| 232 | |||
| 233 | 37497 | arrayUpdate(cacheArr, 1, outCache); | |
| 234 |
2/2✓ Branch 0 taken 13514 times.
✓ Branch 1 taken 23983 times.
|
37497 | if htHasEntries then |
| 235 | 13514 | els2 := fixList(cacheArr, cenv, els2, tree, fixLocalIdent); | |
| 236 | end if; | ||
| 237 | // Update components with new merged modifiers. | ||
| 238 | //(els2, outMod) := updateComponentsAndClassdefs(els2, outMod, inEnv); | ||
| 239 | 37497 | outElements := listAppend(els2, outElements); | |
| 240 | |||
| 241 | 37497 | outNormalEqs := List.unionAppendListOnTrue(listReverse(eq2), outNormalEqs, valueEq); | |
| 242 | 37497 | outInitialEqs := List.unionAppendListOnTrue(listReverse(ieq2), outInitialEqs, valueEq); | |
| 243 | 37497 | outNormalAlgs := List.unionAppendListOnTrue(listReverse(alg2), outNormalAlgs, valueEq); | |
| 244 | 37497 | outInitialAlgs := List.unionAppendListOnTrue(listReverse(ialg2), outInitialAlgs, valueEq); | |
| 245 | 37497 | outComments := listAppend(comments1, listAppend(comments2, cmt::outComments)); | |
| 246 | |||
| 247 |
2/2✓ Branch 0 taken 32561 times.
✓ Branch 1 taken 4936 times.
|
37497 | if not inPartialInst then |
| 248 |
2/2✓ Branch 0 taken 12642 times.
✓ Branch 1 taken 19919 times.
|
32561 | if htHasEntries then |
| 249 | 12642 | eq1 := fixList(cacheArr, cenv, eq1, tree, fixEquation); | |
| 250 | 12642 | ieq1 := fixList(cacheArr, cenv, ieq1, tree, fixEquation); | |
| 251 | 12642 | alg1 := fixList(cacheArr, cenv, alg1, tree, fixAlgorithm); | |
| 252 | 12642 | ialg1 := fixList(cacheArr, cenv, ialg1, tree, fixAlgorithm); | |
| 253 | end if; | ||
| 254 | 32561 | outNormalEqs := List.unionAppendListOnTrue(listReverse(eq1), outNormalEqs, valueEq); | |
| 255 | 32561 | outInitialEqs := List.unionAppendListOnTrue(listReverse(ieq1), outInitialEqs, valueEq); | |
| 256 | 32561 | outNormalAlgs := List.unionAppendListOnTrue(listReverse(alg1), outNormalAlgs, valueEq); | |
| 257 | 32561 | outInitialAlgs := List.unionAppendListOnTrue(listReverse(ialg1), outInitialAlgs, valueEq); | |
| 258 | end if; | ||
| 259 | outCache := arrayGet(cacheArr, 1); | ||
| 260 | then | ||
| 261 | (); | ||
| 262 | |||
| 263 | // Skip any extends we couldn't handle if --permissive is given. | ||
| 264 | case SCode.EXTENDS() guard(Flags.getConfigBool(Flags.PERMISSIVE)) | ||
| 265 | then (); | ||
| 266 | |||
| 267 | case SCode.COMPONENT() | ||
| 268 | algorithm | ||
| 269 | // Keep only constants if partial inst, otherwise keep all components. | ||
| 270 |
4/4✓ Branch 2 taken 55865 times.
✓ Branch 3 taken 10407 times.
✓ Branch 4 taken 55857 times.
✓ Branch 5 taken 8 times.
|
66272 | if SCodeUtil.isConstant(SCodeUtil.attrVariability(el.attributes)) or not inPartialInst then |
| 271 | 66264 | outElements := (el, DAE.NOMOD(), false) :: outElements; | |
| 272 | end if; | ||
| 273 | then | ||
| 274 | (); | ||
| 275 | |||
| 276 | case SCode.CLASS() | ||
| 277 | algorithm | ||
| 278 | 25878 | outElements := (el, DAE.NOMOD(), false) :: outElements; | |
| 279 | 25878 | outComments := {el.cmt}; | |
| 280 | then | ||
| 281 | (); | ||
| 282 | |||
| 283 | case SCode.IMPORT() | ||
| 284 | algorithm | ||
| 285 | ✗ | outElements := (el, DAE.NOMOD(), false) :: outElements; | |
| 286 | then | ||
| 287 | (); | ||
| 288 | |||
| 289 | // Instantiation failed. | ||
| 290 | else | ||
| 291 | algorithm | ||
| 292 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | true := Flags.isSet(Flags.FAILTRACE); |
| 293 | ✗ | Debug.traceln("- Inst.instExtendsList failed on:\n\t" + | |
| 294 | "className: " + inClassName + "\n\t" + | ||
| 295 | "env: " + FGraph.printGraphPathStr(outEnv) + "\n\t" + | ||
| 296 | "mods: " + Mod.printModStr(outMod) + "\n\t" + | ||
| 297 | "elem: " + SCodeDump.unparseElementStr(el) | ||
| 298 | ); | ||
| 299 | ✗ | then | |
| 300 | fail(); | ||
| 301 | |||
| 302 | end matchcontinue; | ||
| 303 | end for; | ||
| 304 | |||
| 305 | 264942 | (outElements, outMod) := updateComponentsAndClassdefs(outElements, outMod, inEnv); | |
| 306 | end instExtendsList; | ||
| 307 | |||
| 308 | protected function lookupBaseClass | ||
| 309 | "Looks up a base class used in an extends clause." | ||
| 310 | input Absyn.Path inPath; | ||
| 311 | input Boolean inSelfReference; | ||
| 312 | input String inClassName; | ||
| 313 | input FCore.Graph inEnv; | ||
| 314 | input FCore.Cache inCache; | ||
| 315 | output FCore.Cache outCache; | ||
| 316 | output Option<SCode.Element> outElement; | ||
| 317 | output FCore.Graph outEnv; | ||
| 318 | algorithm | ||
| 319 | (outCache, outElement, outEnv) := match(inPath, inSelfReference) | ||
| 320 | local | ||
| 321 | String name; | ||
| 322 | SCode.Element elem; | ||
| 323 | FCore.Graph env; | ||
| 324 | FCore.Cache cache; | ||
| 325 | Absyn.Path path; | ||
| 326 | |||
| 327 | // We have a simple identifier with a self reference, i.e. a class which | ||
| 328 | // extends a base class with the same name. The only legal situation in this | ||
| 329 | // case is when extending a local class with the same name, e.g.: | ||
| 330 | // | ||
| 331 | // class A | ||
| 332 | // extends A; | ||
| 333 | // class A end A; | ||
| 334 | // end A; | ||
| 335 | case (Absyn.IDENT(name), true) | ||
| 336 | algorithm | ||
| 337 | // Only look the name up locally, otherwise we might get an infinite | ||
| 338 | // loop if the class extends itself. | ||
| 339 | ✗ | (elem, env) := Lookup.lookupClassLocal(inEnv, name); | |
| 340 | ✗ | then | |
| 341 | (inCache, SOME(elem), env); | ||
| 342 | |||
| 343 | // Otherwise, remove the first identifier if it's the same as the class name | ||
| 344 | // and look it up as normal. | ||
| 345 | case (_, _) | ||
| 346 | algorithm | ||
| 347 | 37499 | path := AbsynUtil.removePartialPrefix(Absyn.IDENT(inClassName), inPath); | |
| 348 | 37499 | (cache, elem, env) := Lookup.lookupClass(inCache, inEnv, path); | |
| 349 | 37499 | then | |
| 350 | (cache, SOME(elem), env); | ||
| 351 | |||
| 352 | else (inCache, NONE(), inEnv); | ||
| 353 | end match; | ||
| 354 | end lookupBaseClass; | ||
| 355 | |||
| 356 | protected function updateElementListVisibility | ||
| 357 | input list<SCode.Element> inElements; | ||
| 358 | input SCode.Visibility inVisibility; | ||
| 359 | output list<SCode.Element> outElements; | ||
| 360 | algorithm | ||
| 361 | outElements := match inVisibility | ||
| 362 | case SCode.PUBLIC() then inElements; | ||
| 363 |
4/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
|
4 | else list(SCodeUtil.makeElementProtected(e) for e in inElements); |
| 364 | end match; | ||
| 365 | end updateElementListVisibility; | ||
| 366 | |||
| 367 | public function instExtendsAndClassExtendsList " | ||
| 368 | This function flattens out the inheritance structure of a class. | ||
| 369 | It takes an SCode.Element list and flattens out the extends nodes and | ||
| 370 | class extends nodes of that list. The result is a list of components and | ||
| 371 | lists of equations and algorithms." | ||
| 372 | input FCore.Cache inCache; | ||
| 373 | input FCore.Graph inEnv; | ||
| 374 | input InnerOuter.InstHierarchy inIH; | ||
| 375 | input DAE.Mod inMod; | ||
| 376 | input DAE.Prefix inPrefix; | ||
| 377 | input list<SCode.Element> inExtendsElementLst; | ||
| 378 | input list<SCode.Element> inClassExtendsElementLst; | ||
| 379 | input list<SCode.Element> inElementsFromExtendsScope; | ||
| 380 | input ClassInf.State inState; | ||
| 381 | input String inClassName; // the class name whose elements are getting instantiated. | ||
| 382 | input Boolean inImpl; | ||
| 383 | input Boolean isPartialInst; | ||
| 384 | output FCore.Cache outCache; | ||
| 385 | output FCore.Graph outEnv; | ||
| 386 | output InnerOuter.InstHierarchy outIH; | ||
| 387 | output DAE.Mod outMod; | ||
| 388 | output list<tuple<SCode.Element, DAE.Mod>> outElements; | ||
| 389 | output list<SCode.Equation> outNormalEqs; | ||
| 390 | output list<SCode.Equation> outInitialEqs; | ||
| 391 | output list<SCode.AlgorithmSection> outNormalAlgs; | ||
| 392 | output list<SCode.AlgorithmSection> outInitialAlgs; | ||
| 393 | output list<SCode.Comment> outComments; | ||
| 394 | protected | ||
| 395 | list<tuple<SCode.Element, DAE.Mod, Boolean>> elts; | ||
| 396 | list<SCode.Element> cdefelts, tmpelts, extendselts; | ||
| 397 | algorithm | ||
| 398 | 227447 | extendselts := List.map(inExtendsElementLst, SCodeInstUtil.expandEnumerationClass); | |
| 399 | //fprintln(Flags.DEBUG,"instExtendsAndClassExtendsList: " + inClassName); | ||
| 400 | 227447 | (outCache,outEnv,outIH,outMod,elts,outNormalEqs,outInitialEqs,outNormalAlgs,outInitialAlgs,outComments):= | |
| 401 | instExtendsAndClassExtendsList2(inCache,inEnv,inIH,inMod,inPrefix,extendselts,inClassExtendsElementLst,inElementsFromExtendsScope,inState,inClassName,inImpl,isPartialInst); | ||
| 402 | // Filter out the last boolean in the tuple | ||
| 403 | 227445 | outElements := List.map(elts, Util.tuple312); | |
| 404 | // Create a list of the class definitions, since these can't be properly added in the recursive call | ||
| 405 | 227445 | tmpelts := List.map(outElements,Util.tuple21); | |
| 406 | 227445 | (_,cdefelts,_,_) := InstUtil.splitEltsNoComponents(tmpelts); | |
| 407 | // Add the class definitions to the environment | ||
| 408 | 227445 | (outCache,outEnv,outIH) := InstUtil.addClassdefsToEnv(outCache,outEnv,outIH,inPrefix,cdefelts,inImpl,SOME(outMod)); | |
| 409 | //fprintln(Flags.DEBUG,"instExtendsAndClassExtendsList: " + inClassName + " done"); | ||
| 410 | end instExtendsAndClassExtendsList; | ||
| 411 | |||
| 412 | protected function instExtendsAndClassExtendsList2 " | ||
| 413 | This function flattens out the inheritance structure of a class. | ||
| 414 | It takes an SCode.Element list and flattens out the extends nodes and | ||
| 415 | class extends nodes of that list. The result is a list of components and | ||
| 416 | lists of equations and algorithms." | ||
| 417 | input FCore.Cache inCache; | ||
| 418 | input FCore.Graph inEnv; | ||
| 419 | input InnerOuter.InstHierarchy inIH; | ||
| 420 | input DAE.Mod inMod; | ||
| 421 | input DAE.Prefix inPrefix; | ||
| 422 | input list<SCode.Element> inExtendsElementLst; | ||
| 423 | input list<SCode.Element> inClassExtendsElementLst; | ||
| 424 | input list<SCode.Element> inElementsFromExtendsScope; | ||
| 425 | input ClassInf.State inState; | ||
| 426 | input String inClassName; // the class name whose elements are getting instantiated. | ||
| 427 | input Boolean inImpl; | ||
| 428 | input Boolean isPartialInst; | ||
| 429 | output FCore.Cache outCache; | ||
| 430 | output FCore.Graph outEnv; | ||
| 431 | output InnerOuter.InstHierarchy outIH; | ||
| 432 | output DAE.Mod outMod; | ||
| 433 | output list<tuple<SCode.Element, DAE.Mod, Boolean>> outElements; | ||
| 434 | output list<SCode.Equation> outNormalEqs; | ||
| 435 | output list<SCode.Equation> outInitialEqs; | ||
| 436 | output list<SCode.AlgorithmSection> outNormalAlgs; | ||
| 437 | output list<SCode.AlgorithmSection> outInitialAlgs; | ||
| 438 | output list<SCode.Comment> comments; | ||
| 439 | algorithm | ||
| 440 | 264944 | (outCache,outEnv,outIH,outMod,outElements,outNormalEqs,outInitialEqs,outNormalAlgs,outInitialAlgs,comments):= | |
| 441 | instExtendsList(inCache,inEnv,inIH,inMod,inPrefix,inExtendsElementLst,inElementsFromExtendsScope,inState,inClassName,inImpl,isPartialInst); | ||
| 442 | 264942 | (outMod,outElements):=instClassExtendsList(inEnv,outMod,inClassExtendsElementLst,outElements); | |
| 443 | end instExtendsAndClassExtendsList2; | ||
| 444 | |||
| 445 | protected function instClassExtendsList | ||
| 446 | "Instantiate element nodes of type SCode.CLASS_EXTENDS. This is done by walking | ||
| 447 | the extended classes and performing the modifications in-place. The old class | ||
| 448 | will no longer be accessible." | ||
| 449 | input FCore.Graph inEnv; | ||
| 450 | input DAE.Mod inMod; | ||
| 451 | input list<SCode.Element> inClassExtendsList; | ||
| 452 | input list<tuple<SCode.Element, DAE.Mod, Boolean>> inElements; | ||
| 453 | output DAE.Mod outMod; | ||
| 454 | output list<tuple<SCode.Element, DAE.Mod, Boolean>> outElements; | ||
| 455 | algorithm | ||
| 456 | (outMod,outElements) := matchcontinue (inMod,inClassExtendsList,inElements) | ||
| 457 | local | ||
| 458 | SCode.Element first; | ||
| 459 | list<SCode.Element> rest; | ||
| 460 | String name; | ||
| 461 | list<SCode.Element> els; | ||
| 462 | list<tuple<SCode.Element, DAE.Mod, Boolean>> compelts; | ||
| 463 | DAE.Mod emod; | ||
| 464 | list<String> names; | ||
| 465 | |||
| 466 | 264942 | case (emod,{},compelts) then (emod,compelts); | |
| 467 | |||
| 468 | case (emod,(first as SCode.CLASS(name=name))::rest,compelts) | ||
| 469 | algorithm | ||
| 470 | 10070 | (emod,compelts) := instClassExtendsList2(inEnv,emod,name,first,compelts); | |
| 471 | 10070 | (emod,compelts) := instClassExtendsList(inEnv,emod,rest,compelts); | |
| 472 | then (emod,compelts); | ||
| 473 | |||
| 474 | case (_,SCode.CLASS(name=name)::_,compelts) | ||
| 475 | algorithm | ||
| 476 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 477 | ✗ | Debug.traceln("- Inst.instClassExtendsList failed " + name); | |
| 478 | ✗ | Debug.traceln(" Candidate classes: "); | |
| 479 | ✗ | els := List.map(compelts, Util.tuple31); | |
| 480 | ✗ | names := List.map(els, SCodeUtil.elementName); | |
| 481 | ✗ | Debug.traceln(stringDelimitList(names, ",")); | |
| 482 | ✗ | then fail(); | |
| 483 | |||
| 484 | end matchcontinue; | ||
| 485 | end instClassExtendsList; | ||
| 486 | |||
| 487 | protected function buildClassExtendsName | ||
| 488 | input String inEnvPath; | ||
| 489 | input String inClassName; | ||
| 490 | output String outClassName; | ||
| 491 | algorithm | ||
| 492 | 10070 | outClassName := "$parent." + inClassName + ".$env." + inEnvPath; | |
| 493 | end buildClassExtendsName; | ||
| 494 | |||
| 495 | protected function instClassExtendsList2 | ||
| 496 | input FCore.Graph inEnv; | ||
| 497 | input DAE.Mod inMod; | ||
| 498 | input String inName; | ||
| 499 | input SCode.Element inClassExtendsElt; | ||
| 500 | input list<tuple<SCode.Element, DAE.Mod, Boolean>> inElements; | ||
| 501 | output DAE.Mod outMod; | ||
| 502 | output list<tuple<SCode.Element, DAE.Mod, Boolean>> outElements; | ||
| 503 | algorithm | ||
| 504 | (outMod,outElements) := matchcontinue (inMod,inName,inClassExtendsElt,inElements) | ||
| 505 | local | ||
| 506 | SCode.Element elt,compelt,classExtendsElt; | ||
| 507 | SCode.Element cl; | ||
| 508 | SCode.ClassDef classDef,classExtendsCdef; | ||
| 509 | SCode.Partial partialPrefix1,partialPrefix2; | ||
| 510 | SCode.Encapsulated encapsulatedPrefix1,encapsulatedPrefix2; | ||
| 511 | SCode.Restriction restriction1,restriction2; | ||
| 512 | SCode.Prefixes prefixes1,prefixes2; | ||
| 513 | SCode.Visibility vis2; | ||
| 514 | String name1,name2,env_path; | ||
| 515 | Option<SCode.ExternalDecl> externalDecl1,externalDecl2; | ||
| 516 | SCode.Comment comment1,comment2; | ||
| 517 | list<SCode.Element> els1,els2; | ||
| 518 | list<SCode.Equation> nEqn1,nEqn2,inEqn1,inEqn2; | ||
| 519 | list<SCode.AlgorithmSection> nAlg1,nAlg2,inAlg1,inAlg2; | ||
| 520 | list<SCode.ConstraintSection> inCons1, inCons2; | ||
| 521 | list<Absyn.NamedArg> clats; | ||
| 522 | list<tuple<SCode.Element, DAE.Mod, Boolean>> rest; | ||
| 523 | tuple<SCode.Element, DAE.Mod, Boolean> first; | ||
| 524 | SCode.Mod mods, derivedMod; | ||
| 525 | DAE.Mod mod1,emod; | ||
| 526 | SourceInfo info1, info2; | ||
| 527 | Boolean b; | ||
| 528 | SCode.Attributes attrs; | ||
| 529 | Absyn.TypeSpec derivedTySpec; | ||
| 530 | |||
| 531 | // found the base class with parts | ||
| 532 | case (emod,name1,classExtendsElt,(cl as SCode.CLASS(name = name2, classDef = SCode.PARTS()),mod1,b)::rest) | ||
| 533 | algorithm | ||
| 534 |
4/4✓ Branch 0 taken 22966 times.
✓ Branch 1 taken 371451 times.
✓ Branch 3 taken 10070 times.
✓ Branch 4 taken 12896 times.
|
394417 | true := name1 == name2; // Compare the name before pattern-matching to speed this up |
| 535 | |||
| 536 | 10070 | env_path := AbsynUtil.pathString(FGraph.getGraphName(inEnv)); | |
| 537 | 10070 | name2 := buildClassExtendsName(env_path,name2); | |
| 538 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 10070 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10070 times.
|
10070 | SCode.CLASS(_,prefixes2,encapsulatedPrefix2,partialPrefix2,restriction2,SCode.PARTS(els2,nEqn2,inEqn2,nAlg2,inAlg2,inCons2,clats,externalDecl2),comment2,info2) := cl; |
| 539 | |||
| 540 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10070 times.
|
10070 | SCode.CLASS(_, prefixes1, encapsulatedPrefix1, partialPrefix1, restriction1, classExtendsCdef, comment1, info1) := classExtendsElt; |
| 541 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 10070 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10070 times.
|
10070 | SCode.CLASS_EXTENDS(mods,SCode.PARTS(els1,nEqn1,inEqn1,nAlg1,inAlg1,inCons1,_,externalDecl1)) := classExtendsCdef; |
| 542 | |||
| 543 | 10070 | classDef := SCode.PARTS(els2,nEqn2,inEqn2,nAlg2,inAlg2,inCons2,clats,externalDecl2); | |
| 544 | 10070 | compelt := SCode.CLASS(name2,prefixes2,encapsulatedPrefix2,partialPrefix2,restriction2,classDef,comment2,info2); | |
| 545 | 10070 | vis2 := SCodeUtil.prefixesVisibility(prefixes2); | |
| 546 | 10070 | elt := SCode.EXTENDS(Absyn.IDENT(name2),vis2,mods,NONE(),info1); | |
| 547 | 10070 | classDef := SCode.PARTS(elt::els1,nEqn1,inEqn1,nAlg1,inAlg1,inCons1,clats,externalDecl1); | |
| 548 | 10070 | elt := SCode.CLASS(name1, prefixes1, encapsulatedPrefix1, partialPrefix1, restriction1, classDef, comment1, info1); | |
| 549 | 10070 | emod := Mod.renameTopLevelNamedSubMod(emod,name1,name2); | |
| 550 | //Debug.traceln("class extends: " + SCodeDump.unparseElementStr(compelt) + " " + SCodeDump.unparseElementStr(elt)); | ||
| 551 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10070 times.
|
10070 | then |
| 552 | (emod,(compelt,mod1,b)::(elt,DAE.NOMOD(),true)::rest); | ||
| 553 | |||
| 554 | // found the base class which is derived | ||
| 555 | case (emod,name1,classExtendsElt,(cl as SCode.CLASS(name = name2, classDef = SCode.DERIVED()),mod1,b)::rest) | ||
| 556 | algorithm | ||
| 557 |
3/4✓ Branch 0 taken 16559 times.
✓ Branch 1 taken 240113 times.
✓ Branch 3 taken 16559 times.
✗ Branch 4 not taken.
|
256672 | true := name1 == name2; // Compare the name before pattern-matching to speed this up |
| 558 | |||
| 559 | ✗ | env_path := AbsynUtil.pathString(FGraph.getGraphName(inEnv)); | |
| 560 | ✗ | name2 := buildClassExtendsName(env_path,name2); | |
| 561 | ✗ | SCode.CLASS(_,prefixes2,encapsulatedPrefix2,partialPrefix2,restriction2,SCode.DERIVED(derivedTySpec, derivedMod, attrs),comment2,info2) := cl; | |
| 562 | |||
| 563 | ✗ | SCode.CLASS(_, prefixes1, encapsulatedPrefix1, partialPrefix1, restriction1, classExtendsCdef, comment1, info1) := classExtendsElt; | |
| 564 | ✗ | SCode.CLASS_EXTENDS(mods,SCode.PARTS(els1,nEqn1,inEqn1,nAlg1,inAlg1,inCons1,_,externalDecl1)) := classExtendsCdef; | |
| 565 | |||
| 566 | ✗ | classDef := SCode.DERIVED(derivedTySpec, derivedMod, attrs); | |
| 567 | ✗ | compelt := SCode.CLASS(name2,prefixes2,encapsulatedPrefix2,partialPrefix2,restriction2,classDef,comment2,info2); | |
| 568 | ✗ | vis2 := SCodeUtil.prefixesVisibility(prefixes2); | |
| 569 | ✗ | elt := SCode.EXTENDS(Absyn.IDENT(name2),vis2,mods,NONE(),info1); | |
| 570 | ✗ | classDef := SCode.PARTS(elt::els1,nEqn1,inEqn1,nAlg1,inAlg1,inCons1,{},externalDecl1); | |
| 571 | ✗ | elt := SCode.CLASS(name1, prefixes1, encapsulatedPrefix1, partialPrefix1, restriction1, classDef, comment1, info1); | |
| 572 | ✗ | emod := Mod.renameTopLevelNamedSubMod(emod,name1,name2); | |
| 573 | //Debug.traceln("class extends: " + SCodeDump.unparseElementStr(compelt) + " " + SCodeDump.unparseElementStr(elt)); | ||
| 574 | ✗ | then | |
| 575 | (emod,(compelt,mod1,b)::(elt,DAE.NOMOD(),true)::rest); | ||
| 576 | |||
| 577 | // not this one, switch to next one | ||
| 578 | case (emod,name1,classExtendsElt,first::rest) | ||
| 579 | algorithm | ||
| 580 | 824075 | (emod,rest) := instClassExtendsList2(inEnv,emod,name1,classExtendsElt,rest); | |
| 581 | 824075 | then | |
| 582 | (emod,first::rest); | ||
| 583 | |||
| 584 | // bah, we did not find it | ||
| 585 | case (_,_,_,{}) | ||
| 586 | algorithm | ||
| 587 | |||
| 588 | ✗ | Debug.traceln("TODO: Make a proper Error message here - Inst.instClassExtendsList2 couldn't find the class to extend"); | |
| 589 | ✗ | then | |
| 590 | fail(); | ||
| 591 | |||
| 592 | end matchcontinue; | ||
| 593 | end instClassExtendsList2; | ||
| 594 | |||
| 595 | public function instDerivedClasses | ||
| 596 | "author: PA | ||
| 597 | This function takes a class definition and returns the | ||
| 598 | elements and equations and algorithms of the class. | ||
| 599 | If the class is derived, the class is looked up and the | ||
| 600 | derived class parts are fetched." | ||
| 601 | input FCore.Cache inCache; | ||
| 602 | input FCore.Graph inEnv; | ||
| 603 | input InnerOuter.InstHierarchy inIH; | ||
| 604 | input DAE.Mod inMod; | ||
| 605 | input DAE.Prefix inPrefix; | ||
| 606 | input SCode.Element inClass; | ||
| 607 | input Boolean inBoolean; | ||
| 608 | input SourceInfo inInfo "File information of the extends element"; | ||
| 609 | output FCore.Cache outCache; | ||
| 610 | output FCore.Graph outEnv1; | ||
| 611 | output InnerOuter.InstHierarchy outIH; | ||
| 612 | output list<SCode.Element> outSCodeElementLst2; | ||
| 613 | output list<SCode.Equation> outSCodeEquationLst3; | ||
| 614 | output list<SCode.Equation> outSCodeEquationLst4; | ||
| 615 | output list<SCode.AlgorithmSection> outSCodeAlgorithmLst5; | ||
| 616 | output list<SCode.AlgorithmSection> outSCodeAlgorithmLst6; | ||
| 617 | output DAE.Mod outMod; | ||
| 618 | output list<SCode.Comment> outComments; | ||
| 619 | algorithm | ||
| 620 | 37519 | (outCache,outEnv1,outIH,outSCodeElementLst2,outSCodeEquationLst3,outSCodeEquationLst4,outSCodeAlgorithmLst5,outSCodeAlgorithmLst6,outMod,outComments) := | |
| 621 | instDerivedClassesWork(inCache,inEnv,inIH,inMod,inPrefix,inClass,inBoolean,inInfo,false,0); | ||
| 622 | end instDerivedClasses; | ||
| 623 | |||
| 624 | protected function instDerivedClassesWork | ||
| 625 | "author: PA | ||
| 626 | This function takes a class definition and returns the | ||
| 627 | elements and equations and algorithms of the class. | ||
| 628 | If the class is derived, the class is looked up and the | ||
| 629 | derived class parts are fetched." | ||
| 630 | input FCore.Cache inCache; | ||
| 631 | input FCore.Graph inEnv; | ||
| 632 | input InnerOuter.InstHierarchy inIH; | ||
| 633 | input DAE.Mod inMod; | ||
| 634 | input DAE.Prefix inPrefix; | ||
| 635 | input SCode.Element inClass; | ||
| 636 | input Boolean inBoolean; | ||
| 637 | input SourceInfo inInfo "File information of the extends element"; | ||
| 638 | input Boolean overflow; | ||
| 639 | input Integer numIter; | ||
| 640 | output FCore.Cache outCache; | ||
| 641 | output FCore.Graph outEnv1; | ||
| 642 | output InnerOuter.InstHierarchy outIH; | ||
| 643 | output list<SCode.Element> outSCodeElementLst2; | ||
| 644 | output list<SCode.Equation> outSCodeEquationLst3; | ||
| 645 | output list<SCode.Equation> outSCodeEquationLst4; | ||
| 646 | output list<SCode.AlgorithmSection> outSCodeAlgorithmLst5; | ||
| 647 | output list<SCode.AlgorithmSection> outSCodeAlgorithmLst6; | ||
| 648 | output DAE.Mod outMod; | ||
| 649 | output list<SCode.Comment> outComments; | ||
| 650 | algorithm | ||
| 651 | (outCache,outEnv1,outIH,outSCodeElementLst2,outSCodeEquationLst3,outSCodeEquationLst4,outSCodeAlgorithmLst5,outSCodeAlgorithmLst6,outMod,outComments):= | ||
| 652 | matchcontinue (inCache,inEnv,inIH,inMod,inPrefix,inClass,inBoolean,inInfo,overflow) | ||
| 653 | local | ||
| 654 | list<SCode.Element> elt; | ||
| 655 | FCore.Graph env,cenv; | ||
| 656 | DAE.Mod mod,daeDMOD; | ||
| 657 | list<SCode.Equation> eq,ieq; | ||
| 658 | list<SCode.AlgorithmSection> alg,ialg; | ||
| 659 | SCode.Element c; | ||
| 660 | Absyn.Path tp; | ||
| 661 | SCode.Mod dmod; | ||
| 662 | Boolean impl; | ||
| 663 | FCore.Cache cache; | ||
| 664 | InstanceHierarchy ih; | ||
| 665 | SCode.Comment cmt; | ||
| 666 | list<SCode.Enum> enumLst; | ||
| 667 | String n,name,str1,str2; | ||
| 668 | Option<SCode.ExternalDecl> extdecl; | ||
| 669 | DAE.Prefix pre; | ||
| 670 | SourceInfo info; | ||
| 671 | SCode.Prefixes prefixes; | ||
| 672 | |||
| 673 | // from basic types return nothing | ||
| 674 | case (cache,env,ih,_,_,SCode.CLASS(name = name),_,_,_) | ||
| 675 | algorithm | ||
| 676 |
2/2✓ Branch 1 taken 37907 times.
✓ Branch 2 taken 81 times.
|
37988 | true := InstUtil.isBuiltInClass(name); |
| 677 | 81 | then | |
| 678 | (cache,env,ih,{},{},{},{},{},inMod,{}); | ||
| 679 | |||
| 680 | case (cache,env,ih,_,_,SCode.CLASS(name = name, classDef = | ||
| 681 | SCode.PARTS(elementLst = elt, | ||
| 682 | normalEquationLst = eq,initialEquationLst = ieq, | ||
| 683 | normalAlgorithmLst = alg,initialAlgorithmLst = ialg, | ||
| 684 | externalDecl = extdecl)),_,info,_) | ||
| 685 | algorithm | ||
| 686 | /* elt_1 = noImportElements(elt); */ | ||
| 687 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 37438 times.
|
37438 | Error.assertionOrAddSourceMessage(isNone(extdecl), Error.EXTENDS_EXTERNAL, {name}, info); |
| 688 | 37438 | then | |
| 689 | (cache,env,ih,elt,eq,ieq,alg,ialg,inMod,{inClass.cmt}); | ||
| 690 | |||
| 691 | case (cache,env,ih,mod,pre,SCode.CLASS( info = info, classDef = SCode.DERIVED(typeSpec = Absyn.TPATH(tp, _),modifications = dmod)),impl, _, false) | ||
| 692 | algorithm | ||
| 693 | // fprintln(Flags.INST_TRACE, "DERIVED: " + FGraph.printGraphPathStr(env) + " el: " + SCodeDump.unparseElementStr(inClass) + " mods: " + Mod.printModStr(mod)); | ||
| 694 | 469 | (cache, c, cenv) := Lookup.lookupClass(cache, env, tp, SOME(info)); | |
| 695 | 469 | dmod := InstUtil.chainRedeclares(mod, dmod); | |
| 696 | // false = AbsynUtil.pathEqual(FGraph.getGraphName(env),FGraph.getGraphName(cenv)) and SCodeUtil.elementEqual(c,inClass); | ||
| 697 | // modifiers should be evaluated in the current scope for derived! | ||
| 698 | //daeDMOD = Mod.elabUntypedMod(dmod, Mod.DERIVED(tp)); | ||
| 699 | 469 | (cache,daeDMOD) := Mod.elabMod(cache, env, ih, pre, dmod, impl, Mod.DERIVED(tp), info); | |
| 700 | 469 | mod := Mod.merge(mod, daeDMOD); | |
| 701 | // print("DER: " + SCodeDump.unparseElementStr(inClass, SCodeDump.defaultOptions) + "\n"); | ||
| 702 | 469 | (cache,env,ih,elt,eq,ieq,alg,ialg,mod,outComments) := instDerivedClassesWork(cache, cenv, ih, mod, pre, c, impl, info, numIter >= Global.recursionDepthLimit, numIter+1) | |
| 703 | "Mod.lookup_modification_p(mod, c) => innermod & We have to merge and apply modifications as well!" ; | ||
| 704 | 469 | then | |
| 705 | (cache,env,ih,elt,eq,ieq,alg,ialg,mod,inClass.cmt::outComments); | ||
| 706 | |||
| 707 | case (cache,env,ih,mod,pre,SCode.CLASS(name=n, prefixes = prefixes, classDef = SCode.ENUMERATION(enumLst), cmt = cmt, info = info),impl,_,false) | ||
| 708 | algorithm | ||
| 709 | ✗ | c := SCodeInstUtil.expandEnumeration(n, enumLst, prefixes, cmt, info); | |
| 710 | ✗ | (cache,env,ih,elt,eq,ieq,alg,ialg,mod,outComments) := instDerivedClassesWork(cache, env, ih, mod, pre, c, impl,info, numIter >= Global.recursionDepthLimit, numIter+1); | |
| 711 | then | ||
| 712 | (cache,env,ih,elt,eq,ieq,alg,ialg,mod,outComments); | ||
| 713 | |||
| 714 | case (_,_,_,_,_,_,_,_,true) | ||
| 715 | algorithm | ||
| 716 | ✗ | str1 := SCodeDump.unparseElementStr(inClass,SCodeDump.defaultOptions); | |
| 717 | ✗ | str2 := FGraph.printGraphPathStr(inEnv); | |
| 718 | // print("instDerivedClassesWork recursion depth... " + str1 + " " + str2 + "\n"); | ||
| 719 | ✗ | Error.addSourceMessage(Error.RECURSION_DEPTH_DERIVED,{str1,str2},inInfo); | |
| 720 | ✗ | then fail(); | |
| 721 | |||
| 722 | else | ||
| 723 | algorithm | ||
| 724 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 725 | ✗ | Debug.trace("- Inst.instDerivedClasses failed\n"); | |
| 726 | ✗ | then | |
| 727 | fail(); | ||
| 728 | end matchcontinue; | ||
| 729 | end instDerivedClassesWork; | ||
| 730 | |||
| 731 | protected function noImportElements | ||
| 732 | "Returns all elements except imports, i.e. filter out import elements." | ||
| 733 | input list<SCode.Element> inElements; | ||
| 734 | output list<SCode.Element> outElements; | ||
| 735 | algorithm | ||
| 736 | ✗ | outElements := list(e for e guard(not SCodeUtil.elementIsImport(e)) in inElements); | |
| 737 | end noImportElements; | ||
| 738 | |||
| 739 | protected function updateComponentsAndClassdefs | ||
| 740 | "This function takes a list of components and a Mod and returns a list of | ||
| 741 | components with the modifiers updated. The function is used when flattening | ||
| 742 | the inheritance structure, resulting in a list of components to insert into | ||
| 743 | the class definition. For instance | ||
| 744 | model A | ||
| 745 | extends B(modifiers) | ||
| 746 | end A; | ||
| 747 | will result in a list of components | ||
| 748 | from B for which modifiers should be applied to." | ||
| 749 | input list<tuple<SCode.Element, DAE.Mod, Boolean>> inComponents; | ||
| 750 | input DAE.Mod inMod; | ||
| 751 | input FCore.Graph inEnv; | ||
| 752 | output list<tuple<SCode.Element, DAE.Mod, Boolean>> outComponents; | ||
| 753 | output DAE.Mod outRestMod; | ||
| 754 | algorithm | ||
| 755 | 264942 | (outComponents, outRestMod) := List.map1Fold(inComponents, | |
| 756 | updateComponentsAndClassdefs2, inEnv, inMod); | ||
| 757 | end updateComponentsAndClassdefs; | ||
| 758 | |||
| 759 | protected function updateComponentsAndClassdefs2 | ||
| 760 | input tuple<SCode.Element, DAE.Mod, Boolean> inComponent; | ||
| 761 | input FCore.Graph inEnv; | ||
| 762 | input DAE.Mod inMod; | ||
| 763 | output tuple<SCode.Element, DAE.Mod, Boolean> outComponent; | ||
| 764 | output DAE.Mod outRestMod; | ||
| 765 | protected | ||
| 766 | SCode.Element el; | ||
| 767 | DAE.Mod mod; | ||
| 768 | Boolean b; | ||
| 769 | algorithm | ||
| 770 | 316681 | (el, mod, b) := inComponent; | |
| 771 | |||
| 772 | (outComponent, outRestMod) := matchcontinue el | ||
| 773 | local | ||
| 774 | SCode.Element comp; | ||
| 775 | DAE.Mod cmod, mod_rest; | ||
| 776 | |||
| 777 | case SCode.COMPONENT() | ||
| 778 | algorithm | ||
| 779 | // Debug.traceln(" comp: " + id + " " + Mod.printModStr(mod)); | ||
| 780 | // take ONLY the modification from the equation if is typed | ||
| 781 | // cmod2 = Mod.getModifs(inMod, id, m); | ||
| 782 | 165472 | cmod := Mod.lookupCompModificationFromEqu(inMod, el.name); | |
| 783 | // Debug.traceln("\tSpecific mods on comp: " + Mod.printModStr(cmod2)); | ||
| 784 | 165472 | cmod := Mod.merge(cmod, mod, el.name, false); | |
| 785 | mod_rest := inMod; //mod_rest = Mod.removeMod(inMod, id); | ||
| 786 |
2/2✓ Branch 0 taken 66264 times.
✓ Branch 1 taken 99208 times.
|
231736 | then |
| 787 | ((el, cmod, b), mod_rest); | ||
| 788 | |||
| 789 | case SCode.EXTENDS() | ||
| 790 | then (inComponent, inMod); | ||
| 791 | |||
| 792 | case SCode.IMPORT() | ||
| 793 | ✗ | then ((el, DAE.NOMOD(), b), inMod); | |
| 794 | |||
| 795 | case SCode.CLASS(prefixes = SCode.PREFIXES(replaceablePrefix = SCode.REPLACEABLE(_))) | ||
| 796 | algorithm | ||
| 797 |
2/2✓ Branch 1 taken 63522 times.
✓ Branch 2 taken 7065 times.
|
70587 | DAE.REDECL(element = comp, mod = cmod) := Mod.lookupCompModification(inMod, el.name); |
| 798 | mod_rest := inMod; //mod_rest = Mod.removeMod(inMod, id); | ||
| 799 | 7065 | cmod := Mod.merge(cmod, mod, el.name, false); | |
| 800 | 7065 | comp := SCodeUtil.mergeWithOriginal(comp, el); | |
| 801 | // comp2 = SCodeUtil.renameElement(comp2, id); | ||
| 802 |
2/2✓ Branch 0 taken 4813 times.
✓ Branch 1 taken 2252 times.
|
11878 | then |
| 803 | ((comp, cmod, b), mod_rest); | ||
| 804 | |||
| 805 | // adrpo: | ||
| 806 | // 2011-01-19 we can have a modifier in the mods here, | ||
| 807 | // example in Modelica.Media: | ||
| 808 | // partial package SingleGasNasa | ||
| 809 | // extends Interfaces.PartialPureSubstance( | ||
| 810 | // ThermoStates = Choices.IndependentVariables.pT, | ||
| 811 | // mediumName=data.name, | ||
| 812 | // substanceNames={data.name}, | ||
| 813 | // singleState=false, | ||
| 814 | // Temperature(min=200, max=6000, start=500, nominal=500), | ||
| 815 | // SpecificEnthalpy(start=if referenceChoice==ReferenceEnthalpy.ZeroAt0K then data.H0 else | ||
| 816 | // if referenceChoice==ReferenceEnthalpy.UserDefined then h_offset else 0, nominal=1.0e5), | ||
| 817 | // Density(start=10, nominal=10), | ||
| 818 | // AbsolutePressure(start=10e5, nominal=10e5)); <--- AbsolutePressure is a type and can have modifications! | ||
| 819 | case SCode.CLASS() | ||
| 820 | algorithm | ||
| 821 | 144144 | cmod := Mod.lookupCompModification(inMod, el.name); | |
| 822 |
4/4✓ Branch 1 taken 9245 times.
✓ Branch 2 taken 134899 times.
✓ Branch 3 taken 2290 times.
✓ Branch 4 taken 6955 times.
|
146434 | outComponent := if valueEq(cmod, DAE.NOMOD()) then inComponent else (el,cmod,b); |
| 823 | then | ||
| 824 | (outComponent, inMod); | ||
| 825 | |||
| 826 | else | ||
| 827 | algorithm | ||
| 828 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 829 | ✗ | Debug.traceln( | |
| 830 | "- InstExtends.updateComponentsAndClassdefs2 failed on:\n" + | ||
| 831 | "env = " + FGraph.printGraphPathStr(inEnv) + | ||
| 832 | "\nmod = " + Mod.printModStr(inMod) + | ||
| 833 | "\ncmod = " + Mod.printModStr(mod) + | ||
| 834 | "\nbool = " + boolString(b) + "\n" + | ||
| 835 | SCodeDump.unparseElementStr(el) | ||
| 836 | ); | ||
| 837 | ✗ | then | |
| 838 | fail(); | ||
| 839 | end matchcontinue; | ||
| 840 | end updateComponentsAndClassdefs2; | ||
| 841 | |||
| 842 | protected function getLocalIdentList | ||
| 843 | " Analyzes the elements of a class and fetches a list of components and classdefs, | ||
| 844 | as well as aliases from imports to paths. | ||
| 845 | " | ||
| 846 | input list<Type_A> ielts; | ||
| 847 | input output AvlSetString.Tree tree; | ||
| 848 | input getIdentFn getIdent; | ||
| 849 | |||
| 850 | replaceable type Type_A subtypeof Any; | ||
| 851 | partial function getIdentFn | ||
| 852 | input Type_A inA; | ||
| 853 | input output AvlSetString.Tree tree; | ||
| 854 | end getIdentFn; | ||
| 855 | algorithm | ||
| 856 |
2/2✓ Branch 0 taken 675100 times.
✓ Branch 1 taken 280292 times.
|
955392 | for elt in ielts loop |
| 857 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 675100 times.
|
675100 | tree := getIdent(elt, tree); |
| 858 | end for; | ||
| 859 | end getLocalIdentList; | ||
| 860 | |||
| 861 | protected function getLocalIdentElementTpl | ||
| 862 | " Analyzes the elements of a class and fetches a list of components and classdefs, | ||
| 863 | as well as aliases from imports to paths. | ||
| 864 | " | ||
| 865 | input tuple<SCode.Element,DAE.Mod,Boolean> eltTpl; | ||
| 866 | input output AvlSetString.Tree tree; | ||
| 867 | protected | ||
| 868 | SCode.Element elt; | ||
| 869 | algorithm | ||
| 870 | 224539 | (elt, _, _) := eltTpl; | |
| 871 | 224539 | tree := getLocalIdentElement(elt, tree); | |
| 872 | end getLocalIdentElementTpl; | ||
| 873 | |||
| 874 | protected function getLocalIdentElement | ||
| 875 | " Analyzes an element of a class and fetches a list of components and classdefs, | ||
| 876 | as well as aliases from imports to paths." | ||
| 877 | input SCode.Element elt; | ||
| 878 | input output AvlSetString.Tree tree; | ||
| 879 | algorithm | ||
| 880 | tree := match elt | ||
| 881 | local | ||
| 882 | String id; | ||
| 883 | |||
| 884 | case SCode.COMPONENT(name = id) | ||
| 885 | 424032 | then AvlSetString.add(tree, id); | |
| 886 | |||
| 887 | case SCode.CLASS(name = id) | ||
| 888 | 158485 | then AvlSetString.add(tree, id); | |
| 889 | |||
| 890 | else tree; | ||
| 891 | end match; | ||
| 892 | end getLocalIdentElement; | ||
| 893 | |||
| 894 | protected function fixLocalIdent | ||
| 895 | " All of the fix functions do the following: | ||
| 896 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 897 | local lookup or fully qualified in the environment." | ||
| 898 | input array<FCore.Cache> inCache; | ||
| 899 | input FCore.Graph inEnv; | ||
| 900 | input output tuple<SCode.Element,DAE.Mod,Boolean> elt; | ||
| 901 | input AvlSetString.Tree tree; | ||
| 902 | protected | ||
| 903 | SCode.Element elt1,elt2; | ||
| 904 | DAE.Mod mod; | ||
| 905 | Boolean b; | ||
| 906 | algorithm | ||
| 907 | 224539 | (elt1, mod, b) := elt; | |
| 908 | 224539 | elt2 := fixElement(inCache, inEnv, elt1, tree); | |
| 909 |
2/2✓ Branch 0 taken 124963 times.
✓ Branch 1 taken 99576 times.
|
224539 | if (not referenceEq(elt1, elt2)) or not b then |
| 910 | 99576 | elt := (elt2, mod, true); | |
| 911 | end if; | ||
| 912 | end fixLocalIdent; | ||
| 913 | |||
| 914 | protected function fixElement | ||
| 915 | " All of the fix functions do the following: | ||
| 916 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 917 | local lookup or fully qualified in the environment. | ||
| 918 | " | ||
| 919 | input array<FCore.Cache> inCache; | ||
| 920 | input FCore.Graph inEnv; | ||
| 921 | input SCode.Element inElt; | ||
| 922 | input AvlSetString.Tree tree; | ||
| 923 | output SCode.Element outElts; | ||
| 924 | algorithm | ||
| 925 | outElts := matchcontinue (inEnv,inElt) | ||
| 926 | local | ||
| 927 | String name; | ||
| 928 | SCode.Prefixes prefixes; | ||
| 929 | SCode.Partial partialPrefix; | ||
| 930 | Absyn.TypeSpec typeSpec1, typeSpec2; | ||
| 931 | SCode.Mod modifications1, modifications2; | ||
| 932 | SCode.Comment comment; | ||
| 933 | Option<Absyn.Exp> condition; | ||
| 934 | SourceInfo info; | ||
| 935 | SCode.ClassDef classDef1,classDef2; | ||
| 936 | SCode.Restriction restriction; | ||
| 937 | Option<SCode.Annotation> optAnnotation; | ||
| 938 | Absyn.Path extendsPath1, extendsPath2; | ||
| 939 | SCode.Visibility vis; | ||
| 940 | Absyn.ArrayDim ad; | ||
| 941 | FCore.Graph env; | ||
| 942 | SCode.Element elt, elt2; | ||
| 943 | SCode.Attributes attr; | ||
| 944 | |||
| 945 | case (env,elt as SCode.COMPONENT(prefixes=SCode.PREFIXES(replaceablePrefix = SCode.REPLACEABLE(_)))) | ||
| 946 | algorithm | ||
| 947 | //fprintln(Flags.DEBUG,"fix comp " + SCodeDump.unparseElementStr(elt,SCodeDump.defaultOptions)); | ||
| 948 | // lookup as it might have been redeclared!!! | ||
| 949 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 46 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
92 | (_,_,elt2 as SCode.COMPONENT(name, prefixes, attr as SCode.ATTR(), typeSpec1, modifications1, comment, condition, info),_,_,env) |
| 950 | := Lookup.lookupIdentLocal(arrayGet(inCache, 1), env, elt.name); | ||
| 951 | ✗ | modifications2 := fixModifications(inCache,env,modifications1,tree); | |
| 952 | ✗ | typeSpec2 := fixTypeSpec(inCache,env,typeSpec1,tree); | |
| 953 | ✗ | ad := fixArrayDim(inCache, env, attr.arrayDims, tree); | |
| 954 | ✗ | if not referenceEq(ad, attr.arrayDims) then | |
| 955 | ✗ | attr.arrayDims := ad; | |
| 956 | end if; | ||
| 957 | ✗ | if not (referenceEq(ad, attr.arrayDims) and referenceEq(typeSpec1, typeSpec2) and referenceEq(modifications1, modifications2)) then | |
| 958 | ✗ | elt2 := SCode.COMPONENT(name, prefixes, attr, typeSpec2, modifications2, comment, condition, info); | |
| 959 | end if; | ||
| 960 | then elt2; | ||
| 961 | |||
| 962 | case (env,elt as SCode.COMPONENT(attributes=attr)) | ||
| 963 | algorithm | ||
| 964 | 382909 | modifications2 := fixModifications(inCache,env,elt.modifications,tree); | |
| 965 | 382909 | typeSpec2 := fixTypeSpec(inCache,env,elt.typeSpec,tree); | |
| 966 | 382909 | ad := fixArrayDim(inCache, env, attr.arrayDims, tree); | |
| 967 |
2/2✓ Branch 0 taken 458 times.
✓ Branch 1 taken 382451 times.
|
382909 | if not referenceEq(ad, attr.arrayDims) then |
| 968 | 458 | attr.arrayDims := ad; | |
| 969 | end if; | ||
| 970 |
5/6✓ Branch 0 taken 382909 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 329232 times.
✓ Branch 3 taken 53677 times.
✓ Branch 4 taken 1209 times.
✓ Branch 5 taken 328023 times.
|
382909 | if not (referenceEq(ad, attr.arrayDims) and referenceEq(elt.typeSpec, typeSpec2) and referenceEq(elt.modifications, modifications2)) then |
| 971 | 54886 | elt := SCode.COMPONENT(elt.name, elt.prefixes, attr, typeSpec2, modifications2, elt.comment, elt.condition, elt.info); | |
| 972 | end if; | ||
| 973 | then elt; | ||
| 974 | |||
| 975 | case (env,SCode.CLASS(name, prefixes as SCode.PREFIXES(replaceablePrefix = SCode.REPLACEABLE(_)), | ||
| 976 | SCode.ENCAPSULATED(), partialPrefix, restriction, _, comment, info)) | ||
| 977 | algorithm | ||
| 978 | //fprintln(Flags.DEBUG,"fixClassdef " + name); | ||
| 979 | // lookup as it might have been redeclared!!! | ||
| 980 | ✗ | (SCode.CLASS(prefixes = prefixes, partialPrefix = partialPrefix, restriction = restriction, | |
| 981 | cmt = comment, info = info,classDef=classDef1),env) := Lookup.lookupClassLocal(env, name); | ||
| 982 | ✗ | env := FGraph.openScope(env, SCode.ENCAPSULATED(), name, FGraph.restrictionToScopeType(restriction)); | |
| 983 | ✗ | classDef2 := fixClassdef(inCache, env,classDef1,tree); | |
| 984 | ✗ | then | |
| 985 | (if referenceEq(classDef1,classDef2) then inElt else SCode.CLASS(name, prefixes, SCode.ENCAPSULATED(), partialPrefix, restriction, classDef2, comment, info)); | ||
| 986 | |||
| 987 | // failed above | ||
| 988 | case (env,SCode.CLASS(name, prefixes, SCode.ENCAPSULATED(), partialPrefix, restriction, classDef1, comment, info)) | ||
| 989 | algorithm | ||
| 990 | //fprintln(Flags.DEBUG,"fixClassdef " + name); | ||
| 991 | 2 | env := FGraph.openScope(env, SCode.ENCAPSULATED(), name, FGraph.restrictionToScopeType(restriction)); | |
| 992 | 2 | classDef2 := fixClassdef(inCache, env,classDef1,tree); | |
| 993 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
|
2 | then |
| 994 | (if referenceEq(classDef1,classDef2) then inElt else SCode.CLASS(name, prefixes, SCode.ENCAPSULATED(), partialPrefix, restriction, classDef2, comment, info)); | ||
| 995 | |||
| 996 | case (env,SCode.CLASS(name, prefixes as SCode.PREFIXES(replaceablePrefix = SCode.REPLACEABLE(_)), | ||
| 997 | SCode.NOT_ENCAPSULATED(), partialPrefix, restriction, _, comment, info)) | ||
| 998 | algorithm | ||
| 999 | //fprintln(Flags.DEBUG,"fixClassdef " + name + str); | ||
| 1000 | // lookup as it might have been redeclared!!! | ||
| 1001 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 13478 times.
|
55085 | (SCode.CLASS(prefixes = prefixes, partialPrefix = partialPrefix, restriction = restriction, |
| 1002 | cmt = comment, info = info,classDef=classDef1),env) := Lookup.lookupClassLocal(env, name); | ||
| 1003 | |||
| 1004 | 13478 | env := FGraph.openScope(env, SCode.NOT_ENCAPSULATED(), name, FGraph.restrictionToScopeType(restriction)); | |
| 1005 | 13478 | classDef2 := fixClassdef(inCache,env,classDef1,tree); | |
| 1006 |
2/2✓ Branch 0 taken 12279 times.
✓ Branch 1 taken 1199 times.
|
13478 | then |
| 1007 | (if referenceEq(classDef1,classDef2) then inElt else SCode.CLASS(name, prefixes, SCode.NOT_ENCAPSULATED(), partialPrefix, restriction, classDef2, comment, info)); | ||
| 1008 | |||
| 1009 | // failed above | ||
| 1010 | case (env,SCode.CLASS(name, prefixes, SCode.NOT_ENCAPSULATED(), partialPrefix, restriction, classDef1, comment, info)) | ||
| 1011 | algorithm | ||
| 1012 | //fprintln(Flags.DEBUG,"fixClassdef " + name + str); | ||
| 1013 | 119127 | env := FGraph.openScope(env, SCode.NOT_ENCAPSULATED(), name, FGraph.restrictionToScopeType(restriction)); | |
| 1014 | 119127 | classDef2 := fixClassdef(inCache,env,classDef1,tree); | |
| 1015 |
2/2✓ Branch 0 taken 12709 times.
✓ Branch 1 taken 106418 times.
|
119127 | then |
| 1016 | (if referenceEq(classDef1,classDef2) then inElt else SCode.CLASS(name, prefixes, SCode.NOT_ENCAPSULATED(), partialPrefix, restriction, classDef2, comment, info)); | ||
| 1017 | |||
| 1018 | case (env,SCode.EXTENDS(extendsPath1,vis,modifications1,optAnnotation,info)) | ||
| 1019 | algorithm | ||
| 1020 | //fprintln(Flags.DEBUG,"fix extends " + SCodeDump.unparseElementStr(elt,SCodeDump.defaultOptions)); | ||
| 1021 | 92581 | extendsPath2 := fixPath(inCache,env,extendsPath1,tree); | |
| 1022 | 92581 | modifications2 := fixModifications(inCache,env,modifications1,tree); | |
| 1023 |
2/2✓ Branch 0 taken 20278 times.
✓ Branch 1 taken 72303 times.
|
92581 | then |
| 1024 | (if referenceEq(extendsPath1,extendsPath2) and referenceEq(modifications1,modifications2) then inElt else SCode.EXTENDS(extendsPath2,vis,modifications2,optAnnotation,info)); | ||
| 1025 | |||
| 1026 | case (_,SCode.IMPORT()) then inElt; | ||
| 1027 | |||
| 1028 | case (_,elt) | ||
| 1029 | algorithm | ||
| 1030 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 1031 | ✗ | Debug.traceln("InstExtends.fixElement failed: " + SCodeDump.unparseElementStr(elt)); | |
| 1032 | ✗ | then fail(); | |
| 1033 | |||
| 1034 | end matchcontinue; | ||
| 1035 | end fixElement; | ||
| 1036 | |||
| 1037 | protected function fixClassdef | ||
| 1038 | " All of the fix functions do the following: | ||
| 1039 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1040 | local lookup or fully qualified in the environment." | ||
| 1041 | input array<FCore.Cache> cache; | ||
| 1042 | input FCore.Graph inEnv; | ||
| 1043 | input SCode.ClassDef inCd; | ||
| 1044 | input AvlSetString.Tree inTree; | ||
| 1045 | output SCode.ClassDef outCd; | ||
| 1046 | protected | ||
| 1047 | AvlSetString.Tree tree=inTree; | ||
| 1048 | algorithm | ||
| 1049 | outCd := matchcontinue (inEnv,inCd) | ||
| 1050 | local | ||
| 1051 | list<SCode.Element> elts,elts_1; | ||
| 1052 | list<SCode.Equation> ne,ne_1,ie,ie_1; | ||
| 1053 | list<SCode.AlgorithmSection> na,na_1,ia,ia_1; | ||
| 1054 | list<SCode.ConstraintSection> nc,nc_1; | ||
| 1055 | list<Absyn.NamedArg> clats; | ||
| 1056 | Option<SCode.ExternalDecl> ed; | ||
| 1057 | Absyn.TypeSpec ts,ts_1; | ||
| 1058 | SCode.Attributes attr; | ||
| 1059 | SCode.Mod mod,mod_1; | ||
| 1060 | FCore.Graph env; | ||
| 1061 | SCode.ClassDef cd,cd_1; | ||
| 1062 | |||
| 1063 | case (env,SCode.PARTS(elts,ne,ie,na,ia,nc,clats,ed)) | ||
| 1064 | algorithm | ||
| 1065 | 92803 | tree := getLocalIdentList(elts, tree, getLocalIdentElement); | |
| 1066 | 92803 | elts_1 := fixList(cache,env,elts,tree,fixElement); | |
| 1067 | 92803 | ne_1 := fixList(cache,env,ne,tree,fixEquation); | |
| 1068 | 92803 | ie_1 := fixList(cache,env,ie,tree,fixEquation); | |
| 1069 | 92803 | na_1 := fixList(cache,env,na,tree,fixAlgorithm); | |
| 1070 | 92803 | ia_1 := fixList(cache,env,ia,tree,fixAlgorithm); | |
| 1071 | 92803 | nc_1 := fixList(cache,env,nc,tree,fixConstraint); | |
| 1072 |
5/6✓ Branch 0 taken 69866 times.
✓ Branch 1 taken 22937 times.
✓ Branch 2 taken 66124 times.
✓ Branch 3 taken 3742 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 66124 times.
|
92803 | then if referenceEq(elts,elts_1) and referenceEq(ne,ne_1) and referenceEq(ie,ie_1) and referenceEq(na,na_1) and referenceEq(ia,ia_1) and referenceEq(nc,nc_1) |
| 1073 | then inCd else SCode.PARTS(elts_1,ne_1,ie_1,na_1,ia_1,nc_1,clats,ed); | ||
| 1074 | |||
| 1075 | case (env,SCode.CLASS_EXTENDS(mod,cd as SCode.PARTS(elts,ne,ie,na,ia,nc,clats,ed))) | ||
| 1076 | algorithm | ||
| 1077 | ✗ | mod_1 := fixModifications(cache,env,mod,inTree); | |
| 1078 | ✗ | elts_1 := fixList(cache,env,elts,tree,fixElement); | |
| 1079 | ✗ | ne_1 := fixList(cache,env,ne,tree,fixEquation); | |
| 1080 | ✗ | ie_1 := fixList(cache,env,ie,tree,fixEquation); | |
| 1081 | ✗ | na_1 := fixList(cache,env,na,tree,fixAlgorithm); | |
| 1082 | ✗ | ia_1 := fixList(cache,env,ia,tree,fixAlgorithm); | |
| 1083 | ✗ | nc_1 := fixList(cache,env,nc,tree,fixConstraint); | |
| 1084 | ✗ | cd_1 := if referenceEq(elts,elts_1) and referenceEq(ne,ne_1) and referenceEq(ie,ie_1) and referenceEq(na,na_1) and referenceEq(ia,ia_1) and referenceEq(nc,nc_1) | |
| 1085 | then cd else SCode.PARTS(elts_1,ne_1,ie_1,na_1,ia_1,nc_1,clats,ed); | ||
| 1086 | ✗ | then if referenceEq(cd,cd_1) and referenceEq(mod,mod_1) | |
| 1087 | then inCd else SCode.CLASS_EXTENDS(mod_1,cd_1); | ||
| 1088 | |||
| 1089 | case (env,SCode.DERIVED(ts,mod,attr)) | ||
| 1090 | algorithm | ||
| 1091 | 43747 | ts_1 := fixTypeSpec(cache,env,ts,tree); | |
| 1092 | 43747 | mod_1 := fixModifications(cache,env,mod,tree); | |
| 1093 |
2/2✓ Branch 0 taken 2079 times.
✓ Branch 1 taken 41668 times.
|
43747 | then if referenceEq(ts,ts_1) and referenceEq(mod,mod_1) then inCd else SCode.DERIVED(ts_1,mod_1,attr); |
| 1094 | |||
| 1095 | case (_,cd as SCode.ENUMERATION()) then cd; | ||
| 1096 | case (_,cd as SCode.OVERLOAD()) then cd; | ||
| 1097 | case (_,cd as SCode.PDER()) then cd; | ||
| 1098 | |||
| 1099 | case (_,cd) | ||
| 1100 | algorithm | ||
| 1101 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 1102 | ✗ | Debug.traceln("InstExtends.fixClassDef failed: " + SCodeDump.classDefStr(cd)); | |
| 1103 | ✗ | then | |
| 1104 | fail(); | ||
| 1105 | |||
| 1106 | end matchcontinue; | ||
| 1107 | end fixClassdef; | ||
| 1108 | |||
| 1109 | protected function fixEquation | ||
| 1110 | " All of the fix functions do the following: | ||
| 1111 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1112 | local lookup or fully qualified in the environment. | ||
| 1113 | " | ||
| 1114 | input array<FCore.Cache> cache; | ||
| 1115 | input FCore.Graph inEnv; | ||
| 1116 | input SCode.Equation inEeq; | ||
| 1117 | input AvlSetString.Tree tree; | ||
| 1118 | output SCode.Equation outEeq; | ||
| 1119 | algorithm | ||
| 1120 | outEeq := match inEeq | ||
| 1121 | local | ||
| 1122 | String id; | ||
| 1123 | Absyn.ComponentRef cref,cref1,cref2; | ||
| 1124 | Absyn.Exp exp,exp1,exp2,exp3; | ||
| 1125 | list<Absyn.Exp> expl; | ||
| 1126 | list<SCode.Equation> eql; | ||
| 1127 | list<list<SCode.Equation>> eqll; | ||
| 1128 | list<tuple<Absyn.Exp, list<SCode.Equation>>> whenlst; | ||
| 1129 | SCode.Comment comment; | ||
| 1130 | Option<Absyn.Exp> optExp; | ||
| 1131 | SourceInfo info; | ||
| 1132 | |||
| 1133 | case SCode.EQ_IF(expl,eqll,eql,comment,info) | ||
| 1134 | algorithm | ||
| 1135 | 5899 | expl := fixList(cache,inEnv,expl,tree,fixExp); | |
| 1136 | 5899 | eqll := fixListList(cache,inEnv,eqll,tree,fixEquation); | |
| 1137 | 5899 | eql := fixList(cache,inEnv,eql,tree,fixEquation); | |
| 1138 | 5899 | then (SCode.EQ_IF(expl,eqll,eql,comment,info)); | |
| 1139 | case SCode.EQ_EQUALS(exp1,exp2,comment,info) | ||
| 1140 | algorithm | ||
| 1141 | 15805 | exp1 := fixExp(cache,inEnv,exp1,tree); | |
| 1142 | 15805 | exp2 := fixExp(cache,inEnv,exp2,tree); | |
| 1143 | 15805 | then (SCode.EQ_EQUALS(exp1,exp2,comment,info)); | |
| 1144 | case SCode.EQ_PDE(exp1,exp2,cref,comment,info) | ||
| 1145 | algorithm | ||
| 1146 | 2 | exp1 := fixExp(cache,inEnv,exp1,tree); | |
| 1147 | 2 | exp2 := fixExp(cache,inEnv,exp2,tree); | |
| 1148 | 2 | cref := fixCref(cache,inEnv,cref,tree); | |
| 1149 | 2 | then (SCode.EQ_PDE(exp1,exp2,cref,comment,info)); | |
| 1150 | case SCode.EQ_CONNECT(cref1,cref2,comment,info) | ||
| 1151 | algorithm | ||
| 1152 | 213 | cref1 := fixCref(cache,inEnv,cref1,tree); | |
| 1153 | 213 | cref2 := fixCref(cache,inEnv,cref2,tree); | |
| 1154 | 213 | then (SCode.EQ_CONNECT(cref1,cref2,comment,info)); | |
| 1155 | case SCode.EQ_FOR(id,optExp,eql,comment,info) | ||
| 1156 | algorithm | ||
| 1157 | 1414 | optExp := fixOption(cache,inEnv,optExp,tree,fixExp); | |
| 1158 | 1414 | eql := fixList(cache,inEnv,eql,tree,fixEquation); | |
| 1159 | 1414 | then (SCode.EQ_FOR(id,optExp,eql,comment,info)); | |
| 1160 | case SCode.EQ_WHEN(exp,eql,whenlst,comment,info) | ||
| 1161 | algorithm | ||
| 1162 | 6 | exp := fixExp(cache,inEnv,exp,tree); | |
| 1163 | 6 | eql := fixList(cache,inEnv,eql,tree,fixEquation); | |
| 1164 | 6 | whenlst := fixListTuple2(cache,inEnv,whenlst,tree,fixExp,fixListEquation); | |
| 1165 | 6 | then (SCode.EQ_WHEN(exp,eql,whenlst,comment,info)); | |
| 1166 | case SCode.EQ_ASSERT(exp1,exp2,exp3,comment,info) | ||
| 1167 | algorithm | ||
| 1168 | 3463 | exp1 := fixExp(cache,inEnv,exp1,tree); | |
| 1169 | 3463 | exp2 := fixExp(cache,inEnv,exp2,tree); | |
| 1170 | 3463 | exp3 := fixExp(cache,inEnv,exp3,tree); | |
| 1171 | 3463 | then (SCode.EQ_ASSERT(exp1,exp2,exp3,comment,info)); | |
| 1172 | case SCode.EQ_TERMINATE(exp,comment,info) | ||
| 1173 | algorithm | ||
| 1174 | ✗ | exp := fixExp(cache,inEnv,exp,tree); | |
| 1175 | ✗ | then (SCode.EQ_TERMINATE(exp,comment,info)); | |
| 1176 | case SCode.EQ_REINIT(exp1,exp,comment,info) | ||
| 1177 | algorithm | ||
| 1178 | ✗ | exp1 := fixExp(cache,inEnv,exp1,tree); | |
| 1179 | ✗ | exp := fixExp(cache,inEnv,exp,tree); | |
| 1180 | ✗ | then (SCode.EQ_REINIT(exp1,exp,comment,info)); | |
| 1181 | case SCode.EQ_NORETCALL(exp,comment,info) | ||
| 1182 | algorithm | ||
| 1183 | 10 | exp := fixExp(cache,inEnv,exp,tree); | |
| 1184 | 10 | then (SCode.EQ_NORETCALL(exp,comment,info)); | |
| 1185 | end match; | ||
| 1186 | end fixEquation; | ||
| 1187 | |||
| 1188 | protected function fixListEquation | ||
| 1189 | " All of the fix functions do the following: | ||
| 1190 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1191 | local lookup or fully qualified in the environment. | ||
| 1192 | " | ||
| 1193 | input array<FCore.Cache> cache; | ||
| 1194 | input FCore.Graph env; | ||
| 1195 | input list<SCode.Equation> eeq; | ||
| 1196 | input AvlSetString.Tree tree; | ||
| 1197 | output list<SCode.Equation> outEeq; | ||
| 1198 | algorithm | ||
| 1199 | ✗ | outEeq := fixList(cache,env,eeq,tree,fixEquation); | |
| 1200 | end fixListEquation; | ||
| 1201 | |||
| 1202 | protected function fixAlgorithm | ||
| 1203 | " All of the fix functions do the following: | ||
| 1204 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1205 | local lookup or fully qualified in the environment. | ||
| 1206 | " | ||
| 1207 | input array<FCore.Cache> inCache; | ||
| 1208 | input FCore.Graph inEnv; | ||
| 1209 | input SCode.AlgorithmSection inAlg; | ||
| 1210 | input AvlSetString.Tree tree; | ||
| 1211 | output SCode.AlgorithmSection outAlg; | ||
| 1212 | protected | ||
| 1213 | list<SCode.Statement> stmts1,stmts2; | ||
| 1214 | algorithm | ||
| 1215 | 41925 | SCode.ALGORITHM(stmts1) := inAlg; | |
| 1216 | 41925 | stmts2 := fixList(inCache, inEnv, stmts1, tree, fixStatement); | |
| 1217 |
2/2✓ Branch 0 taken 6628 times.
✓ Branch 1 taken 35297 times.
|
41925 | outAlg := if referenceEq(stmts1,stmts2) then inAlg else SCode.ALGORITHM(stmts2); |
| 1218 | end fixAlgorithm; | ||
| 1219 | |||
| 1220 | protected function fixConstraint | ||
| 1221 | " All of the fix functions do the following: | ||
| 1222 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1223 | local lookup or fully qualified in the environment. | ||
| 1224 | " | ||
| 1225 | input array<FCore.Cache> inCache; | ||
| 1226 | input FCore.Graph inEnv; | ||
| 1227 | input SCode.ConstraintSection inConstrs; | ||
| 1228 | input AvlSetString.Tree tree; | ||
| 1229 | output SCode.ConstraintSection outConstrs; | ||
| 1230 | protected | ||
| 1231 | list<Absyn.Exp> exps; | ||
| 1232 | algorithm | ||
| 1233 | ✗ | SCode.CONSTRAINTS(exps) := inConstrs; | |
| 1234 | ✗ | exps := fixList(inCache, inEnv, exps, tree, fixExp); | |
| 1235 | ✗ | outConstrs := SCode.CONSTRAINTS(exps); | |
| 1236 | end fixConstraint; | ||
| 1237 | |||
| 1238 | protected function fixListAlgorithmItem | ||
| 1239 | " All of the fix functions do the following: | ||
| 1240 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1241 | local lookup or fully qualified in the environment. | ||
| 1242 | " | ||
| 1243 | input array<FCore.Cache> cache; | ||
| 1244 | input FCore.Graph env; | ||
| 1245 | input list<SCode.Statement> alg; | ||
| 1246 | input AvlSetString.Tree tree; | ||
| 1247 | output list<SCode.Statement> outAlg; | ||
| 1248 | algorithm | ||
| 1249 | 264 | outAlg := fixList(cache,env,alg,tree,fixStatement); | |
| 1250 | end fixListAlgorithmItem; | ||
| 1251 | |||
| 1252 | protected function fixStatement | ||
| 1253 | " All of the fix functions do the following: | ||
| 1254 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1255 | local lookup or fully qualified in the environment. | ||
| 1256 | " | ||
| 1257 | input array<FCore.Cache> cache; | ||
| 1258 | input FCore.Graph inEnv; | ||
| 1259 | input SCode.Statement inStmt; | ||
| 1260 | input AvlSetString.Tree tree; | ||
| 1261 | output SCode.Statement outStmt; | ||
| 1262 | algorithm | ||
| 1263 | outStmt := matchcontinue inStmt | ||
| 1264 | local | ||
| 1265 | Absyn.Exp exp,exp_1,exp1,exp2,exp1_1,exp2_1; | ||
| 1266 | Option<Absyn.Exp> optExp1,optExp2; | ||
| 1267 | String iter; | ||
| 1268 | list<tuple<Absyn.Exp, list<SCode.Statement>>> elseifbranch1,elseifbranch2,whenlst; | ||
| 1269 | list<SCode.Statement> truebranch1,truebranch2,elsebranch1,elsebranch2,body1,body2; | ||
| 1270 | SCode.Comment comment; | ||
| 1271 | SourceInfo info; | ||
| 1272 | |||
| 1273 | case SCode.ALG_ASSIGN(exp1,exp2,comment,info) | ||
| 1274 | algorithm | ||
| 1275 | 49903 | exp1_1 := fixExp(cache,inEnv,exp1,tree); | |
| 1276 | 49903 | exp2_1 := fixExp(cache,inEnv,exp2,tree); | |
| 1277 |
2/2✓ Branch 0 taken 6804 times.
✓ Branch 1 taken 43099 times.
|
49903 | then if referenceEq(exp1,exp1_1) and referenceEq(exp2,exp2_1) then inStmt else SCode.ALG_ASSIGN(exp1_1,exp2_1,comment,info); |
| 1278 | |||
| 1279 | case SCode.ALG_IF(exp1,truebranch1,elseifbranch1,elsebranch1,comment,info) | ||
| 1280 | algorithm | ||
| 1281 | 553 | exp2 := fixExp(cache,inEnv,exp1,tree); | |
| 1282 | 553 | truebranch2 := fixList(cache,inEnv,truebranch1,tree,fixStatement); | |
| 1283 | 553 | elseifbranch2 := fixListTuple2(cache,inEnv,elseifbranch1,tree,fixExp,fixListAlgorithmItem); | |
| 1284 | 553 | elsebranch2 := fixList(cache,inEnv,elsebranch1,tree,fixStatement); | |
| 1285 |
4/4✓ Branch 0 taken 472 times.
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 391 times.
|
553 | then if referenceEq(exp1,exp2) and referenceEq(truebranch1,truebranch2) and referenceEq(elseifbranch1,elseifbranch2) and referenceEq(elsebranch1,elsebranch2) then inStmt else SCode.ALG_IF(exp2,truebranch2,elseifbranch2,elsebranch2,comment,info); |
| 1286 | |||
| 1287 | case SCode.ALG_FOR(iter,optExp1,body1,comment,info) | ||
| 1288 | algorithm | ||
| 1289 | 695 | optExp2 := fixOption(cache,inEnv,optExp1,tree,fixExp); | |
| 1290 | 695 | body2 := fixList(cache,inEnv,body1,tree,fixStatement); | |
| 1291 |
2/2✓ Branch 0 taken 76 times.
✓ Branch 1 taken 619 times.
|
695 | then if referenceEq(optExp1,optExp2) and referenceEq(body1,body2) then inStmt else SCode.ALG_FOR(iter,optExp2,body2,comment,info); |
| 1292 | |||
| 1293 | case SCode.ALG_PARFOR(iter,optExp1,body1,comment,info) | ||
| 1294 | algorithm | ||
| 1295 | ✗ | optExp2 := fixOption(cache,inEnv,optExp1,tree,fixExp); | |
| 1296 | ✗ | body2 := fixList(cache,inEnv,body1,tree,fixStatement); | |
| 1297 | ✗ | then if referenceEq(optExp1,optExp2) and referenceEq(body1,body2) then inStmt else SCode.ALG_PARFOR(iter,optExp2,body2,comment,info); | |
| 1298 | |||
| 1299 | case SCode.ALG_WHILE(exp1,body1,comment,info) | ||
| 1300 | algorithm | ||
| 1301 | 10 | exp2 := fixExp(cache,inEnv,exp1,tree); | |
| 1302 | 10 | body2 := fixList(cache,inEnv,body1,tree,fixStatement); | |
| 1303 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
|
10 | then if referenceEq(exp1,exp2) and referenceEq(body1,body2) then inStmt else SCode.ALG_WHILE(exp2,body2,comment,info); |
| 1304 | |||
| 1305 | case SCode.ALG_WHEN_A(whenlst,comment,info) | ||
| 1306 | algorithm | ||
| 1307 | ✗ | whenlst := fixListTuple2(cache,inEnv,whenlst,tree,fixExp,fixListAlgorithmItem); | |
| 1308 | ✗ | then SCode.ALG_WHEN_A(whenlst,comment,info); | |
| 1309 | |||
| 1310 | case SCode.ALG_ASSERT(exp, exp1, exp2, comment, info) | ||
| 1311 | algorithm | ||
| 1312 | 159 | exp_1 := fixExp(cache, inEnv, exp, tree); | |
| 1313 | 159 | exp1_1 := fixExp(cache, inEnv, exp1, tree); | |
| 1314 | 159 | exp2_1 := fixExp(cache, inEnv, exp2, tree); | |
| 1315 |
4/4✓ Branch 0 taken 158 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 52 times.
|
159 | then if referenceEq(exp,exp_1) and referenceEq(exp1,exp1_1) and referenceEq(exp2,exp2_1) then inStmt else SCode.ALG_ASSERT(exp_1, exp1_1, exp2_1, comment, info); |
| 1316 | |||
| 1317 | case SCode.ALG_TERMINATE(exp1, comment, info) | ||
| 1318 | algorithm | ||
| 1319 | ✗ | exp2 := fixExp(cache, inEnv, exp1, tree); | |
| 1320 | ✗ | then if referenceEq(exp1,exp2) then inStmt else SCode.ALG_TERMINATE(exp2, comment, info); | |
| 1321 | |||
| 1322 | case SCode.ALG_REINIT(exp1, exp2, comment, info) | ||
| 1323 | algorithm | ||
| 1324 | ✗ | exp1_1 := fixExp(cache, inEnv, exp1, tree); | |
| 1325 | ✗ | exp2_1 := fixExp(cache, inEnv, exp2, tree); | |
| 1326 | ✗ | then if referenceEq(exp1, exp1_1) and referenceEq(exp2, exp2_1) then inStmt else SCode.ALG_REINIT(exp1_1, exp2_1, comment, info); | |
| 1327 | |||
| 1328 | case SCode.ALG_NORETCALL(exp1,comment,info) | ||
| 1329 | algorithm | ||
| 1330 | 25 | exp2 := fixExp(cache,inEnv,exp1,tree); | |
| 1331 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
|
25 | then if referenceEq(exp1,exp2) then inStmt else SCode.ALG_NORETCALL(exp2,comment,info); |
| 1332 | |||
| 1333 | case SCode.ALG_RETURN() then inStmt; | ||
| 1334 | case SCode.ALG_BREAK() then inStmt; | ||
| 1335 | |||
| 1336 | case SCode.ALG_FAILURE(body1, comment, info) | ||
| 1337 | algorithm | ||
| 1338 | ✗ | body2 := fixList(cache, inEnv, body1, tree, fixStatement); | |
| 1339 | ✗ | then | |
| 1340 | if referenceEq(body1, body2) then inStmt else SCode.ALG_FAILURE(body2, comment, info); | ||
| 1341 | |||
| 1342 | case SCode.ALG_TRY(truebranch1, elsebranch1, comment, info) | ||
| 1343 | algorithm | ||
| 1344 | ✗ | truebranch2 := fixList(cache, inEnv, truebranch1, tree, fixStatement); | |
| 1345 | ✗ | elsebranch2 := fixList(cache, inEnv, elsebranch1, tree, fixStatement); | |
| 1346 | ✗ | then | |
| 1347 | if referenceEq(truebranch1, truebranch2) and referenceEq(elsebranch1, elsebranch2) then | ||
| 1348 | inStmt else SCode.ALG_TRY(truebranch2, elsebranch2, comment, info); | ||
| 1349 | |||
| 1350 | case SCode.ALG_CONTINUE() then inStmt; | ||
| 1351 | |||
| 1352 | else | ||
| 1353 | algorithm | ||
| 1354 | ✗ | Error.addInternalError(getInstanceName() + " failed: " + | |
| 1355 | Dump.unparseAlgorithmStr(SCodeUtil.statementToAlgorithmItem(inStmt)), sourceInfo()); | ||
| 1356 | ✗ | then fail(); | |
| 1357 | end matchcontinue; | ||
| 1358 | end fixStatement; | ||
| 1359 | |||
| 1360 | protected function fixArrayDim | ||
| 1361 | " All of the fix functions do the following: | ||
| 1362 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1363 | local lookup or fully qualified in the environment. | ||
| 1364 | " | ||
| 1365 | input array<FCore.Cache> inCache; | ||
| 1366 | input FCore.Graph inEnv; | ||
| 1367 | input output Absyn.ArrayDim ads; | ||
| 1368 | input AvlSetString.Tree tree; | ||
| 1369 | algorithm | ||
| 1370 | 382909 | ads := fixList(inCache, inEnv, ads, tree, fixSubscript); | |
| 1371 | end fixArrayDim; | ||
| 1372 | |||
| 1373 | protected function fixSubscript | ||
| 1374 | " All of the fix functions do the following: | ||
| 1375 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1376 | local lookup or fully qualified in the environment. | ||
| 1377 | " | ||
| 1378 | input array<FCore.Cache> cache; | ||
| 1379 | input FCore.Graph inEnv; | ||
| 1380 | input Absyn.Subscript inSub; | ||
| 1381 | input AvlSetString.Tree tree; | ||
| 1382 | output Absyn.Subscript outSub; | ||
| 1383 | algorithm | ||
| 1384 | outSub := match inSub | ||
| 1385 | local | ||
| 1386 | Absyn.Exp exp1, exp2; | ||
| 1387 | |||
| 1388 | case Absyn.NOSUB() then inSub; | ||
| 1389 | case Absyn.SUBSCRIPT(exp1) | ||
| 1390 | algorithm | ||
| 1391 | 28111 | exp2 := fixExp(cache, inEnv, exp1, tree); | |
| 1392 |
2/2✓ Branch 0 taken 460 times.
✓ Branch 1 taken 27651 times.
|
28111 | then if referenceEq(exp1,exp2) then inSub else Absyn.SUBSCRIPT(exp2); |
| 1393 | end match; | ||
| 1394 | end fixSubscript; | ||
| 1395 | |||
| 1396 | protected function fixTypeSpec | ||
| 1397 | " All of the fix functions do the following: | ||
| 1398 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1399 | local lookup or fully qualified in the environment. | ||
| 1400 | " | ||
| 1401 | input array<FCore.Cache> cache; | ||
| 1402 | input FCore.Graph inEnv; | ||
| 1403 | input Absyn.TypeSpec inTs; | ||
| 1404 | input AvlSetString.Tree tree; | ||
| 1405 | output Absyn.TypeSpec outTs; | ||
| 1406 | algorithm | ||
| 1407 | outTs := match inTs | ||
| 1408 | local | ||
| 1409 | Absyn.Path path1, path2; | ||
| 1410 | Option<Absyn.ArrayDim> arrayDim1,arrayDim2; | ||
| 1411 | list<Absyn.TypeSpec> typeSpecs1, typeSpecs2; | ||
| 1412 | |||
| 1413 | case Absyn.TPATH(path1,arrayDim1) | ||
| 1414 | algorithm | ||
| 1415 | 426674 | arrayDim2 := fixOption(cache,inEnv,arrayDim1,tree,fixArrayDim); | |
| 1416 | 426674 | path2 := fixPath(cache,inEnv,path1,tree); | |
| 1417 |
2/2✓ Branch 0 taken 55691 times.
✓ Branch 1 taken 370983 times.
|
426674 | then if referenceEq(arrayDim2,arrayDim1) and referenceEq(path1,path2) then inTs else Absyn.TPATH(path2,arrayDim2); |
| 1418 | case Absyn.TCOMPLEX(path1,typeSpecs1,arrayDim1) | ||
| 1419 | algorithm | ||
| 1420 | 112 | arrayDim2 := fixOption(cache,inEnv,arrayDim1,tree,fixArrayDim); | |
| 1421 | 112 | path2 := fixPath(cache,inEnv,path1,tree); | |
| 1422 | 112 | typeSpecs2 := fixList(cache,inEnv,typeSpecs1,tree,fixTypeSpec); | |
| 1423 |
3/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
|
112 | then if referenceEq(arrayDim2,arrayDim1) and referenceEq(path1,path2) and referenceEq(typeSpecs1,typeSpecs2) then inTs else Absyn.TCOMPLEX(path2,typeSpecs2,arrayDim2); |
| 1424 | end match; | ||
| 1425 | end fixTypeSpec; | ||
| 1426 | |||
| 1427 | protected function fixPath | ||
| 1428 | " All of the fix functions do the following: | ||
| 1429 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1430 | local lookup or fully qualified in the environment." | ||
| 1431 | input array<FCore.Cache> inCache; | ||
| 1432 | input FCore.Graph inEnv; | ||
| 1433 | input Absyn.Path inPath; | ||
| 1434 | input AvlSetString.Tree tree; | ||
| 1435 | output Absyn.Path outPath; | ||
| 1436 | algorithm | ||
| 1437 | outPath := matchcontinue inPath | ||
| 1438 | local | ||
| 1439 | String id; | ||
| 1440 | Absyn.Path path2,path; | ||
| 1441 | FCore.Cache cache; | ||
| 1442 | |||
| 1443 | case Absyn.FULLYQUALIFIED() | ||
| 1444 | then inPath; | ||
| 1445 | |||
| 1446 | case _ | ||
| 1447 | algorithm | ||
| 1448 | 335341 | id := AbsynUtil.pathFirstIdent(inPath); | |
| 1449 |
2/2✓ Branch 1 taken 91056 times.
✓ Branch 2 taken 244285 times.
|
335341 | true := AvlSetString.hasKey(tree, id); |
| 1450 | 244285 | path2 := FGraph.pathStripGraphScopePrefix(inPath, inEnv, false); | |
| 1451 | then path2; | ||
| 1452 | |||
| 1453 | // first indent is local in the inEnv, DO NOT QUALIFY! | ||
| 1454 | case _ | ||
| 1455 | algorithm | ||
| 1456 | //fprintln(Flags.DEBUG,"Try makeFullyQualified " + AbsynUtil.pathString(path)); | ||
| 1457 | 91056 | Lookup.lookupClassLocal(inEnv, AbsynUtil.pathFirstIdent(inPath)); | |
| 1458 | 44 | path := FGraph.pathStripGraphScopePrefix(inPath, inEnv, false); | |
| 1459 | //fprintln(Flags.DEBUG,"FullyQual: " + AbsynUtil.pathString(path)); | ||
| 1460 | then path; | ||
| 1461 | |||
| 1462 | case _ | ||
| 1463 | algorithm | ||
| 1464 | // isOutside = isPathOutsideScope(cache, inEnv, path); | ||
| 1465 | //print("Try makeFullyQualified " + AbsynUtil.pathString(path) + "\n"); | ||
| 1466 | 91012 | (cache, path) := Inst.makeFullyQualified(arrayGet(inCache,1), inEnv, inPath); | |
| 1467 | // path = if_(isOutside, path, FGraph.pathStripGraphScopePrefix(path, inEnv, false)); | ||
| 1468 | 91012 | path := FGraph.pathStripGraphScopePrefix(path, inEnv, false); | |
| 1469 | //print("FullyQual: " + AbsynUtil.pathString(path) + "\n"); | ||
| 1470 | 91012 | arrayUpdate(inCache, 1, cache); | |
| 1471 | then path; | ||
| 1472 | |||
| 1473 | else | ||
| 1474 | algorithm | ||
| 1475 | ✗ | path := FGraph.pathStripGraphScopePrefix(inPath, inEnv, false); | |
| 1476 | //fprintln(Flags.DEBUG, "Path not fixed: " + AbsynUtil.pathString(path) + "\n"); | ||
| 1477 | then path; | ||
| 1478 | |||
| 1479 | end matchcontinue; | ||
| 1480 | end fixPath; | ||
| 1481 | |||
| 1482 | protected function lookupVarNoErrorMessage | ||
| 1483 | input FCore.Cache inCache; | ||
| 1484 | input FCore.Graph inEnv; | ||
| 1485 | input String ident; | ||
| 1486 | output FCore.Graph outEnv; | ||
| 1487 | output String id; | ||
| 1488 | algorithm | ||
| 1489 | try | ||
| 1490 | 186595 | ErrorExt.setCheckpoint("InstExtends.lookupVarNoErrorMessage"); | |
| 1491 | 186595 | (_,_,_,_,_,_,outEnv,_,id) := Lookup.lookupVarIdent(inCache, inEnv, ident); | |
| 1492 | 1781 | ErrorExt.rollBack("InstExtends.lookupVarNoErrorMessage"); | |
| 1493 | else | ||
| 1494 | 184814 | ErrorExt.rollBack("InstExtends.lookupVarNoErrorMessage"); | |
| 1495 | 184814 | fail(); | |
| 1496 | end try; | ||
| 1497 | end lookupVarNoErrorMessage; | ||
| 1498 | |||
| 1499 | protected function fixCref | ||
| 1500 | " All of the fix functions do the following: | ||
| 1501 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1502 | local lookup or fully qualified in the environment." | ||
| 1503 | input array<FCore.Cache> cache; | ||
| 1504 | input FCore.Graph inEnv; | ||
| 1505 | input Absyn.ComponentRef inCref; | ||
| 1506 | input AvlSetString.Tree tree; | ||
| 1507 | output Absyn.ComponentRef outCref; | ||
| 1508 | algorithm | ||
| 1509 | outCref := matchcontinue (inEnv,inCref) | ||
| 1510 | local | ||
| 1511 | String id; | ||
| 1512 | FCore.Graph env, denv; | ||
| 1513 | Absyn.ComponentRef cref; | ||
| 1514 | SCode.Element c; | ||
| 1515 | |||
| 1516 | case (env, Absyn.CREF_FULLYQUALIFIED()) | ||
| 1517 | algorithm | ||
| 1518 | 5591 | env := FGraph.topScope(inEnv); | |
| 1519 | 5591 | then | |
| 1520 | fixCref(cache, env, inCref.componentRef, tree); | ||
| 1521 | |||
| 1522 | case (env,cref) | ||
| 1523 | algorithm | ||
| 1524 | 563336 | id := AbsynUtil.crefFirstIdent(cref); | |
| 1525 |
2/2✓ Branch 1 taken 186595 times.
✓ Branch 2 taken 376700 times.
|
563295 | true := AvlSetString.hasKey(tree, id); |
| 1526 | 376700 | cref := FGraph.crefStripGraphScopePrefix(cref, env, false); | |
| 1527 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 376700 times.
|
376700 | cref := if AbsynUtil.crefEqual(cref, inCref) then inCref else cref; |
| 1528 | then cref; | ||
| 1529 | |||
| 1530 | // try lookup var (constant in a package?) | ||
| 1531 | case (env,cref) | ||
| 1532 | algorithm | ||
| 1533 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 186595 times.
|
186636 | id := AbsynUtil.crefFirstIdent(cref); |
| 1534 | //fprintln(Flags.DEBUG,"Try lookupV " + id); | ||
| 1535 | 186595 | (denv,id) := lookupVarNoErrorMessage(arrayGet(cache,1),env,id); | |
| 1536 | //fprintln(Flags.DEBUG,"Got env " + intString(listLength(env))); | ||
| 1537 | // isOutside = FGraph.graphPrefixOf(denv, env); | ||
| 1538 | 1781 | denv := FGraph.openScope(denv,SCode.ENCAPSULATED(),id,NONE()); | |
| 1539 | 1781 | cref := AbsynUtil.crefReplaceFirstIdent(cref,FGraph.getGraphName(denv)); | |
| 1540 | // cref = if_(isOutside, cref, FGraph.crefStripGraphScopePrefix(cref, env, false)); | ||
| 1541 | 1781 | cref := FGraph.crefStripGraphScopePrefix(cref, env, false); | |
| 1542 | //fprintln(Flags.DEBUG, "Cref VAR fixed: " + Dump.printComponentRefStr(cref)); | ||
| 1543 |
2/2✓ Branch 1 taken 1766 times.
✓ Branch 2 taken 15 times.
|
1781 | cref := if AbsynUtil.crefEqual(cref, inCref) then inCref else cref; |
| 1544 | then cref; | ||
| 1545 | |||
| 1546 | case (env,cref) | ||
| 1547 | algorithm | ||
| 1548 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 184814 times.
|
184855 | id := AbsynUtil.crefFirstIdent(cref); |
| 1549 | //print("Try lookupC " + id + "\n"); | ||
| 1550 | 184814 | (_,c,denv) := Lookup.lookupClassIdent(arrayGet(cache,1),env,id); | |
| 1551 | // isOutside = FGraph.graphPrefixOf(denv, env); | ||
| 1552 | // id might come from named import, make sure you use the actual class name! | ||
| 1553 | 72913 | id := SCodeUtil.getElementName(c); | |
| 1554 | //fprintln(Flags.DEBUG,"Got env " + intString(listLength(env))); | ||
| 1555 | 72913 | denv := FGraph.openScope(denv,SCode.ENCAPSULATED(),id,NONE()); | |
| 1556 | 72913 | cref := AbsynUtil.crefReplaceFirstIdent(cref,FGraph.getGraphName(denv)); | |
| 1557 | // cref = if_(isOutside, cref, FGraph.crefStripGraphScopePrefix(cref, env, false)); | ||
| 1558 | 72913 | cref := FGraph.crefStripGraphScopePrefix(cref, env, false); | |
| 1559 | //print("Cref CLASS fixed: " + Dump.printComponentRefStr(cref) + "\n"); | ||
| 1560 |
2/2✓ Branch 1 taken 8948 times.
✓ Branch 2 taken 63965 times.
|
72913 | cref := if AbsynUtil.crefEqual(cref, inCref) then inCref else cref; |
| 1561 | then cref; | ||
| 1562 | |||
| 1563 | else inCref; | ||
| 1564 | |||
| 1565 | end matchcontinue; | ||
| 1566 | end fixCref; | ||
| 1567 | |||
| 1568 | protected function fixModifications | ||
| 1569 | " All of the fix functions do the following: | ||
| 1570 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1571 | local lookup or fully qualified in the environment. | ||
| 1572 | " | ||
| 1573 | input array<FCore.Cache> inCache; | ||
| 1574 | input FCore.Graph inEnv; | ||
| 1575 | input SCode.Mod inMod; | ||
| 1576 | input AvlSetString.Tree tree; | ||
| 1577 | output SCode.Mod outMod = inMod; | ||
| 1578 | algorithm | ||
| 1579 | outMod := matchcontinue outMod | ||
| 1580 | local | ||
| 1581 | list<SCode.SubMod> subModLst; | ||
| 1582 | Option<Absyn.Exp> exp; | ||
| 1583 | SCode.Element e; | ||
| 1584 | SCode.ClassDef cdef; | ||
| 1585 | |||
| 1586 | case SCode.NOMOD() then inMod; | ||
| 1587 | |||
| 1588 | case SCode.MOD() | ||
| 1589 | algorithm | ||
| 1590 | 295991 | subModLst := fixList(inCache, inEnv, outMod.subModLst, tree, fixSubMod); | |
| 1591 |
2/2✓ Branch 0 taken 1461 times.
✓ Branch 1 taken 294530 times.
|
295991 | if not referenceEq(outMod.subModLst, subModLst) then |
| 1592 | 1461 | outMod.subModLst := subModLst; | |
| 1593 | end if; | ||
| 1594 | |||
| 1595 | 295991 | exp := fixOption(inCache, inEnv, outMod.binding, tree, fixExp); | |
| 1596 |
2/2✓ Branch 0 taken 2934 times.
✓ Branch 1 taken 293057 times.
|
295991 | if not referenceEq(exp, outMod.binding) then |
| 1597 | 2934 | outMod.binding := exp; | |
| 1598 | end if; | ||
| 1599 | then outMod; | ||
| 1600 | |||
| 1601 | case SCode.REDECL(element = SCode.COMPONENT()) | ||
| 1602 | algorithm | ||
| 1603 | 43 | e := fixElement(inCache, inEnv, outMod.element, tree); | |
| 1604 |
1/2✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
|
43 | if not referenceEq(e, outMod.element) then |
| 1605 | 43 | outMod.element := e; | |
| 1606 | end if; | ||
| 1607 | then outMod; | ||
| 1608 | |||
| 1609 | case SCode.REDECL(element = e as SCode.CLASS(classDef = cdef)) | ||
| 1610 | algorithm | ||
| 1611 | 3943 | cdef := fixClassdef(inCache, inEnv, cdef, tree); | |
| 1612 |
2/2✓ Branch 0 taken 3769 times.
✓ Branch 1 taken 174 times.
|
3943 | if not referenceEq(cdef, e.classDef) then |
| 1613 | 3769 | e.classDef := cdef; | |
| 1614 | 3769 | outMod.element := e; | |
| 1615 | end if; | ||
| 1616 | then outMod; | ||
| 1617 | |||
| 1618 | else | ||
| 1619 | algorithm | ||
| 1620 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 1621 | ✗ | Debug.traceln("InstExtends.fixModifications failed: " + SCodeDump.printModStr(inMod)); | |
| 1622 | ✗ | then | |
| 1623 | fail(); | ||
| 1624 | |||
| 1625 | end matchcontinue; | ||
| 1626 | end fixModifications; | ||
| 1627 | |||
| 1628 | protected function fixSubMod | ||
| 1629 | " All of the fix functions do the following: | ||
| 1630 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1631 | local lookup or fully qualified in the environment." | ||
| 1632 | input array<FCore.Cache> inCache; | ||
| 1633 | input FCore.Graph inEnv; | ||
| 1634 | input output SCode.SubMod subMod; | ||
| 1635 | input AvlSetString.Tree tree; | ||
| 1636 | protected | ||
| 1637 | Absyn.Ident ident; | ||
| 1638 | SCode.Mod mod1, mod2; | ||
| 1639 | algorithm | ||
| 1640 | 135733 | SCode.NAMEMOD(ident, mod1) := subMod; | |
| 1641 | 135733 | mod2 := fixModifications(inCache, inEnv, mod1, tree); | |
| 1642 |
2/2✓ Branch 0 taken 130545 times.
✓ Branch 1 taken 5188 times.
|
135733 | if not referenceEq(mod1, mod2) then |
| 1643 | 5188 | subMod := SCode.NAMEMOD(ident, mod2); | |
| 1644 | end if; | ||
| 1645 | end fixSubMod; | ||
| 1646 | |||
| 1647 | protected function fixExp | ||
| 1648 | " All of the fix functions do the following: | ||
| 1649 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1650 | local lookup or fully qualified in the environment. | ||
| 1651 | " | ||
| 1652 | input array<FCore.Cache> cache; | ||
| 1653 | input FCore.Graph inEnv; | ||
| 1654 | input Absyn.Exp inExp; | ||
| 1655 | input AvlSetString.Tree tree; | ||
| 1656 | output Absyn.Exp outExp; | ||
| 1657 | algorithm | ||
| 1658 | 431179 | (outExp,_) := AbsynUtil.traverseExp(inExp,fixExpTraverse,(cache,inEnv,tree)); | |
| 1659 | end fixExp; | ||
| 1660 | |||
| 1661 | protected function fixExpTraverse | ||
| 1662 | " All of the fix functions do the following: | ||
| 1663 | Analyzes the SCode datastructure and replace paths with a new path (from | ||
| 1664 | local lookup or fully qualified in the environment. | ||
| 1665 | " | ||
| 1666 | input output Absyn.Exp exp; | ||
| 1667 | input output tuple<array<FCore.Cache>,FCore.Graph,AvlSetString.Tree> tpl; | ||
| 1668 | algorithm | ||
| 1669 | exp := match (exp,tpl) | ||
| 1670 | local | ||
| 1671 | Absyn.FunctionArgs fargs; | ||
| 1672 | Absyn.ComponentRef cref, cref1; | ||
| 1673 | array<FCore.Cache> cache; | ||
| 1674 | FCore.Graph env; | ||
| 1675 | AvlSetString.Tree tree; | ||
| 1676 | |||
| 1677 | case (Absyn.CREF(cref),(cache,env,tree)) | ||
| 1678 | algorithm | ||
| 1679 | 457370 | cref1 := fixCref(cache,env,cref,tree); | |
| 1680 |
2/2✓ Branch 0 taken 5489 times.
✓ Branch 1 taken 451881 times.
|
457370 | then (if referenceEq(cref, cref1) then exp else Absyn.CREF(cref1)); |
| 1681 | |||
| 1682 | case (Absyn.CALL(function_ = cref),(cache,env,tree)) | ||
| 1683 | algorithm | ||
| 1684 | // print("cref actual: " + AbsynUtil.crefString(cref) + " scope: " + FGraph.printGraphPathStr(env) + "\n"); | ||
| 1685 | 105370 | cref1 := fixCref(cache,env,cref,tree); | |
| 1686 | // print("cref fixed : " + AbsynUtil.crefString(cref) + "\n"); | ||
| 1687 |
2/2✓ Branch 0 taken 10816 times.
✓ Branch 1 taken 94554 times.
|
105370 | then (if referenceEq(cref, cref1) then exp else Absyn.CALL(cref1, exp.functionArgs, exp.typeVars)); |
| 1688 | |||
| 1689 | case (Absyn.PARTEVALFUNCTION(cref,fargs),(cache,env,tree)) | ||
| 1690 | algorithm | ||
| 1691 | 168 | cref1 := fixCref(cache,env,cref,tree); | |
| 1692 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
|
168 | then (if referenceEq(cref, cref1) then exp else Absyn.PARTEVALFUNCTION(cref1,fargs)); |
| 1693 | |||
| 1694 | else exp; | ||
| 1695 | end match; | ||
| 1696 | end fixExpTraverse; | ||
| 1697 | |||
| 1698 | protected function fixOption<Type_A> | ||
| 1699 | " Generic function to fix an optional element." | ||
| 1700 | input array<FCore.Cache> inCache; | ||
| 1701 | input FCore.Graph inEnv; | ||
| 1702 | input Option<Type_A> inA; | ||
| 1703 | input AvlSetString.Tree tree; | ||
| 1704 | input FixAFn fixA; | ||
| 1705 | output Option<Type_A> outA; | ||
| 1706 | |||
| 1707 | partial function FixAFn | ||
| 1708 | input array<FCore.Cache> inCache; | ||
| 1709 | input FCore.Graph inEnv; | ||
| 1710 | input Type_A inA; | ||
| 1711 | input AvlSetString.Tree tree; | ||
| 1712 | output Type_A outTypeA; | ||
| 1713 | end FixAFn; | ||
| 1714 | algorithm | ||
| 1715 | outA := match inA | ||
| 1716 | local | ||
| 1717 | Type_A A1,A2; | ||
| 1718 | |||
| 1719 | case NONE() then inA; | ||
| 1720 | case SOME(A1) | ||
| 1721 | algorithm | ||
| 1722 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 253155 times.
|
253155 | A2 := fixA(inCache, inEnv, A1, tree); |
| 1723 |
2/2✓ Branch 0 taken 2979 times.
✓ Branch 1 taken 250176 times.
|
253155 | then if referenceEq(A1,A2) then inA else SOME(A2); |
| 1724 | end match; | ||
| 1725 | end fixOption; | ||
| 1726 | |||
| 1727 | protected function fixList<Type_A> | ||
| 1728 | " Generic function to fix a list of elements." | ||
| 1729 | input array<FCore.Cache> inCache; | ||
| 1730 | input FCore.Graph inEnv; | ||
| 1731 | input list<Type_A> inA; | ||
| 1732 | input AvlSetString.Tree tree; | ||
| 1733 | input FixAFn fixA; | ||
| 1734 | output list<Type_A> outA; | ||
| 1735 | |||
| 1736 | partial function FixAFn | ||
| 1737 | input array<FCore.Cache> inCache; | ||
| 1738 | input FCore.Graph inEnv; | ||
| 1739 | input Type_A inA; | ||
| 1740 | input AvlSetString.Tree tree; | ||
| 1741 | output Type_A outTypeA; | ||
| 1742 | end FixAFn; | ||
| 1743 | algorithm | ||
| 1744 |
2/2✓ Branch 0 taken 1059926 times.
✓ Branch 1 taken 304522 times.
|
1364448 | if listEmpty(inA) then |
| 1745 | outA := inA; | ||
| 1746 | 1059926 | return; | |
| 1747 | end if; | ||
| 1748 | 304522 | outA := List.mapCheckReferenceEq(inA, function fixA(inCache=inCache, inEnv=inEnv, tree=tree)); | |
| 1749 | end fixList; | ||
| 1750 | |||
| 1751 | protected function fixListList<Type_A> | ||
| 1752 | " Generic function to fix a list of elements." | ||
| 1753 | input array<FCore.Cache> inCache; | ||
| 1754 | input FCore.Graph inEnv; | ||
| 1755 | input list<list<Type_A>> inA; | ||
| 1756 | input AvlSetString.Tree tree; | ||
| 1757 | input FixAFn fixA; | ||
| 1758 | output list<list<Type_A>> outA = {}; | ||
| 1759 | |||
| 1760 | partial function FixAFn | ||
| 1761 | input array<FCore.Cache> inCache; | ||
| 1762 | input FCore.Graph inEnv; | ||
| 1763 | input Type_A inA; | ||
| 1764 | input AvlSetString.Tree tree; | ||
| 1765 | output Type_A outTypeA; | ||
| 1766 | end FixAFn; | ||
| 1767 | algorithm | ||
| 1768 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5899 times.
|
5899 | if listEmpty(inA) then |
| 1769 | outA := {}; | ||
| 1770 | ✗ | return; | |
| 1771 | end if; | ||
| 1772 | |||
| 1773 | 5899 | outA := List.mapCheckReferenceEq(inA, function fixList(inCache=inCache, inEnv=inEnv, tree=tree, fixA=fixA)); | |
| 1774 | end fixListList; | ||
| 1775 | |||
| 1776 | protected function fixListTuple2<Type_A, Type_B> | ||
| 1777 | " Generic function to fix a list of elements." | ||
| 1778 | input array<FCore.Cache> inCache; | ||
| 1779 | input FCore.Graph inEnv; | ||
| 1780 | input list<tuple<Type_A,Type_B>> inRest; | ||
| 1781 | input AvlSetString.Tree tree; | ||
| 1782 | input FixAFn fixA; | ||
| 1783 | input FixBFn fixB; | ||
| 1784 | output list<tuple<Type_A,Type_B>> outA; | ||
| 1785 | |||
| 1786 | partial function FixAFn | ||
| 1787 | input array<FCore.Cache> inCache; | ||
| 1788 | input FCore.Graph inEnv; | ||
| 1789 | input Type_A inA; | ||
| 1790 | input AvlSetString.Tree tree; | ||
| 1791 | output Type_A outLst; | ||
| 1792 | end FixAFn; | ||
| 1793 | partial function FixBFn | ||
| 1794 | input array<FCore.Cache> inCache; | ||
| 1795 | input FCore.Graph inEnv; | ||
| 1796 | input Type_B inA; | ||
| 1797 | input AvlSetString.Tree tree; | ||
| 1798 | output Type_B outTypeA; | ||
| 1799 | end FixBFn; | ||
| 1800 | protected | ||
| 1801 | algorithm | ||
| 1802 | 559 | outA := fixList(inCache, inEnv, inRest, tree, function fixTuple2(fixA=fixA, fixB=fixB)); | |
| 1803 | end fixListTuple2; | ||
| 1804 | |||
| 1805 | protected function fixTuple2<Type_A, Type_B> | ||
| 1806 | " Generic function to fix a list of elements." | ||
| 1807 | input array<FCore.Cache> inCache; | ||
| 1808 | input FCore.Graph inEnv; | ||
| 1809 | input output tuple<Type_A,Type_B> tpl; | ||
| 1810 | input AvlSetString.Tree tree; | ||
| 1811 | input FixAFn fixA; | ||
| 1812 | input FixBFn fixB; | ||
| 1813 | |||
| 1814 | partial function FixAFn | ||
| 1815 | input array<FCore.Cache> inCache; | ||
| 1816 | input FCore.Graph inEnv; | ||
| 1817 | input Type_A inA; | ||
| 1818 | input AvlSetString.Tree tree; | ||
| 1819 | output Type_A outLst; | ||
| 1820 | end FixAFn; | ||
| 1821 | partial function FixBFn | ||
| 1822 | input array<FCore.Cache> inCache; | ||
| 1823 | input FCore.Graph inEnv; | ||
| 1824 | input Type_B inA; | ||
| 1825 | input AvlSetString.Tree tree; | ||
| 1826 | output Type_B outTypeA; | ||
| 1827 | end FixBFn; | ||
| 1828 | protected | ||
| 1829 | Type_A a1,a2; | ||
| 1830 | Type_B b1,b2; | ||
| 1831 | algorithm | ||
| 1832 | 264 | (a1, b1) := tpl; | |
| 1833 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 264 times.
|
264 | a2 := fixA(inCache, inEnv, a1, tree); |
| 1834 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 264 times.
|
264 | b2 := fixB(inCache, inEnv, b1, tree); |
| 1835 |
2/2✓ Branch 0 taken 243 times.
✓ Branch 1 taken 21 times.
|
264 | if not (referenceEq(a1,a2) and referenceEq(b1,b2)) then |
| 1836 | 21 | tpl := (a2, b2); | |
| 1837 | end if; | ||
| 1838 | end fixTuple2; | ||
| 1839 | |||
| 1840 | annotation(__OpenModelica_Interface="frontend"); | ||
| 1841 | end InstExtends; | ||
| 1842 |