OMCompiler/Compiler/FrontEnd/Lookup.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 Lookup | ||
| 37 | " file: Lookup.mo | ||
| 38 | package: Lookup | ||
| 39 | description: Scoping rules | ||
| 40 | |||
| 41 | |||
| 42 | This module is responsible for the lookup mechanism in Modelica. | ||
| 43 | It is responsible for looking up classes, variables, etc. in the | ||
| 44 | environment Env by following the lookup rules. | ||
| 45 | The most important functions are: | ||
| 46 | lookupClass - to find a class | ||
| 47 | lookupType - to find types (e.g. functions, types, etc.) | ||
| 48 | lookupVar - to find a variable in the instance hierarchy." | ||
| 49 | |||
| 50 | public import Absyn; | ||
| 51 | public import AbsynUtil; | ||
| 52 | public import ClassInf; | ||
| 53 | public import DAE; | ||
| 54 | public import FCore; | ||
| 55 | public import HashTableStringToPath; | ||
| 56 | public import InstTypes; | ||
| 57 | public import SCode; | ||
| 58 | public import Util; | ||
| 59 | public import Types; | ||
| 60 | |||
| 61 | protected import BaseHashTable; | ||
| 62 | protected import Builtin; | ||
| 63 | protected import ComponentReference; | ||
| 64 | protected import ComponentReferenceBasics; | ||
| 65 | protected import Config; | ||
| 66 | protected import DAE.Connect; | ||
| 67 | protected import ConnectionGraph; | ||
| 68 | protected import Debug; | ||
| 69 | protected import Error; | ||
| 70 | protected import Expression; | ||
| 71 | protected import Flags; | ||
| 72 | protected import FGraph; | ||
| 73 | protected import FNode; | ||
| 74 | protected import Inst; | ||
| 75 | protected import InstExtends; | ||
| 76 | protected import InstFunction; | ||
| 77 | protected import InstUtil; | ||
| 78 | protected import InnerOuter; | ||
| 79 | protected import List; | ||
| 80 | protected import Mod; | ||
| 81 | protected import Mutable; | ||
| 82 | protected import PrefixUtil; | ||
| 83 | import SCodeUtil; | ||
| 84 | protected import Static; | ||
| 85 | protected import UnitAbsyn; | ||
| 86 | protected import SCodeDump; | ||
| 87 | protected import ErrorExt; | ||
| 88 | protected import ValuesUtil; | ||
| 89 | protected import Values; | ||
| 90 | protected import ExpressionBasics; | ||
| 91 | protected import ClassInfUtil; | ||
| 92 | |||
| 93 | /* - Lookup functions | ||
| 94 | |||
| 95 | These functions look up class and variable names in the environment. | ||
| 96 | The names are supplied as a path, and if the path is qualified, a | ||
| 97 | variable named as the first part of the path is searched for, and the | ||
| 98 | name is looked for in it. | ||
| 99 | |||
| 100 | */ | ||
| 101 | |||
| 102 | public function lookupType | ||
| 103 | " This function finds a specified type in the environment. | ||
| 104 | If it finds a function instead, this will be implicitly instantiated | ||
| 105 | and lookup will start over. | ||
| 106 | " | ||
| 107 | input FCore.Cache inCache; | ||
| 108 | input FCore.Graph inEnv "environment to search in"; | ||
| 109 | input Absyn.Path inPath "type to look for"; | ||
| 110 | input Option<SourceInfo> msg "Messaage flag, SOME() outputs lookup error messages"; | ||
| 111 | output FCore.Cache cache; | ||
| 112 | output DAE.Type t "the found type"; | ||
| 113 | output FCore.Graph env "The environment the type was found in"; | ||
| 114 | algorithm | ||
| 115 | (cache,t,env) := match inPath | ||
| 116 | |||
| 117 | case Absyn.IDENT() | ||
| 118 | algorithm | ||
| 119 | 15857 | (cache, t, env) := lookupTypeIdent(inCache,inEnv,inPath.name,msg); | |
| 120 | then (cache, t, env); | ||
| 121 | |||
| 122 | else | ||
| 123 | algorithm | ||
| 124 | 47553 | (cache, t, env) := lookupTypeQual(inCache,inEnv,inPath,msg); | |
| 125 | then (cache, t, env); | ||
| 126 | end match; | ||
| 127 | end lookupType; | ||
| 128 | |||
| 129 | protected function lookupTypeQual | ||
| 130 | " This function finds a specified type in the environment. | ||
| 131 | If it finds a function instead, this will be implicitly instantiated | ||
| 132 | and lookup will start over. | ||
| 133 | " | ||
| 134 | input FCore.Cache inCache; | ||
| 135 | input FCore.Graph inEnv "environment to search in"; | ||
| 136 | input Absyn.Path inPath "type to look for"; | ||
| 137 | input Option<SourceInfo> msg "Messaage flag, SOME() outputs lookup error messages"; | ||
| 138 | output FCore.Cache outCache; | ||
| 139 | output DAE.Type outType "the found type"; | ||
| 140 | output FCore.Graph outEnv "The environment the type was found in"; | ||
| 141 | algorithm | ||
| 142 | (outCache,outType,outEnv):= | ||
| 143 | matchcontinue (inCache,inEnv,inPath,msg) | ||
| 144 | local | ||
| 145 | DAE.Type t; | ||
| 146 | FCore.Graph env_1,env,env_2; | ||
| 147 | Absyn.Path path; | ||
| 148 | SCode.Element c; | ||
| 149 | String classname,scope; | ||
| 150 | FCore.Cache cache; | ||
| 151 | SourceInfo info; | ||
| 152 | |||
| 153 | // Special handling for Connections.isRoot | ||
| 154 | case (cache,env,Absyn.QUALIFIED("Connections", Absyn.IDENT("isRoot")),_) | ||
| 155 | algorithm | ||
| 156 | ✗ | t := DAE.T_FUNCTION({DAE.FUNCARG("x", DAE.T_ANYTYPE_DEFAULT, DAE.C_VAR(), DAE.NON_PARALLEL(), NONE())}, DAE.T_BOOL_DEFAULT, DAE.FUNCTION_ATTRIBUTES_DEFAULT, inPath); | |
| 157 | ✗ | then | |
| 158 | (cache, t, env); | ||
| 159 | |||
| 160 | // Special handling for Connections.uniqueRootIndices | ||
| 161 | case (cache,env,Absyn.QUALIFIED("Connections", Absyn.IDENT("uniqueRootIndices")),_) | ||
| 162 | algorithm | ||
| 163 | ✗ | t := DAE.T_FUNCTION({ | |
| 164 | DAE.FUNCARG("roots", DAE.T_ARRAY(DAE.T_ANYTYPE_DEFAULT, {DAE.DIM_UNKNOWN()}), DAE.C_VAR(), DAE.NON_PARALLEL(), NONE()), | ||
| 165 | DAE.FUNCARG("nodes", DAE.T_ARRAY(DAE.T_ANYTYPE_DEFAULT, {DAE.DIM_UNKNOWN()}), DAE.C_VAR(), DAE.NON_PARALLEL(), NONE()), | ||
| 166 | DAE.FUNCARG("message", DAE.T_STRING_DEFAULT, DAE.C_VAR(), DAE.NON_PARALLEL(), NONE())}, | ||
| 167 | DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT, {DAE.DIM_UNKNOWN()}), | ||
| 168 | DAE.FUNCTION_ATTRIBUTES_DEFAULT, inPath); | ||
| 169 | ✗ | then | |
| 170 | (cache, t, env); | ||
| 171 | |||
| 172 | // Special classes (function, record, metarecord, external object) | ||
| 173 | case (cache,env,path,_) | ||
| 174 | algorithm | ||
| 175 | 47553 | (cache,c,env_1) := lookupClass(cache,env,path); | |
| 176 | 47226 | (cache,t,env_2) := lookupType2(cache,env_1,c); | |
| 177 | then | ||
| 178 | (cache,t,env_2); | ||
| 179 | |||
| 180 | // Error for type not found | ||
| 181 | case (_,env,path,SOME(info)) | ||
| 182 | algorithm | ||
| 183 | ✗ | classname := AbsynUtil.pathString(path); | |
| 184 | ✗ | classname := stringAppend(classname," (its type) "); | |
| 185 | ✗ | scope := FGraph.printGraphPathStr(env); | |
| 186 | ✗ | Error.addSourceMessage(Error.LOOKUP_ERROR, {classname,scope}, info); | |
| 187 | ✗ | then | |
| 188 | fail(); | ||
| 189 | end matchcontinue; | ||
| 190 | end lookupTypeQual; | ||
| 191 | |||
| 192 | public function lookupTypeIdent | ||
| 193 | " This function finds a specified type in the environment. | ||
| 194 | If it finds a function instead, this will be implicitly instantiated | ||
| 195 | and lookup will start over. | ||
| 196 | " | ||
| 197 | input FCore.Cache inCache; | ||
| 198 | input FCore.Graph inEnv "environment to search in"; | ||
| 199 | input String ident "type to look for"; | ||
| 200 | input Option<SourceInfo> msg "Messaage flag, SOME() outputs lookup error messages"; | ||
| 201 | output FCore.Cache outCache; | ||
| 202 | output DAE.Type outType "the found type"; | ||
| 203 | output FCore.Graph outEnv "The environment the type was found in"; | ||
| 204 | algorithm | ||
| 205 | (outCache,outType,outEnv):= | ||
| 206 | matchcontinue (inCache,inEnv,ident,msg) | ||
| 207 | local | ||
| 208 | DAE.Type t; | ||
| 209 | FCore.Graph env_1,env,env_2; | ||
| 210 | SCode.Element c; | ||
| 211 | String classname,scope; | ||
| 212 | FCore.Cache cache; | ||
| 213 | SourceInfo info; | ||
| 214 | |||
| 215 | // Special handling for MultiBody 3.x rooted() operator | ||
| 216 | case (cache,env,"rooted",_) | ||
| 217 | algorithm | ||
| 218 | t := DAE.T_FUNCTION({DAE.FUNCARG("x", DAE.T_ANYTYPE_DEFAULT, DAE.C_VAR(), DAE.NON_PARALLEL(), NONE())}, DAE.T_BOOL_DEFAULT, DAE.FUNCTION_ATTRIBUTES_DEFAULT, Absyn.IDENT("rooted")); | ||
| 219 | ✗ | then | |
| 220 | (cache, t, env); | ||
| 221 | |||
| 222 | // For simple names | ||
| 223 | case (cache,env,_,_) | ||
| 224 | algorithm | ||
| 225 | 31236 | (cache,t,env_1) := lookupTypeInEnv(cache,env,ident); | |
| 226 | then | ||
| 227 | (cache,t,env_1); | ||
| 228 | |||
| 229 | // Special classes (function, record, metarecord, external object) | ||
| 230 | case (cache,env,_,_) | ||
| 231 | algorithm | ||
| 232 | 28675 | (cache,c,env_1) := lookupClassIdent(cache,env,ident); | |
| 233 | 12096 | (cache,t,env_2) := lookupType2(cache,env_1,c); | |
| 234 | then | ||
| 235 | (cache,t,env_2); | ||
| 236 | |||
| 237 | // Error for type not found | ||
| 238 | case (_,env,_,SOME(info)) | ||
| 239 | algorithm | ||
| 240 | ✗ | classname := stringAppend(ident," (its type) "); | |
| 241 | ✗ | scope := FGraph.printGraphPathStr(env); | |
| 242 | ✗ | Error.addSourceMessage(Error.LOOKUP_ERROR, {classname,scope}, info); | |
| 243 | ✗ | then | |
| 244 | fail(); | ||
| 245 | end matchcontinue; | ||
| 246 | end lookupTypeIdent; | ||
| 247 | |||
| 248 | protected function lookupType2 | ||
| 249 | " This function handles the case when we looked up a class, but need to | ||
| 250 | check if it is function, record, metarecord, etc. | ||
| 251 | " | ||
| 252 | input FCore.Cache inCache; | ||
| 253 | input FCore.Graph inEnv "environment to search in"; | ||
| 254 | input SCode.Element inClass "the class lookupType found"; | ||
| 255 | output FCore.Cache outCache; | ||
| 256 | output DAE.Type outType "the found type"; | ||
| 257 | output FCore.Graph outEnv "The environment the type was found in"; | ||
| 258 | algorithm | ||
| 259 | (outCache,outType,outEnv) := matchcontinue (inCache,inEnv,inClass) | ||
| 260 | local | ||
| 261 | DAE.Type t; | ||
| 262 | FCore.Graph env_1,env_2,env_3; | ||
| 263 | Absyn.Path path; | ||
| 264 | SCode.Element c; | ||
| 265 | String id; | ||
| 266 | FCore.Cache cache; | ||
| 267 | SCode.Restriction r; | ||
| 268 | list<DAE.Var> types; | ||
| 269 | list<String> names; | ||
| 270 | ClassInf.State ci_state; | ||
| 271 | SCode.Encapsulated encflag; | ||
| 272 | DAE.Mod mod; | ||
| 273 | |||
| 274 | // Record constructors | ||
| 275 | case (cache,env_1,c as SCode.CLASS(restriction=SCode.R_RECORD(_))) | ||
| 276 | algorithm | ||
| 277 | 5 | (cache,env_1,t) := buildRecordType(cache,env_1,c); | |
| 278 | 5 | then | |
| 279 | (cache,t,env_1); | ||
| 280 | |||
| 281 | // lookup of an enumeration type | ||
| 282 | case (cache,env_1,c as SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=r as SCode.R_ENUMERATION())) | ||
| 283 | algorithm | ||
| 284 | 122 | env_2 := FGraph.openScope(env_1, encflag, id, SOME(FCore.CLASS_SCOPE())); | |
| 285 | 122 | ci_state := ClassInfUtil.start(r, FGraph.getGraphName(env_2)); | |
| 286 | // fprintln(Flags.INST_TRACE, "LOOKUP TYPE ICD: " + FGraph.printGraphPathStr(env_1) + " path:" + AbsynUtil.pathString(path)); | ||
| 287 | 122 | mod := Mod.getClassModifier(env_1, id); | |
| 288 | 122 | (cache,env_3,_,_,_,_,_,types,_,_,_,_) := | |
| 289 | Inst.instClassIn( | ||
| 290 | cache,env_2,InnerOuter.emptyInstHierarchy,UnitAbsyn.noStore, | ||
| 291 | mod, DAE.NOPRE(), | ||
| 292 | ci_state, c, SCode.PUBLIC(), {}, false, InstTypes.INNER_CALL(), | ||
| 293 | ConnectionGraph.EMPTY, Connect.emptySet, NONE()); | ||
| 294 | // build names | ||
| 295 | 122 | (_,names) := SCodeUtil.getClassComponents(c); | |
| 296 | 122 | Types.checkEnumDuplicateLiterals(names, c.info); | |
| 297 | // generate the enumeration type | ||
| 298 | 122 | path := FGraph.getGraphName(env_3); | |
| 299 | 122 | t := DAE.T_ENUMERATION(NONE(), path, names, types, {}); | |
| 300 | 122 | env_3 := FGraph.mkTypeNode(env_3, id, t); | |
| 301 | 122 | then | |
| 302 | (cache,t,env_3); | ||
| 303 | |||
| 304 | // Real Type | ||
| 305 | case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="Real"))))) | ||
| 306 | algorithm | ||
| 307 | t := DAE.T_REAL_DEFAULT; | ||
| 308 | ✗ | then | |
| 309 | (cache,t,env_1); | ||
| 310 | |||
| 311 | // Integer Type | ||
| 312 | case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="Integer"))))) | ||
| 313 | algorithm | ||
| 314 | t := DAE.T_INTEGER_DEFAULT; | ||
| 315 | ✗ | then | |
| 316 | (cache,t,env_1); | ||
| 317 | |||
| 318 | // Boolean Type | ||
| 319 | case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="Boolean"))))) | ||
| 320 | algorithm | ||
| 321 | t := DAE.T_BOOL_DEFAULT; | ||
| 322 | ✗ | then | |
| 323 | (cache,t,env_1); | ||
| 324 | |||
| 325 | // String Type | ||
| 326 | case (cache,env_1,SCode.CLASS(restriction=SCode.R_TYPE(),classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path=Absyn.IDENT(name="String"))))) | ||
| 327 | algorithm | ||
| 328 | t := DAE.T_STRING_DEFAULT; | ||
| 329 | ✗ | then | |
| 330 | (cache,t,env_1); | ||
| 331 | |||
| 332 | // Metamodelica extension, Uniontypes | ||
| 333 | case (cache,env_1,c as SCode.CLASS(restriction=SCode.R_METARECORD())) | ||
| 334 | algorithm | ||
| 335 | 48727 | (cache,env_2,t) := buildMetaRecordType(cache,env_1,c); | |
| 336 | 48705 | then | |
| 337 | (cache,t,env_2); | ||
| 338 | |||
| 339 | // Classes that are external objects. Implicitly instantiate to get type | ||
| 340 | case (cache,env_1,c) | ||
| 341 | algorithm | ||
| 342 | // fprintln(Flags.INST_TRACE, "LOOKUP TYPE ICD: " + FGraph.printGraphPathStr(env_1) + " path:" + AbsynUtil.pathString(path)); | ||
| 343 |
2/2✓ Branch 1 taken 10477 times.
✓ Branch 2 taken 13 times.
|
10490 | true := SCodeUtil.classIsExternalObject(c); |
| 344 | 13 | (cache,env_1,_,_,_,_,_,_,_,_) := Inst.instClass( | |
| 345 | cache,env_1,InnerOuter.emptyInstHierarchy, UnitAbsyn.noStore, | ||
| 346 | DAE.NOMOD(), DAE.NOPRE(), c, | ||
| 347 | {}, false, InstTypes.TOP_CALL(), ConnectionGraph.EMPTY, Connect.emptySet); | ||
| 348 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | SCode.CLASS(name=id) := c; |
| 349 | 13 | (env_1, _) := FGraph.stripLastScopeRef(env_1); | |
| 350 | 13 | (cache,t,env_2) := lookupTypeInEnv(cache,env_1,id); | |
| 351 | then | ||
| 352 | (cache,t,env_2); | ||
| 353 | |||
| 354 | // If we find a class definition that is a function or external function | ||
| 355 | // with the same name then we implicitly instantiate that function, look | ||
| 356 | // up the type. | ||
| 357 | case (cache,env_1,c as SCode.CLASS(name = id,restriction=SCode.R_FUNCTION(_))) | ||
| 358 | algorithm | ||
| 359 | // fprintln(Flags.INST_TRACE, "LOOKUP TYPE ICD: " + FGraph.printGraphPathStr(env_1) + " path:" + AbsynUtil.pathString(path)); | ||
| 360 | 10455 | (cache,env_2,_) := | |
| 361 | InstFunction.implicitFunctionTypeInstantiation(cache,env_1,InnerOuter.emptyInstHierarchy,c); | ||
| 362 | 9156 | (cache,t,env_3) := lookupTypeInEnv(cache,env_2,id); | |
| 363 | then | ||
| 364 | (cache,t,env_3); | ||
| 365 | end matchcontinue; | ||
| 366 | end lookupType2; | ||
| 367 | |||
| 368 | public function lookupMetarecordsRecursive | ||
| 369 | "Takes a list of paths to Uniontypes. Use this list to create a list of T_METARECORD. | ||
| 370 | The function is guarded against recursive definitions by accumulating all paths it | ||
| 371 | starts to traverse." | ||
| 372 | input FCore.Cache inCache; | ||
| 373 | input FCore.Graph inEnv; | ||
| 374 | input list<Absyn.Path> inUniontypePaths; | ||
| 375 | output FCore.Cache outCache; | ||
| 376 | output list<DAE.Type> outMetarecordTypes; | ||
| 377 | algorithm | ||
| 378 | 148 | (outCache,_,outMetarecordTypes) := lookupMetarecordsRecursive2(inCache, inEnv, inUniontypePaths, HashTableStringToPath.emptyHashTable(), {}); | |
| 379 | end lookupMetarecordsRecursive; | ||
| 380 | |||
| 381 | protected function lookupMetarecordsRecursive2 | ||
| 382 | "Takes a list of paths to Uniontypes. Use this list to create a list of T_METARECORD. | ||
| 383 | The function is guarded against recursive definitions by accumulating all paths it | ||
| 384 | starts to traverse." | ||
| 385 | input FCore.Cache inCache; | ||
| 386 | input FCore.Graph inEnv; | ||
| 387 | input list<Absyn.Path> inUniontypePaths; | ||
| 388 | input HashTableStringToPath.HashTable inHt; | ||
| 389 | input list<DAE.Type> inAcc; | ||
| 390 | output FCore.Cache outCache = inCache; | ||
| 391 | output HashTableStringToPath.HashTable outHt = inHt; | ||
| 392 | output list<DAE.Type> outMetarecordTypes = inAcc; | ||
| 393 | algorithm | ||
| 394 |
2/2✓ Branch 0 taken 475881 times.
✓ Branch 1 taken 17507 times.
|
493388 | for first in inUniontypePaths loop |
| 395 | 475881 | (outCache, outHt, outMetarecordTypes) := | |
| 396 | lookupMetarecordsRecursive3(outCache, inEnv, first, AbsynUtil.pathString(first), outHt, outMetarecordTypes); | ||
| 397 | end for; | ||
| 398 | end lookupMetarecordsRecursive2; | ||
| 399 | |||
| 400 | protected function lookupMetarecordsRecursive3 | ||
| 401 | "Takes a list of paths to Uniontypes. Use this list to create a list of T_METARECORD. | ||
| 402 | The function is guarded against recursive definitions by accumulating all paths it | ||
| 403 | starts to traverse." | ||
| 404 | input FCore.Cache inCache; | ||
| 405 | input FCore.Graph inEnv; | ||
| 406 | input Absyn.Path path; | ||
| 407 | input String str; | ||
| 408 | input HashTableStringToPath.HashTable inHt; | ||
| 409 | input list<DAE.Type> inAcc; | ||
| 410 | output FCore.Cache outCache; | ||
| 411 | output HashTableStringToPath.HashTable outHt; | ||
| 412 | output list<DAE.Type> outMetarecordTypes; | ||
| 413 | algorithm | ||
| 414 | (outCache,outHt,outMetarecordTypes) := match (inCache, inEnv, inHt, inAcc) | ||
| 415 | local | ||
| 416 | FCore.Cache cache; | ||
| 417 | FCore.Graph env; | ||
| 418 | list<Absyn.Path> uniontypePaths; | ||
| 419 | list<DAE.Type> uniontypeTypes; | ||
| 420 | DAE.Type ty; | ||
| 421 | list<DAE.Type> acc; | ||
| 422 | HashTableStringToPath.HashTable ht; | ||
| 423 | |||
| 424 | case (cache, _, ht, acc) guard BaseHashTable.hasKey(str, ht) | ||
| 425 | 458522 | then (cache, ht, acc); | |
| 426 | case (cache, env, ht, acc) | ||
| 427 | algorithm | ||
| 428 | 17359 | ht := BaseHashTable.add((str,path),ht); | |
| 429 | 17359 | (cache, ty, _) := lookupType(cache, env, path, SOME(Absyn.dummyInfo)); | |
| 430 | 17359 | acc := ty::acc; | |
| 431 | 17359 | uniontypeTypes := Types.getAllInnerTypesOfType(ty, Types.uniontypeFilter); | |
| 432 | 17359 | uniontypePaths := List.flatten(List.map(uniontypeTypes, Types.getUniontypePaths)); | |
| 433 | 17359 | (cache, ht, acc) := lookupMetarecordsRecursive2(cache, env, uniontypePaths, ht, acc); | |
| 434 | then (cache,ht,acc); | ||
| 435 | end match; | ||
| 436 | end lookupMetarecordsRecursive3; | ||
| 437 | |||
| 438 | public function lookupClass "Tries to find a specified class in an environment" | ||
| 439 | input FCore.Cache inCache; | ||
| 440 | input FCore.Graph inEnv "Where to look"; | ||
| 441 | input Absyn.Path inPath "Path of the class to look for"; | ||
| 442 | input Option<SourceInfo> inInfo = NONE(); | ||
| 443 | output FCore.Cache outCache; | ||
| 444 | output SCode.Element outClass; | ||
| 445 | output FCore.Graph outEnv; | ||
| 446 | algorithm | ||
| 447 | (outCache,outClass,outEnv) := matchcontinue inPath | ||
| 448 | local | ||
| 449 | Absyn.Path id; | ||
| 450 | String name; | ||
| 451 | FGraph.Graph cenv; | ||
| 452 | |||
| 453 | /* | ||
| 454 | case (_,_,_,_) | ||
| 455 | algorithm | ||
| 456 | print("CL: " + AbsynUtil.pathString(inPath) + " env: " + FGraph.printGraphPathStr(inEnv) + " msg: " + boolString(msg) + "\n"); | ||
| 457 | then | ||
| 458 | fail();*/ | ||
| 459 | |||
| 460 | // see if the first path ident is a component | ||
| 461 | // we might have a component reference, i.e. world.gravityAcceleration | ||
| 462 | case Absyn.QUALIFIED(name, id) | ||
| 463 | algorithm | ||
| 464 | 264240 | ErrorExt.setCheckpoint("functionViaComponentRef2"); | |
| 465 | 264240 | (outCache,_,_,_,_,_,_,cenv,_) := lookupVarIdent(inCache, inEnv, name, {}); | |
| 466 | 12053 | (outCache, outClass, outEnv) := lookupClass(outCache, cenv, id); | |
| 467 | 1226 | ErrorExt.rollBack("functionViaComponentRef2"); | |
| 468 | 1226 | then | |
| 469 | (outCache,outClass,outEnv); | ||
| 470 | |||
| 471 | case Absyn.QUALIFIED(_, _) | ||
| 472 | algorithm | ||
| 473 | 263014 | ErrorExt.rollBack("functionViaComponentRef2"); | |
| 474 | 263014 | then | |
| 475 | fail(); | ||
| 476 | |||
| 477 | // normal case | ||
| 478 | case _ | ||
| 479 | algorithm | ||
| 480 | 1972668 | (outCache,outClass,outEnv,_) := lookupClass1(inCache, inEnv, inPath, {}, Mutable.create(false), inInfo); | |
| 481 | // print("CLRET: " + SCodeUtil.elementName(outClass) + " outenv: " + FGraph.printGraphPathStr(outEnv) + "\n"); | ||
| 482 | 1835425 | then | |
| 483 | (outCache,outClass,outEnv); | ||
| 484 | end matchcontinue; | ||
| 485 | // print("Lookup C2: " + " outenv: " + FGraph.printGraphPathStr(outEnv) + "\n"); | ||
| 486 | end lookupClass; | ||
| 487 | |||
| 488 | public function lookupClassIdent "Like lookupClass, but takes a String as ident for input (avoids Absyn.IDENT() creation)" | ||
| 489 | input FCore.Cache inCache; | ||
| 490 | input FCore.Graph inEnv "Where to look"; | ||
| 491 | input String ident; | ||
| 492 | input Option<SourceInfo> inInfo = NONE(); | ||
| 493 | output FCore.Cache outCache; | ||
| 494 | output SCode.Element outClass; | ||
| 495 | output FCore.Graph outEnv; | ||
| 496 | algorithm | ||
| 497 | 815999 | (outCache,outClass,outEnv) := lookupClassInEnv(inCache, inEnv, ident, {}, Mutable.create(false), inInfo); | |
| 498 | end lookupClassIdent; | ||
| 499 | |||
| 500 | protected function lookupClass1 "help function to lookupClass, does all the work." | ||
| 501 | input FCore.Cache inCache; | ||
| 502 | input FCore.Graph inEnv; | ||
| 503 | input Absyn.Path inPath "The path of the class to lookup"; | ||
| 504 | input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion."; | ||
| 505 | input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment"; | ||
| 506 | input Option<SourceInfo> inInfo; | ||
| 507 | output FCore.Cache outCache; | ||
| 508 | output SCode.Element outClass; | ||
| 509 | output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)"; | ||
| 510 | output FCore.Scope outPrevFrames; | ||
| 511 | protected | ||
| 512 | Integer errors = Error.getNumErrorMessages(); | ||
| 513 | algorithm | ||
| 514 | try | ||
| 515 | 1972668 | (outCache, outClass, outEnv, outPrevFrames) := lookupClass2(inCache, inEnv, | |
| 516 | inPath, inPrevFrames, inState, inInfo); | ||
| 517 | else | ||
| 518 |
5/6✗ Branch 0 not taken.
✓ Branch 1 taken 137243 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 137220 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 22 times.
|
137243 | if isSome(inInfo) and errors == Error.getNumErrorMessages() then |
| 519 | 3 | Error.addSourceMessage(Error.LOOKUP_ERROR, | |
| 520 | {AbsynUtil.pathString(inPath), FGraph.printGraphPathStr(inEnv)}, | ||
| 521 | Util.getOption(inInfo)); | ||
| 522 | end if; | ||
| 523 | 137243 | fail(); | |
| 524 | end try; | ||
| 525 | end lookupClass1; | ||
| 526 | |||
| 527 | protected function lookupClass2 "help function to lookupClass, does all the work." | ||
| 528 | input FCore.Cache inCache; | ||
| 529 | input FCore.Graph inEnv; | ||
| 530 | input Absyn.Path inPath "The path of the class to lookup"; | ||
| 531 | input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion."; | ||
| 532 | input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment"; | ||
| 533 | input Option<SourceInfo> inInfo; | ||
| 534 | output FCore.Cache outCache; | ||
| 535 | output SCode.Element outClass; | ||
| 536 | output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)"; | ||
| 537 | output FCore.Scope outPrevFrames; | ||
| 538 | algorithm | ||
| 539 | (outCache,outClass,outEnv,outPrevFrames) := match (inCache,inEnv,inPath,inPrevFrames) | ||
| 540 | local | ||
| 541 | FCore.Ref r; | ||
| 542 | FCore.Cache cache; | ||
| 543 | SCode.Element c; | ||
| 544 | FCore.Graph env,env_1,env_2; | ||
| 545 | FCore.Scope prevFrames; | ||
| 546 | Absyn.Path path; | ||
| 547 | String id,pack; | ||
| 548 | Option<FCore.Ref> optFrame; | ||
| 549 | |||
| 550 | // Fully qualified names are looked up in top scope. With previous frames remembered. | ||
| 551 | case (cache,env,Absyn.FULLYQUALIFIED(path),{}) | ||
| 552 | algorithm | ||
| 553 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 456301 times.
|
456301 | r::prevFrames := listReverse(FGraph.currentScope(env)); |
| 554 | 456301 | Mutable.update(inState,true); | |
| 555 | 456301 | env := FGraph.setScope(env, {r}); | |
| 556 | 456301 | (cache,c,env_1,prevFrames) := lookupClass2(cache,env,path,prevFrames,inState,inInfo); | |
| 557 | then | ||
| 558 | (cache,c,env_1,prevFrames); | ||
| 559 | |||
| 560 | // Qualified names are handled in a special function in order to avoid infinite recursion. | ||
| 561 | case (cache,env,(Absyn.QUALIFIED(name = pack,path = path)),prevFrames) | ||
| 562 | algorithm | ||
| 563 | 1729557 | (optFrame,prevFrames) := lookupPrevFrames(pack,prevFrames); | |
| 564 | 1729557 | (cache,c,env_2,prevFrames) := lookupClassQualified(cache,env,pack,path,optFrame,prevFrames,inState,inInfo); | |
| 565 | then | ||
| 566 | (cache,c,env_2,prevFrames); | ||
| 567 | |||
| 568 | // Simple names | ||
| 569 | case (cache,env,Absyn.IDENT(name = id),prevFrames) | ||
| 570 | algorithm | ||
| 571 | 2076909 | (cache,c,env_1,prevFrames) := lookupClassInEnv(cache, env, id, prevFrames, inState, inInfo); | |
| 572 | then | ||
| 573 | (cache,c,env_1,prevFrames); | ||
| 574 | |||
| 575 | /* | ||
| 576 | case (cache,env,p,_,_,_) | ||
| 577 | algorithm | ||
| 578 | Debug.traceln("lookupClass failed " + AbsynUtil.pathString(p) + " " + FGraph.printGraphPathStr(env)); | ||
| 579 | then fail(); | ||
| 580 | */ | ||
| 581 | end match; | ||
| 582 | end lookupClass2; | ||
| 583 | |||
| 584 | protected function lookupClassQualified | ||
| 585 | input FCore.Cache inCache; | ||
| 586 | input FCore.Graph inEnv; | ||
| 587 | input String id; | ||
| 588 | input Absyn.Path path; | ||
| 589 | input Option<FCore.Ref> inOptFrame; | ||
| 590 | input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion."; | ||
| 591 | input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment"; | ||
| 592 | input Option<SourceInfo> inInfo; | ||
| 593 | output FCore.Cache outCache; | ||
| 594 | output SCode.Element outClass; | ||
| 595 | output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)"; | ||
| 596 | output FCore.Scope outPrevFrames; | ||
| 597 | algorithm | ||
| 598 | (outCache,outClass,outEnv,outPrevFrames) := match (inCache, inEnv, inOptFrame, inPrevFrames) | ||
| 599 | local | ||
| 600 | SCode.Element c; | ||
| 601 | FCore.Cache cache; | ||
| 602 | FCore.Graph env; | ||
| 603 | FCore.Scope prevFrames; | ||
| 604 | FCore.Ref frame; | ||
| 605 | Option<FCore.Ref> optFrame; | ||
| 606 | |||
| 607 | // Qualified names first identifier cached in previous frames | ||
| 608 | case (cache, env, SOME(frame), prevFrames) | ||
| 609 | algorithm | ||
| 610 | 667999 | Mutable.update(inState,true); | |
| 611 | 667999 | env := FGraph.pushScopeRef(env, frame); | |
| 612 | 667999 | (cache,c,env,prevFrames) := lookupClass2(cache,env,path,prevFrames,inState,inInfo); | |
| 613 | then | ||
| 614 | (cache,c,env,prevFrames); | ||
| 615 | |||
| 616 | // Qualified names in package and non-package | ||
| 617 | case (cache, env, NONE(), _) | ||
| 618 | algorithm | ||
| 619 | 1061558 | (cache,c,env,prevFrames) := lookupClassInEnv(cache,env,id,{},inState,inInfo); | |
| 620 | 1048384 | (optFrame,prevFrames) := lookupPrevFrames(id,prevFrames); | |
| 621 | 1048384 | (cache,c,env,prevFrames) := lookupClassQualified2(cache,env,path,c,optFrame,prevFrames,inState,inInfo); | |
| 622 | then | ||
| 623 | (cache,c,env,prevFrames); | ||
| 624 | |||
| 625 | end match; | ||
| 626 | end lookupClassQualified; | ||
| 627 | |||
| 628 | protected function lookupClassQualified2 | ||
| 629 | input FCore.Cache inCache; | ||
| 630 | input FCore.Graph inEnv; | ||
| 631 | input Absyn.Path path; | ||
| 632 | input SCode.Element inC; | ||
| 633 | input Option<FCore.Ref> optFrame; | ||
| 634 | input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion."; | ||
| 635 | input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in previous frames of the environment"; | ||
| 636 | input Option<SourceInfo> inInfo; | ||
| 637 | output FCore.Cache outCache; | ||
| 638 | output SCode.Element outClass; | ||
| 639 | output FCore.Graph outEnv "The environment in which the class was found (not the environment inside the class)"; | ||
| 640 | output FCore.Scope outPrevFrames; | ||
| 641 | algorithm | ||
| 642 | (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inEnv, inC, optFrame, inPrevFrames) | ||
| 643 | local | ||
| 644 | FCore.Cache cache; | ||
| 645 | FCore.Graph env; | ||
| 646 | FCore.Scope prevFrames; | ||
| 647 | FCore.Ref frame; | ||
| 648 | SCode.Restriction restr; | ||
| 649 | ClassInf.State ci_state; | ||
| 650 | SCode.Encapsulated encflag; | ||
| 651 | String id; | ||
| 652 | SCode.Element c; | ||
| 653 | FCore.Ref r; | ||
| 654 | DAE.Mod mod; | ||
| 655 | |||
| 656 | case (cache, env, _, SOME(frame), prevFrames) | ||
| 657 | algorithm | ||
| 658 | 85055 | env := FGraph.pushScopeRef(env, frame); | |
| 659 | 85055 | (cache,c,env,prevFrames) := lookupClass2(cache,env,path,prevFrames,inState,inInfo); | |
| 660 | // fprintln(Flags.INST_TRACE, "LOOKUP CLASS QUALIFIED FRAME: " + FGraph.printGraphPathStr(env) + " path: " + AbsynUtil.pathString(path) + " class: " + SCodeDump.shortElementStr(c)); | ||
| 661 | then (cache,c,env,prevFrames); | ||
| 662 | |||
| 663 | // class is an instance of a component | ||
| 664 | case (cache, env, SCode.CLASS(name=id), NONE(), _) | ||
| 665 | algorithm | ||
| 666 | 963329 | r := FNode.child(FGraph.lastScopeRef(env), id); | |
| 667 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 963329 times.
✓ Branch 3 taken 963143 times.
✓ Branch 4 taken 186 times.
|
963329 | FCore.CL(status = FCore.CLS_INSTANCE(_)) := FNode.refData(r); |
| 668 | // fetch the env | ||
| 669 | 186 | (cache, env) := Inst.getCachedInstance(cache, env, id, r); | |
| 670 | 186 | (cache,c,env,prevFrames) := lookupClass2(cache,env,path,{},inState,inInfo); | |
| 671 | then (cache,c,env,prevFrames); | ||
| 672 | |||
| 673 | case (cache, env, SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=restr), NONE(), _) | ||
| 674 | algorithm | ||
| 675 | 963143 | env := FGraph.openScope(env, encflag, id, FGraph.restrictionToScopeType(restr)); | |
| 676 | 963143 | ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env)); | |
| 677 | // fprintln(Flags.INST_TRACE, "LOOKUP CLASS QUALIFIED PARTIALICD: " + FGraph.printGraphPathStr(env) + " path: " + AbsynUtil.pathString(path) + " class: " + SCodeDump.shortElementStr(c)); | ||
| 678 | 963143 | mod := Mod.getClassModifier(inEnv, id); | |
| 679 | 963143 | (cache,env,_,_,_) := | |
| 680 | Inst.partialInstClassIn( | ||
| 681 | cache,env,InnerOuter.emptyInstHierarchy, | ||
| 682 | mod, DAE.NOPRE(), | ||
| 683 | ci_state, inC, SCode.PUBLIC(), {}, 0); | ||
| 684 | |||
| 685 | 963063 | checkPartialScope(env, inEnv, cache, inInfo); | |
| 686 | 963063 | (cache,c,env,prevFrames) := lookupClass2(cache,env,path,{},inState,inInfo); | |
| 687 | then (cache,c,env,prevFrames); | ||
| 688 | |||
| 689 | end matchcontinue; | ||
| 690 | end lookupClassQualified2; | ||
| 691 | |||
| 692 | protected function checkPartialScope | ||
| 693 | input FCore.Graph inEnv; | ||
| 694 | input FCore.Graph inParentEnv; | ||
| 695 | input FCore.Cache inCache; | ||
| 696 | input Option<SourceInfo> inInfo; | ||
| 697 | protected | ||
| 698 | SCode.Element el; | ||
| 699 | DAE.Prefix pre; | ||
| 700 | String name, pre_str, cc_str; | ||
| 701 | SourceInfo cls_info, pre_info, info; | ||
| 702 | algorithm | ||
| 703 |
6/8✗ Branch 0 not taken.
✓ Branch 1 taken 963063 times.
✓ Branch 2 taken 403750 times.
✓ Branch 3 taken 559313 times.
✓ Branch 5 taken 403749 times.
✓ Branch 6 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
|
963063 | if isSome(inInfo) and FGraph.isPartialScope(inEnv) and |
| 704 | Config.languageStandardAtLeast(Config.LanguageStandard._3_2) then | ||
| 705 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
|
1 | FCore.N(data = FCore.CL(e = el, pre = pre)) := |
| 706 | FNode.fromRef(FGraph.lastScopeRef(inEnv)); | ||
| 707 | 1 | name := SCodeUtil.elementName(el); | |
| 708 | |||
| 709 |
2/4✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
|
1 | if FGraph.graphPrefixOf(inParentEnv, inEnv) and not |
| 710 | PrefixUtil.isNoPrefix(pre) then | ||
| 711 | ✗ | pre_str := PrefixUtil.printPrefixStr(pre); | |
| 712 | ✗ | cls_info := SCodeUtil.elementInfo(el); | |
| 713 | ✗ | pre_info := PrefixUtil.getPrefixInfo(pre); | |
| 714 | ✗ | cc_str := getConstrainingClass(el, FGraph.stripLastScopeRef(inEnv), inCache); | |
| 715 | ✗ | Error.addMultiSourceMessage(Error.USE_OF_PARTIAL_CLASS, | |
| 716 | {pre_str, name, cc_str}, {cls_info, pre_info}); | ||
| 717 | ✗ | fail(); | |
| 718 | else | ||
| 719 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
|
1 | SOME(info) := inInfo; |
| 720 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 | if not Config.getGraphicsExpMode() then |
| 721 | 1 | Error.addSourceMessage(Error.LOOKUP_IN_PARTIAL_CLASS, {name}, info); | |
| 722 | end if; | ||
| 723 | // We should fail here, but the MSL 3.2.1 contains such errors. So just | ||
| 724 | // print an error and continue anyway for now. | ||
| 725 | end if; | ||
| 726 | end if; | ||
| 727 | end checkPartialScope; | ||
| 728 | |||
| 729 | protected function getConstrainingClass | ||
| 730 | input SCode.Element inClass; | ||
| 731 | input FCore.Graph inEnv; | ||
| 732 | input FCore.Cache inCache; | ||
| 733 | output String outPath; | ||
| 734 | algorithm | ||
| 735 | outPath := matchcontinue inClass | ||
| 736 | local | ||
| 737 | Absyn.Path cc_path; | ||
| 738 | Absyn.TypeSpec ts; | ||
| 739 | SCode.Element el; | ||
| 740 | FCore.Graph env; | ||
| 741 | |||
| 742 | case SCode.CLASS(prefixes = SCode.PREFIXES(replaceablePrefix = | ||
| 743 | SCode.REPLACEABLE(cc = SOME(SCode.CONSTRAINCLASS(constrainingClass = cc_path))))) | ||
| 744 | ✗ | then AbsynUtil.pathString(cc_path); | |
| 745 | |||
| 746 | case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = ts)) | ||
| 747 | algorithm | ||
| 748 | ✗ | (_, el, env) := lookupClass(inCache, inEnv, AbsynUtil.typeSpecPath(ts)); | |
| 749 | ✗ | then | |
| 750 | getConstrainingClass(el, env, inCache); | ||
| 751 | |||
| 752 | ✗ | else FGraph.printGraphPathStr(inEnv) + "." + SCodeUtil.elementName(inClass); | |
| 753 | end matchcontinue; | ||
| 754 | end getConstrainingClass; | ||
| 755 | |||
| 756 | protected function lookupPrevFrames | ||
| 757 | input String id; | ||
| 758 | input FCore.Scope inPrevFrames; | ||
| 759 | output Option<FCore.Ref> outFrame; | ||
| 760 | output FCore.Scope outPrevFrames; | ||
| 761 | algorithm | ||
| 762 | (outFrame,outPrevFrames) := matchcontinue inPrevFrames | ||
| 763 | local | ||
| 764 | String sid; | ||
| 765 | FCore.Scope prevFrames; | ||
| 766 | FCore.Ref ref; | ||
| 767 | |||
| 768 | case ref::prevFrames | ||
| 769 | algorithm | ||
| 770 |
2/2✓ Branch 1 taken 117938 times.
✓ Branch 2 taken 2036366 times.
|
2154304 | false := FNode.isRefTop(ref); |
| 771 | 2036366 | sid := FNode.refName(ref); | |
| 772 |
4/4✓ Branch 0 taken 1088124 times.
✓ Branch 1 taken 948242 times.
✓ Branch 3 taken 831949 times.
✓ Branch 4 taken 256175 times.
|
2036366 | true := id == sid; |
| 773 | then | ||
| 774 | (SOME(ref),prevFrames); | ||
| 775 | |||
| 776 | else (NONE(), {}); | ||
| 777 | |||
| 778 | end matchcontinue; | ||
| 779 | end lookupPrevFrames; | ||
| 780 | |||
| 781 | protected function lookupQualifiedImportedVarInFrame | ||
| 782 | "author: PA | ||
| 783 | Looking up variables (constants) imported using qualified imports, | ||
| 784 | i.e. import Modelica.Constants.PI;" | ||
| 785 | input list<Absyn.Import> inImports; | ||
| 786 | input SCode.Ident ident; | ||
| 787 | output DAE.ComponentRef outCref; | ||
| 788 | algorithm | ||
| 789 | outCref := matchcontinue inImports | ||
| 790 | local | ||
| 791 | String id; | ||
| 792 | list<Absyn.Import> rest; | ||
| 793 | Absyn.Path path; | ||
| 794 | |||
| 795 | // For imported simple name, e.g. A, not possible to assert sub-path package | ||
| 796 | case Absyn.QUAL_IMPORT(path = path) :: _ | ||
| 797 | algorithm | ||
| 798 | ✗ | id := AbsynUtil.pathLastIdent(path); | |
| 799 | ✗ | true := id == ident; | |
| 800 | ✗ | then ComponentReference.pathToCref(path); | |
| 801 | |||
| 802 | // Named imports, e.g. import A = B.C; | ||
| 803 | case Absyn.NAMED_IMPORT(name = id,path = path) :: _ | ||
| 804 | algorithm | ||
| 805 |
4/4✓ Branch 0 taken 122838 times.
✓ Branch 1 taken 799484 times.
✓ Branch 3 taken 31189 times.
✓ Branch 4 taken 91649 times.
|
922322 | true := id == ident; |
| 806 | 91649 | then ComponentReference.pathToCref(path); | |
| 807 | |||
| 808 | // Check next frame. | ||
| 809 | 830673 | case _ :: rest then lookupQualifiedImportedVarInFrame(rest, ident); | |
| 810 | end matchcontinue; | ||
| 811 | end lookupQualifiedImportedVarInFrame; | ||
| 812 | |||
| 813 | protected function moreLookupUnqualifiedImportedVarInFrame | ||
| 814 | "Helper function for lookup_unqualified_imported_var_in_frame. Returns | ||
| 815 | true if there are unqualified imports that matches a sought constant." | ||
| 816 | input FCore.Cache inCache; | ||
| 817 | input list<Absyn.Import> inImports; | ||
| 818 | input FCore.Graph inEnv; | ||
| 819 | input SCode.Ident inIdent; | ||
| 820 | output FCore.Cache outCache; | ||
| 821 | output Boolean outBoolean; | ||
| 822 | algorithm | ||
| 823 | (outCache,outBoolean) := matchcontinue (inCache,inImports,inEnv,inIdent) | ||
| 824 | local | ||
| 825 | FCore.Ref f; | ||
| 826 | String ident; | ||
| 827 | Boolean res; | ||
| 828 | FCore.Graph env; | ||
| 829 | FCore.Scope prevFrames; | ||
| 830 | list<Absyn.Import> rest; | ||
| 831 | FCore.Cache cache; | ||
| 832 | DAE.ComponentRef cref; | ||
| 833 | Absyn.Path path; | ||
| 834 | |||
| 835 | case (cache,Absyn.UNQUAL_IMPORT(path = path) :: _,env,ident) | ||
| 836 | algorithm | ||
| 837 | ✗ | f::prevFrames := listReverse(FGraph.currentScope(env)); | |
| 838 | ✗ | cref := ComponentReference.pathToCref(path); | |
| 839 | ✗ | cref := ComponentReference.crefPrependIdent(cref,ident,{},DAE.T_UNKNOWN_DEFAULT); | |
| 840 | ✗ | env := FGraph.setScope(env, {f}); | |
| 841 | ✗ | (cache,_,_,_,_,_,_,_,_) := lookupVarInPackages(cache,env,cref,prevFrames,Mutable.create(false)); | |
| 842 | ✗ | then | |
| 843 | (cache,true); | ||
| 844 | |||
| 845 | // look into the parent scope | ||
| 846 | case (cache,(_ :: rest),env,ident) | ||
| 847 | algorithm | ||
| 848 | ✗ | (cache, res) := moreLookupUnqualifiedImportedVarInFrame(cache, rest, env, ident); | |
| 849 | then | ||
| 850 | (cache, res); | ||
| 851 | |||
| 852 | // we reached the end, no more lookup | ||
| 853 | 66 | case (cache,{},_,_) then (cache, false); | |
| 854 | |||
| 855 | end matchcontinue; | ||
| 856 | end moreLookupUnqualifiedImportedVarInFrame; | ||
| 857 | |||
| 858 | protected function lookupUnqualifiedImportedVarInFrame "Find a variable from an unqualified import locally in a frame" | ||
| 859 | input FCore.Cache inCache; | ||
| 860 | input list<Absyn.Import> inImports; | ||
| 861 | input FCore.Graph inEnv; | ||
| 862 | input SCode.Ident inIdent; | ||
| 863 | output FCore.Cache outCache; | ||
| 864 | output FCore.Graph outClassEnv; | ||
| 865 | output DAE.Attributes outAttributes; | ||
| 866 | output DAE.Type outType; | ||
| 867 | output DAE.Binding outBinding; | ||
| 868 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 869 | output Boolean outBoolean; | ||
| 870 | output InstTypes.SplicedExpData splicedExpData; | ||
| 871 | output FCore.Graph outComponentEnv; | ||
| 872 | output String name; | ||
| 873 | algorithm | ||
| 874 | (outCache,outClassEnv,outAttributes,outType,outBinding,constOfForIteratorRange,outBoolean,splicedExpData,outComponentEnv,name):= | ||
| 875 | matchcontinue (inCache,inImports,inEnv,inIdent) | ||
| 876 | local | ||
| 877 | FCore.Ref f; | ||
| 878 | DAE.ComponentRef cref; | ||
| 879 | String ident; | ||
| 880 | Boolean more,unique; | ||
| 881 | FCore.Graph env,classEnv,componentEnv,env2; | ||
| 882 | FCore.Scope prevFrames; | ||
| 883 | DAE.Attributes attr; | ||
| 884 | DAE.Type ty; | ||
| 885 | DAE.Binding bind; | ||
| 886 | list<Absyn.Import> rest; | ||
| 887 | FCore.Cache cache; | ||
| 888 | Absyn.Path path; | ||
| 889 | Option<DAE.Const> cnstForRange; | ||
| 890 | |||
| 891 | // unique | ||
| 892 | case (cache,Absyn.UNQUAL_IMPORT(path = path) :: rest,env,ident) | ||
| 893 | algorithm | ||
| 894 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 700 times.
|
700 | f::prevFrames := listReverse(FGraph.currentScope(env)); |
| 895 | 700 | cref := ComponentReference.pathToCref(path); | |
| 896 | 700 | cref := ComponentReference.crefPrependIdent(cref,ident,{},DAE.T_UNKNOWN_DEFAULT); | |
| 897 | 700 | env2 := FGraph.setScope(env, {f}); | |
| 898 | 700 | (cache,classEnv,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env2,cref,prevFrames,Mutable.create(false)); | |
| 899 | 66 | (cache,more) := moreLookupUnqualifiedImportedVarInFrame(cache, rest, env, ident); | |
| 900 | 66 | unique := boolNot(more); | |
| 901 | 66 | then | |
| 902 | (cache,classEnv,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name); | ||
| 903 | |||
| 904 | // search in the parent scopes | ||
| 905 | case (cache,_ :: rest,env,ident) | ||
| 906 | algorithm | ||
| 907 | 634 | (cache,classEnv,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name) := lookupUnqualifiedImportedVarInFrame(cache, rest, env, ident); | |
| 908 | then | ||
| 909 | (cache,classEnv,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name); | ||
| 910 | end matchcontinue; | ||
| 911 | end lookupUnqualifiedImportedVarInFrame; | ||
| 912 | |||
| 913 | protected function lookupQualifiedImportedClassInFrame | ||
| 914 | "Helper function to lookupQualifiedImportedClassInEnv." | ||
| 915 | input FCore.Cache inCache; | ||
| 916 | input list<Absyn.Import> inImport; | ||
| 917 | input FCore.Graph inEnv; | ||
| 918 | input SCode.Ident inIdent; | ||
| 919 | input Mutable<Boolean> inState; | ||
| 920 | input Option<SourceInfo> inInfo; | ||
| 921 | output FCore.Cache outCache; | ||
| 922 | output SCode.Element outClass; | ||
| 923 | output FCore.Graph outEnv; | ||
| 924 | output FCore.Scope outPrevFrames; | ||
| 925 | algorithm | ||
| 926 | (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inImport, inEnv, inIdent) | ||
| 927 | local | ||
| 928 | FCore.Ref r; | ||
| 929 | SCode.Element c; | ||
| 930 | FCore.Graph env_1,env; | ||
| 931 | FCore.Scope prevFrames; | ||
| 932 | String id,ident; | ||
| 933 | list<Absyn.Import> rest; | ||
| 934 | Absyn.Path path; | ||
| 935 | FCore.Cache cache; | ||
| 936 | |||
| 937 | case (cache, Absyn.QUAL_IMPORT(path = Absyn.IDENT(name = id)) :: _, env, ident) | ||
| 938 | algorithm | ||
| 939 | ✗ | true := id == ident "For imported paths A, not possible to assert sub-path package"; | |
| 940 | ✗ | Mutable.update(inState,true); | |
| 941 | ✗ | r::prevFrames := listReverse(FGraph.currentScope(env)); | |
| 942 | ✗ | env := FGraph.setScope(env, {r}); | |
| 943 | ✗ | (cache,c,env_1,prevFrames) := lookupClassInEnv(cache,env,id,prevFrames,Mutable.create(false),inInfo); | |
| 944 | then | ||
| 945 | (cache,c,env_1,prevFrames); | ||
| 946 | |||
| 947 | case (cache, Absyn.QUAL_IMPORT(path = path) :: _, env, ident) | ||
| 948 | algorithm | ||
| 949 | ✗ | id := AbsynUtil.pathLastIdent(path) "For imported path A.B.C, assert A.B is package" ; | |
| 950 | ✗ | true := id == ident; | |
| 951 | ✗ | Mutable.update(inState,true); | |
| 952 | |||
| 953 | ✗ | r::prevFrames := listReverse(FGraph.currentScope(env)); | |
| 954 | ✗ | env := FGraph.setScope(env, {r}); | |
| 955 | // strippath = AbsynUtil.stripLast(path); | ||
| 956 | // (cache,c2,env_1,_) = lookupClass2(cache,{fr},strippath,prevFrames,Mutable.create(false),true); | ||
| 957 | ✗ | (cache,c,env_1,prevFrames) := lookupClass2(cache,env,path,prevFrames,Mutable.create(false),inInfo); | |
| 958 | then | ||
| 959 | (cache,c,env_1,prevFrames); | ||
| 960 | |||
| 961 | case (cache, Absyn.NAMED_IMPORT(name = id,path = path) :: _, env, ident) | ||
| 962 | algorithm | ||
| 963 |
4/4✓ Branch 0 taken 170841 times.
✓ Branch 1 taken 2061641 times.
✓ Branch 3 taken 54973 times.
✓ Branch 4 taken 115868 times.
|
2232482 | true := id == ident "Named imports"; |
| 964 | 115868 | Mutable.update(inState,true); | |
| 965 | |||
| 966 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 115868 times.
|
115868 | r::prevFrames := listReverse(FGraph.currentScope(env)); |
| 967 | 115868 | env := FGraph.setScope(env, {r}); | |
| 968 | // strippath = AbsynUtil.stripLast(path); | ||
| 969 | // Debug.traceln("named import " + id + " is " + AbsynUtil.pathString(path)); | ||
| 970 | // (cache,c2,env_1,prevFrames) = lookupClass2(cache,{fr},strippath,prevFrames,Mutable.create(false),true); | ||
| 971 | 115868 | (cache,c,env_1,prevFrames) := lookupClass2(cache,env,path,prevFrames,Mutable.create(false),inInfo); | |
| 972 | then | ||
| 973 | (cache,c,env_1,prevFrames); | ||
| 974 | |||
| 975 | case (cache, _ :: rest, env, ident) | ||
| 976 | algorithm | ||
| 977 | 2116658 | (cache,c,env_1,prevFrames) := lookupQualifiedImportedClassInFrame(cache,rest,env,ident,inState,inInfo); | |
| 978 | then | ||
| 979 | (cache,c,env_1,prevFrames); | ||
| 980 | |||
| 981 | end matchcontinue; | ||
| 982 | end lookupQualifiedImportedClassInFrame; | ||
| 983 | |||
| 984 | protected function moreLookupUnqualifiedImportedClassInFrame | ||
| 985 | "Helper function for lookupUnqualifiedImportedClassInFrame" | ||
| 986 | input FCore.Cache inCache; | ||
| 987 | input list<Absyn.Import> inImports; | ||
| 988 | input FCore.Graph inEnv; | ||
| 989 | input SCode.Ident inIdent; | ||
| 990 | output FCore.Cache outCache; | ||
| 991 | output Boolean outBoolean; | ||
| 992 | algorithm | ||
| 993 | (outCache,outBoolean) := matchcontinue (inCache,inImports,inEnv,inIdent) | ||
| 994 | local | ||
| 995 | SCode.Element c; | ||
| 996 | String id,ident; | ||
| 997 | SCode.Encapsulated encflag; | ||
| 998 | Boolean res; | ||
| 999 | SCode.Restriction restr; | ||
| 1000 | FCore.Graph env_1,env2,env; | ||
| 1001 | ClassInf.State ci_state; | ||
| 1002 | Absyn.Path path; | ||
| 1003 | list<Absyn.Import> rest; | ||
| 1004 | FCore.Cache cache; | ||
| 1005 | FCore.Ref r; | ||
| 1006 | DAE.Mod mod; | ||
| 1007 | |||
| 1008 | // Not found, instantiate | ||
| 1009 | case (cache,Absyn.UNQUAL_IMPORT(path = path) :: _,env,ident) | ||
| 1010 | algorithm | ||
| 1011 | ✗ | env := FGraph.topScope(env); | |
| 1012 | ✗ | (cache,(c as SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=restr)),env_1) := lookupClass(cache, env, path); | |
| 1013 | ✗ | env2 := FGraph.openScope(env_1, encflag, id, FGraph.restrictionToScopeType(restr)); | |
| 1014 | ✗ | ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env2)); | |
| 1015 | // fprintln(Flags.INST_TRACE, "LOOKUP MORE UNQUALIFIED IMPORTED ICD: " + FGraph.printGraphPathStr(env) + "." + ident); | ||
| 1016 | ✗ | mod := Mod.getClassModifier(env_1, id); | |
| 1017 | ✗ | (cache, env, _,_,_) := Inst.partialInstClassIn(cache, env2, InnerOuter.emptyInstHierarchy, mod, DAE.NOPRE(), ci_state, c, SCode.PUBLIC(), {}, 0); | |
| 1018 | ✗ | r := FGraph.lastScopeRef(env); | |
| 1019 | ✗ | env := FGraph.setScope(env, {r}); | |
| 1020 | ✗ | (cache,_,_) := lookupClass(cache, env, Absyn.IDENT(ident)); | |
| 1021 | ✗ | then | |
| 1022 | (cache, true); | ||
| 1023 | |||
| 1024 | // Look in the parent scope | ||
| 1025 | case (cache,_ :: rest,env,ident) | ||
| 1026 | algorithm | ||
| 1027 | ✗ | (cache, res) := moreLookupUnqualifiedImportedClassInFrame(cache, rest, env, ident); | |
| 1028 | then | ||
| 1029 | (cache, res); | ||
| 1030 | |||
| 1031 | 1000 | case (cache,{},_,_) then (cache,false); | |
| 1032 | |||
| 1033 | end matchcontinue; | ||
| 1034 | end moreLookupUnqualifiedImportedClassInFrame; | ||
| 1035 | |||
| 1036 | protected function lookupUnqualifiedImportedClassInFrame | ||
| 1037 | "Finds a class from an unqualified import locally in a frame" | ||
| 1038 | input FCore.Cache inCache; | ||
| 1039 | input list<Absyn.Import> inImports; | ||
| 1040 | input FCore.Graph inEnv; | ||
| 1041 | input SCode.Ident inIdent; | ||
| 1042 | input Option<SourceInfo> inInfo; | ||
| 1043 | output FCore.Cache outCache; | ||
| 1044 | output SCode.Element outClass; | ||
| 1045 | output FCore.Graph outEnv; | ||
| 1046 | output FCore.Scope outPrevFrames; | ||
| 1047 | output Boolean outBoolean; | ||
| 1048 | algorithm | ||
| 1049 | (outCache,outClass,outEnv,outPrevFrames,outBoolean) := matchcontinue (inCache,inImports,inEnv,inIdent) | ||
| 1050 | local | ||
| 1051 | FCore.Ref r; | ||
| 1052 | SCode.Element c,c_1; | ||
| 1053 | String id,ident; | ||
| 1054 | SCode.Encapsulated encflag; | ||
| 1055 | Boolean more,unique; | ||
| 1056 | SCode.Restriction restr; | ||
| 1057 | FCore.Graph env_1,env2,env, env3; | ||
| 1058 | FCore.Scope prevFrames; | ||
| 1059 | ClassInf.State ci_state; | ||
| 1060 | Absyn.Path path; | ||
| 1061 | list<Absyn.Import> rest; | ||
| 1062 | FCore.Cache cache; | ||
| 1063 | DAE.Mod mod; | ||
| 1064 | |||
| 1065 | // Not in cache, instantiate, unique | ||
| 1066 | case (cache,Absyn.UNQUAL_IMPORT(path = path) :: rest,env,ident) | ||
| 1067 | algorithm | ||
| 1068 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1627 times.
|
1627 | r::prevFrames := listReverse(FGraph.currentScope(env)); |
| 1069 | 1627 | env3 := FGraph.setScope(env, {r}); | |
| 1070 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1627 times.
|
1627 | (cache,(c as |
| 1071 | SCode.CLASS(name=id,encapsulatedPrefix=encflag,restriction=restr)),env_1,prevFrames) | ||
| 1072 | := lookupClass2(cache,env3,path,prevFrames,Mutable.create(false),inInfo); | ||
| 1073 | 1627 | env2 := FGraph.openScope(env_1, encflag, id, FGraph.restrictionToScopeType(restr)); | |
| 1074 | 1627 | ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env2)); | |
| 1075 | // fprintln(Flags.INST_TRACE, "LOOKUP UNQUALIFIED IMPORTED ICD: " + FGraph.printGraphPathStr(env) + "." + ident); | ||
| 1076 | 1627 | mod := Mod.getClassModifier(env_1, id); | |
| 1077 | 1627 | (cache,env2,_,_,_) := | |
| 1078 | Inst.partialInstClassIn(cache, env2, InnerOuter.emptyInstHierarchy, | ||
| 1079 | mod, DAE.NOPRE(), ci_state, c, SCode.PUBLIC(), {}, 0); | ||
| 1080 | // Restrict import to the imported scope only, not its parents, thus {f} below | ||
| 1081 | 1627 | (cache,c_1,env2,prevFrames) := lookupClassInEnv(cache,env2,ident,prevFrames,Mutable.create(true),inInfo) "Restrict import to the imported scope only, not its parents..." ; | |
| 1082 | 1000 | (cache,more) := moreLookupUnqualifiedImportedClassInFrame(cache, rest, env, ident); | |
| 1083 | 1000 | unique := boolNot(more); | |
| 1084 | 1000 | then | |
| 1085 | (cache,c_1,env2,prevFrames,unique); | ||
| 1086 | |||
| 1087 | // Look in the parent scope | ||
| 1088 | case (cache,_ :: rest,env,ident) | ||
| 1089 | algorithm | ||
| 1090 | 627 | (cache,c,env_1,prevFrames,unique) := lookupUnqualifiedImportedClassInFrame(cache, rest, env, ident,inInfo); | |
| 1091 | then | ||
| 1092 | (cache,c,env_1,prevFrames,unique); | ||
| 1093 | |||
| 1094 | end matchcontinue; | ||
| 1095 | end lookupUnqualifiedImportedClassInFrame; | ||
| 1096 | |||
| 1097 | public function lookupRecordConstructorClass | ||
| 1098 | "Searches for a record constructor implicitly defined by a record class." | ||
| 1099 | input FCore.Cache inCache; | ||
| 1100 | input FCore.Graph inEnv; | ||
| 1101 | input Absyn.Path inPath; | ||
| 1102 | output FCore.Cache outCache; | ||
| 1103 | output SCode.Element outClass; | ||
| 1104 | output FCore.Graph outEnv; | ||
| 1105 | algorithm | ||
| 1106 | (outCache,outClass,outEnv) := match (inCache,inEnv,inPath) | ||
| 1107 | local | ||
| 1108 | SCode.Element c; | ||
| 1109 | FCore.Graph env,env_1; | ||
| 1110 | Absyn.Path path; | ||
| 1111 | FCore.Cache cache; | ||
| 1112 | |||
| 1113 | case (cache,env,path) | ||
| 1114 | algorithm | ||
| 1115 | 13 | (cache,c,env_1) := lookupClass(cache,env, path); | |
| 1116 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
|
13 | SCode.CLASS( restriction=SCode.R_RECORD(_)) := c; |
| 1117 | 13 | (cache,_,c) := buildRecordConstructorClass(cache,env_1,c); | |
| 1118 |
1/2✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
|
13 | then |
| 1119 | (cache,c,env_1); | ||
| 1120 | end match; | ||
| 1121 | end lookupRecordConstructorClass; | ||
| 1122 | |||
| 1123 | public function lookupConnectorVar | ||
| 1124 | "Simplified lookup of connector references. The lookup will stop if it finds a | ||
| 1125 | deleted component, so if status is VAR_DELETED() then attr and ty will belong | ||
| 1126 | to the deleted component instead of the looked for component." | ||
| 1127 | input FCore.Graph env; | ||
| 1128 | input DAE.ComponentRef cr; | ||
| 1129 | input Boolean firstId = true; | ||
| 1130 | output DAE.Attributes attr; | ||
| 1131 | output DAE.Type ty; | ||
| 1132 | output FCore.Status status; | ||
| 1133 | output Boolean isExpandable = false; | ||
| 1134 | protected | ||
| 1135 | FCore.Graph comp_env; | ||
| 1136 | DAE.Attributes parent_attr; | ||
| 1137 | algorithm | ||
| 1138 | (attr, ty, status) := match cr | ||
| 1139 | case DAE.CREF_IDENT() | ||
| 1140 | algorithm | ||
| 1141 | 34572 | (DAE.TYPES_VAR(attributes = attr, ty = ty), status, _) := | |
| 1142 | lookupConnectorVar2(env, cr.ident); | ||
| 1143 | 32770 | ty := checkSubscripts(ty, cr.subscriptLst); | |
| 1144 | 32770 | then | |
| 1145 | (attr, ty, status); | ||
| 1146 | |||
| 1147 | case DAE.CREF_QUAL() | ||
| 1148 | algorithm | ||
| 1149 | 40761 | (DAE.TYPES_VAR(attributes = parent_attr, ty = ty), status, comp_env) := | |
| 1150 | lookupConnectorVar2(env, cr.ident); | ||
| 1151 | |||
| 1152 |
2/2✓ Branch 1 taken 40536 times.
✓ Branch 2 taken 225 times.
|
40761 | if FCore.isDeletedComp(status) then |
| 1153 | // Stop if we find a deleted component. | ||
| 1154 | attr := parent_attr; | ||
| 1155 | else | ||
| 1156 | try | ||
| 1157 | 40536 | (attr, ty, status, isExpandable) := | |
| 1158 | lookupConnectorVar(comp_env, cr.componentRef, false); | ||
| 1159 | else | ||
| 1160 |
1/2✓ Branch 1 taken 1802 times.
✗ Branch 2 not taken.
|
1802 | if Types.isExpandableConnector(ty) then |
| 1161 | 1802 | attr := parent_attr; | |
| 1162 | 1802 | isExpandable := true; | |
| 1163 | else | ||
| 1164 | ✗ | fail(); | |
| 1165 | end if; | ||
| 1166 | end try; | ||
| 1167 | |||
| 1168 | // Propagate variability. | ||
| 1169 | 40536 | attr := DAEUtil.setAttrVariability(attr, SCodeUtil.variabilityOr( | |
| 1170 | DAEUtil.getAttrVariability(attr), DAEUtil.getAttrVariability(parent_attr))); | ||
| 1171 | |||
| 1172 | // Use the inner/outer from the first identifier. | ||
| 1173 |
2/2✓ Branch 0 taken 31240 times.
✓ Branch 1 taken 9296 times.
|
40536 | if firstId then |
| 1174 | 31240 | attr := DAEUtil.setAttrInnerOuter(attr, DAEUtil.getAttrInnerOuter(parent_attr)); | |
| 1175 | end if; | ||
| 1176 | end if; | ||
| 1177 | 40761 | then | |
| 1178 | (attr, ty, status); | ||
| 1179 | |||
| 1180 | end match; | ||
| 1181 | end lookupConnectorVar; | ||
| 1182 | |||
| 1183 | protected function lookupConnectorVar2 | ||
| 1184 | "Helper function to lookupConnectorVar." | ||
| 1185 | input FCore.Graph env; | ||
| 1186 | input String name; | ||
| 1187 | output DAE.Var var; | ||
| 1188 | output FCore.Status status; | ||
| 1189 | output FCore.Graph compEnv; | ||
| 1190 | protected | ||
| 1191 | FCore.Scope scope; | ||
| 1192 | FCore.Children ht; | ||
| 1193 | algorithm | ||
| 1194 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 75333 times.
|
75333 | FCore.G(scope = scope) := env; |
| 1195 | |||
| 1196 | // Connectors are not allowed to be constant, so we don't need to look outside | ||
| 1197 | // the local scope. But we do need to check outside implicit scopes, e.g. | ||
| 1198 | // for-scopes. | ||
| 1199 |
1/2✓ Branch 0 taken 75637 times.
✗ Branch 1 not taken.
|
75637 | for r in scope loop |
| 1200 | 75637 | ht := FNode.children(FNode.fromRef(r)); | |
| 1201 | |||
| 1202 | try | ||
| 1203 | 75637 | (var, _, _, status, compEnv) := lookupVar2(ht, name, env); | |
| 1204 |
1/2✓ Branch 0 taken 73531 times.
✗ Branch 1 not taken.
|
73531 | return; |
| 1205 | else | ||
| 1206 | // Continue to the next scope only if the current scope is implicit. | ||
| 1207 |
2/2✓ Branch 1 taken 1802 times.
✓ Branch 2 taken 304 times.
|
2106 | true := FNode.isImplicitRefName(r); |
| 1208 | end try; | ||
| 1209 | end for; | ||
| 1210 | |||
| 1211 | ✗ | fail(); | |
| 1212 | end lookupConnectorVar2; | ||
| 1213 | |||
| 1214 | public function lookupVar | ||
| 1215 | "LS: when looking up qualified component reference, lookupVar only | ||
| 1216 | checks variables when looking for the prefix, i.e. for Constants.PI | ||
| 1217 | where Constants is a package and is implicitly instantiated, PI is not | ||
| 1218 | found since Constants is not a variable (it is a type and/or class). | ||
| 1219 | |||
| 1220 | 1) One option is to make it a variable and put it in the global frame. | ||
| 1221 | 2) Another option is to add a lookup rule that also looks in types. | ||
| 1222 | |||
| 1223 | Now implicitly instantiated packages exists both as a class and as a | ||
| 1224 | type (see implicit_instantiation in Inst.mo). Is this correct? | ||
| 1225 | |||
| 1226 | lookupVar is modified to implement 2. Is this correct? | ||
| 1227 | |||
| 1228 | old lookupVar is changed to lookupVarInternal and a new lookupVar | ||
| 1229 | is written, that first tests the old lookupVar, and if not found | ||
| 1230 | looks in the types | ||
| 1231 | |||
| 1232 | function: lookupVar | ||
| 1233 | |||
| 1234 | This function tries to finds a variable in the environment | ||
| 1235 | |||
| 1236 | Arg1: The environment to search in | ||
| 1237 | Arg2: The variable to search for." | ||
| 1238 | input FCore.Cache inCache; | ||
| 1239 | input FCore.Graph inEnv; | ||
| 1240 | input DAE.ComponentRef inComponentRef; | ||
| 1241 | output FCore.Cache outCache; | ||
| 1242 | output DAE.Attributes outAttributes; | ||
| 1243 | output DAE.Type outType; | ||
| 1244 | output DAE.Binding outBinding; | ||
| 1245 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 1246 | output InstTypes.SplicedExpData outSplicedExpData; | ||
| 1247 | output FCore.Graph outClassEnv "only used for package constants"; | ||
| 1248 | output FCore.Graph outComponentEnv "only used for package constants"; | ||
| 1249 | output String name "so the FQ path can be constructed"; | ||
| 1250 | algorithm | ||
| 1251 | (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,outSplicedExpData,outClassEnv,outComponentEnv,name) := | ||
| 1252 | matchcontinue (inCache,inEnv,inComponentRef) | ||
| 1253 | local | ||
| 1254 | DAE.Attributes attr; | ||
| 1255 | DAE.Type ty; | ||
| 1256 | DAE.Binding binding; | ||
| 1257 | FCore.Graph env, componentEnv, classEnv; | ||
| 1258 | DAE.ComponentRef cref; | ||
| 1259 | FCore.Cache cache; | ||
| 1260 | InstTypes.SplicedExpData splicedExpData; | ||
| 1261 | Option<DAE.Const> cnstForRange; | ||
| 1262 | |||
| 1263 | /*/ debugging | ||
| 1264 | case (cache,env,cref) | ||
| 1265 | algorithm | ||
| 1266 | print("CO: " + ComponentReferenceBasics.printComponentRefStr(cref) + " env: " + FGraph.printGraphPathStr(env) + "\n"); | ||
| 1267 | then | ||
| 1268 | fail();*/ | ||
| 1269 | |||
| 1270 | // try the old lookupVarInternal | ||
| 1271 | case (cache,env,cref) | ||
| 1272 | algorithm | ||
| 1273 | 2720161 | (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name) := lookupVarInternal(cache, env, cref, InstTypes.SEARCH_ALSO_BUILTIN()); | |
| 1274 | then | ||
| 1275 | (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name); | ||
| 1276 | |||
| 1277 | // then look in classes (implicitly instantiated packages) | ||
| 1278 | case (cache,env,cref) | ||
| 1279 | algorithm | ||
| 1280 | 758656 | (cache,classEnv,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cref,{},Mutable.create(false)); | |
| 1281 | 60343 | checkPackageVariableConstant(env,classEnv,componentEnv,attr,ty,cref); | |
| 1282 | // optional Expression.exp to return | ||
| 1283 | 60331 | then | |
| 1284 | (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name); | ||
| 1285 | |||
| 1286 | ✗ | case (cache,env,_) guard Config.getGraphicsExpMode() then (cache,DAE.dummyAttrConst,DAE.T_UNKNOWN_DEFAULT,DAE.UNBOUND(),NONE(),InstTypes.SPLICEDEXPDATA(NONE(),DAE.T_UNKNOWN_DEFAULT),env,env,"#varNotFound#"); | |
| 1287 | |||
| 1288 | /*/ fail if we couldn't find it | ||
| 1289 | case (_,env,cref) | ||
| 1290 | algorithm | ||
| 1291 | fprintln(Flags.FAILTRACE, "- Lookup.lookupVar failed:\n" + | ||
| 1292 | ComponentReferenceBasics.printComponentRefStr(cref) + " in:\n" + | ||
| 1293 | FGraph.printGraphPathStr(env)); | ||
| 1294 | then fail();*/ | ||
| 1295 | end matchcontinue; | ||
| 1296 | end lookupVar; | ||
| 1297 | |||
| 1298 | public function lookupVarIdent "Like lookupVar, but takes only an ident+subscript." | ||
| 1299 | input FCore.Cache inCache; | ||
| 1300 | input FCore.Graph inEnv; | ||
| 1301 | input String ident; | ||
| 1302 | input list<DAE.Subscript> ss={}; | ||
| 1303 | output FCore.Cache outCache; | ||
| 1304 | output DAE.Attributes outAttributes; | ||
| 1305 | output DAE.Type outType; | ||
| 1306 | output DAE.Binding outBinding; | ||
| 1307 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 1308 | output InstTypes.SplicedExpData outSplicedExpData; | ||
| 1309 | output FCore.Graph outClassEnv "only used for package constants"; | ||
| 1310 | output FCore.Graph outComponentEnv "only used for package constants"; | ||
| 1311 | output String name "so the FQ path can be constructed"; | ||
| 1312 | algorithm | ||
| 1313 | (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,outSplicedExpData,outClassEnv,outComponentEnv,name) := | ||
| 1314 | matchcontinue (inCache,inEnv) | ||
| 1315 | local | ||
| 1316 | DAE.Attributes attr; | ||
| 1317 | DAE.Type ty; | ||
| 1318 | DAE.Binding binding; | ||
| 1319 | FCore.Graph env, componentEnv, classEnv; | ||
| 1320 | DAE.ComponentRef cref; | ||
| 1321 | FCore.Cache cache; | ||
| 1322 | InstTypes.SplicedExpData splicedExpData; | ||
| 1323 | Option<DAE.Const> cnstForRange; | ||
| 1324 | |||
| 1325 | // try the old lookupVarInternal | ||
| 1326 | case (cache,env) | ||
| 1327 | algorithm | ||
| 1328 | 639334 | (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name) := lookupVarInternalIdent(cache, env, ident, ss, InstTypes.SEARCH_ALSO_BUILTIN()); | |
| 1329 | then | ||
| 1330 | (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name); | ||
| 1331 | |||
| 1332 | // then look in classes (implicitly instantiated packages) | ||
| 1333 | case (cache,env) | ||
| 1334 | algorithm | ||
| 1335 | // TODO: Skip makeCrefIdent by rewriting lookupVarInPackages | ||
| 1336 | 512924 | cref := ComponentReferenceBasics.makeCrefIdent(ident, DAE.T_UNKNOWN_DEFAULT, ss); | |
| 1337 | 512924 | (cache,classEnv,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cref,{},Mutable.create(false)); | |
| 1338 | 199 | checkPackageVariableConstant(env,classEnv,componentEnv,attr,ty,cref); | |
| 1339 | // optional Expression.exp to return | ||
| 1340 | 199 | then | |
| 1341 | (cache,attr,ty,binding,cnstForRange,splicedExpData,classEnv,componentEnv,name); | ||
| 1342 | |||
| 1343 | end matchcontinue; | ||
| 1344 | end lookupVarIdent; | ||
| 1345 | |||
| 1346 | protected function checkPackageVariableConstant " | ||
| 1347 | Variables in packages must be constant. This function produces an error message and fails | ||
| 1348 | if variable is not constant." | ||
| 1349 | input FCore.Graph parentEnv; | ||
| 1350 | input FCore.Graph classEnv; | ||
| 1351 | input FCore.Graph componentEnv; | ||
| 1352 | input DAE.Attributes attr; | ||
| 1353 | input DAE.Type tp; | ||
| 1354 | input DAE.ComponentRef cref; | ||
| 1355 | algorithm | ||
| 1356 | () := match attr | ||
| 1357 | local | ||
| 1358 | String s1,s2; | ||
| 1359 | |||
| 1360 | // do not fail if is a constant | ||
| 1361 | case DAE.ATTR(variability = SCode.CONST()) then (); | ||
| 1362 | |||
| 1363 | /*/ do not fail if is a parameter in non-package | ||
| 1364 | case (_, _, _,DAE.ATTR(variability = SCode.PARAM()),_,_) | ||
| 1365 | algorithm | ||
| 1366 | FCore.CL(e = cl) = FNode.refData(FGraph.lastScopeRef(classEnv)); | ||
| 1367 | false = SCodeUtil.isPackage(cl); | ||
| 1368 | // print("cref: " + ComponentReferenceBasics.printComponentRefStr(cref) + "\nprenv: " + FGraph.getGraphNameStr(parentEnv) + "\nclenv: " + FGraph.getGraphNameStr(classEnv) + "\ncoenv: " + FGraph.getGraphNameStr(componentEnv) + "\n"); | ||
| 1369 | then | ||
| 1370 | ();*/ | ||
| 1371 | |||
| 1372 | // fail if is not a constant | ||
| 1373 | else | ||
| 1374 | algorithm | ||
| 1375 | 12 | s1 := ComponentReferenceBasics.printComponentRefStr(cref); | |
| 1376 | 12 | s2 := FGraph.printGraphPathStr(classEnv); | |
| 1377 | 12 | Error.addMessage(Error.PACKAGE_VARIABLE_NOT_CONSTANT,{s1,s2}); | |
| 1378 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | true := Flags.isSet(Flags.FAILTRACE); |
| 1379 | ✗ | Debug.traceln("- Lookup.checkPackageVariableConstant failed: " + s1 + " in " + s2); | |
| 1380 | ✗ | then fail(); | |
| 1381 | end match; | ||
| 1382 | end checkPackageVariableConstant; | ||
| 1383 | |||
| 1384 | public function lookupVarInternal "Helper function to lookupVar. Searches the frames for variables." | ||
| 1385 | input FCore.Cache inCache; | ||
| 1386 | input FCore.Graph inEnv; | ||
| 1387 | input DAE.ComponentRef inComponentRef; | ||
| 1388 | input InstTypes.SearchStrategy searchStrategy "if SEARCH_LOCAL_ONLY it won't search in the builtin scope"; | ||
| 1389 | output FCore.Cache outCache; | ||
| 1390 | output DAE.Attributes outAttributes; | ||
| 1391 | output DAE.Type outType; | ||
| 1392 | output DAE.Binding outBinding; | ||
| 1393 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 1394 | output InstTypes.SplicedExpData splicedExpData; | ||
| 1395 | output FCore.Graph outClassEnv "the environment of the variable, typically the same as input, but e.g. for loop scopes can be 'stripped'"; | ||
| 1396 | output FCore.Graph outComponentEnv "the component environment of the variable"; | ||
| 1397 | output String name; | ||
| 1398 | algorithm | ||
| 1399 | (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outClassEnv,outComponentEnv,name) := | ||
| 1400 | matchcontinue (inCache,inEnv,inComponentRef,searchStrategy) | ||
| 1401 | local | ||
| 1402 | DAE.Attributes attr; | ||
| 1403 | DAE.Type ty; | ||
| 1404 | DAE.Binding binding; | ||
| 1405 | FCore.Children ht; | ||
| 1406 | DAE.ComponentRef ref; | ||
| 1407 | FCore.Cache cache; | ||
| 1408 | Option<DAE.Const> cnstForRange; | ||
| 1409 | FCore.Graph env,componentEnv; | ||
| 1410 | FCore.Ref r; | ||
| 1411 | |||
| 1412 | // look into the current frame | ||
| 1413 | case (cache, FCore.G(scope = r :: _), ref, _) | ||
| 1414 | algorithm | ||
| 1415 | 2960640 | ht := FNode.children(FNode.fromRef(r)); | |
| 1416 | 2960640 | (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarF(cache, ht, ref, inEnv); | |
| 1417 | 2001256 | then | |
| 1418 | (cache,attr,ty,binding,cnstForRange,splicedExpData,inEnv,componentEnv,name); | ||
| 1419 | |||
| 1420 | // look in the next frame, only if current frame is a for loop scope. | ||
| 1421 | case (cache, FCore.G(scope = r :: _), ref, _) | ||
| 1422 | algorithm | ||
| 1423 |
2/2✓ Branch 1 taken 758624 times.
✓ Branch 2 taken 200760 times.
|
959384 | true := FNode.isImplicitRefName(r); |
| 1424 | 200760 | (env, _) := FGraph.stripLastScopeRef(inEnv); | |
| 1425 | 200760 | (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name) := lookupVarInternal(cache, env, ref, searchStrategy); | |
| 1426 | then | ||
| 1427 | (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name); | ||
| 1428 | |||
| 1429 | // If not in top scope, look in top scope for builtin variables, e.g. time. | ||
| 1430 | case (cache, FCore.G(scope = _::_::_), ref, InstTypes.SEARCH_ALSO_BUILTIN()) | ||
| 1431 | algorithm | ||
| 1432 |
2/2✓ Branch 1 taken 377077 times.
✓ Branch 2 taken 3 times.
|
377080 | true := Builtin.variableIsBuiltin(ref); |
| 1433 | 3 | env := FGraph.topScope(inEnv); | |
| 1434 | 3 | ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env))); | |
| 1435 | 3 | (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarF(cache, ht, ref, env); | |
| 1436 | 3 | then | |
| 1437 | (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name); | ||
| 1438 | |||
| 1439 | end matchcontinue; | ||
| 1440 | end lookupVarInternal; | ||
| 1441 | |||
| 1442 | public function lookupVarInternalIdent "Helper function to lookupVar. Searches the frames for variables." | ||
| 1443 | input FCore.Cache inCache; | ||
| 1444 | input FCore.Graph inEnv; | ||
| 1445 | input String ident; | ||
| 1446 | input list<DAE.Subscript> ss={}; | ||
| 1447 | input InstTypes.SearchStrategy searchStrategy = InstTypes.SEARCH_LOCAL_ONLY() "if SEARCH_LOCAL_ONLY it won't search in the builtin scope"; | ||
| 1448 | output FCore.Cache outCache; | ||
| 1449 | output DAE.Attributes outAttributes; | ||
| 1450 | output DAE.Type outType; | ||
| 1451 | output DAE.Binding outBinding; | ||
| 1452 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 1453 | output InstTypes.SplicedExpData splicedExpData; | ||
| 1454 | output FCore.Graph outClassEnv "the environment of the variable, typically the same as input, but e.g. for loop scopes can be 'stripped'"; | ||
| 1455 | output FCore.Graph outComponentEnv "the component environment of the variable"; | ||
| 1456 | output String name; | ||
| 1457 | algorithm | ||
| 1458 | (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outClassEnv,outComponentEnv,name) := | ||
| 1459 | matchcontinue (inCache,inEnv,searchStrategy) | ||
| 1460 | local | ||
| 1461 | DAE.Attributes attr; | ||
| 1462 | DAE.Type ty; | ||
| 1463 | DAE.Binding binding; | ||
| 1464 | FCore.Children ht; | ||
| 1465 | FCore.Cache cache; | ||
| 1466 | Option<DAE.Const> cnstForRange; | ||
| 1467 | FCore.Graph env,componentEnv; | ||
| 1468 | FCore.Ref r; | ||
| 1469 | |||
| 1470 | // look into the current frame | ||
| 1471 | case (cache, FCore.G(scope = r :: _), _) | ||
| 1472 | algorithm | ||
| 1473 | 4605667 | ht := FNode.children(FNode.fromRef(r)); | |
| 1474 | 4605667 | (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarFIdent(cache, ht, ident, ss, inEnv); | |
| 1475 | 186471 | then | |
| 1476 | (cache,attr,ty,binding,cnstForRange,splicedExpData,inEnv,componentEnv,name); | ||
| 1477 | |||
| 1478 | // look in the next frame, only if current frame is a for loop scope. | ||
| 1479 | case (cache, FCore.G(scope = r :: _), _) | ||
| 1480 | algorithm | ||
| 1481 |
2/2✓ Branch 1 taken 4207682 times.
✓ Branch 2 taken 211514 times.
|
4419196 | true := FNode.isImplicitRefName(r); |
| 1482 | 211514 | (env, _) := FGraph.stripLastScopeRef(inEnv); | |
| 1483 | 211514 | (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name) := lookupVarInternalIdent(cache, env, ident, ss, searchStrategy); | |
| 1484 | then | ||
| 1485 | (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name); | ||
| 1486 | |||
| 1487 | // If not in top scope, look in top scope for builtin variables, e.g. time. | ||
| 1488 | case (cache, FCore.G(scope = _::_::_), InstTypes.SEARCH_ALSO_BUILTIN()) | ||
| 1489 | algorithm | ||
| 1490 |
2/2✓ Branch 1 taken 510474 times.
✓ Branch 2 taken 11 times.
|
510485 | true := Builtin.variableNameIsBuiltin(ident); |
| 1491 | 11 | env := FGraph.topScope(inEnv); | |
| 1492 | 11 | ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env))); | |
| 1493 | 11 | (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name) := lookupVarFIdent(cache, ht, ident, ss, env); | |
| 1494 | 11 | then | |
| 1495 | (cache,attr,ty,binding,cnstForRange,splicedExpData,env,componentEnv,name); | ||
| 1496 | |||
| 1497 | end matchcontinue; | ||
| 1498 | end lookupVarInternalIdent; | ||
| 1499 | |||
| 1500 | protected function frameIsImplAddedScope | ||
| 1501 | "returns true if the frame is a for-loop scope or a valueblock scope. | ||
| 1502 | This is indicated by the name of the frame." | ||
| 1503 | input FCore.Node f; | ||
| 1504 | output Boolean b; | ||
| 1505 | algorithm | ||
| 1506 | b := match f | ||
| 1507 | local | ||
| 1508 | FCore.Name oname; | ||
| 1509 | 6028 | case FCore.N(name=oname) then FCore.isImplicitScope(oname); | |
| 1510 | else false; | ||
| 1511 | end match; | ||
| 1512 | end frameIsImplAddedScope; | ||
| 1513 | |||
| 1514 | public function lookupVarInPackages "This function is called when a lookup of a variable with qualified names | ||
| 1515 | does not have the first element as a component, e.g. A.B.C is looked up | ||
| 1516 | where A is not a component. This implies that A is a class, and this | ||
| 1517 | class should be temporary instantiated, and the lookup should | ||
| 1518 | be performed within that class. I.e. the function performs lookup of | ||
| 1519 | variables in the class hierarchy. | ||
| 1520 | |||
| 1521 | Note: the splicedExpData is currently not relevant, since constants are always evaluated to a value. | ||
| 1522 | However, this might change in the future since it makes more sense to calculate the constants | ||
| 1523 | during setup in runtime (to gain precision and postpone choice of precision to runtime)." | ||
| 1524 | input FCore.Cache inCache; | ||
| 1525 | input FCore.Graph inEnv; | ||
| 1526 | input DAE.ComponentRef inComponentRef; | ||
| 1527 | input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion."; | ||
| 1528 | input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in a lower scope."; | ||
| 1529 | output FCore.Cache outCache; | ||
| 1530 | output FCore.Graph outClassEnv; | ||
| 1531 | output DAE.Attributes outAttributes; | ||
| 1532 | output DAE.Type outType; | ||
| 1533 | output DAE.Binding outBinding; | ||
| 1534 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 1535 | output InstTypes.SplicedExpData splicedExpData "currently not relevant for constants, but might be used in the future"; | ||
| 1536 | output FCore.Graph outComponentEnv; | ||
| 1537 | output String name "We only return the environment the component was found in; not its FQ name."; | ||
| 1538 | algorithm | ||
| 1539 | (outCache,outClassEnv,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) := | ||
| 1540 | matchcontinue (inCache, inEnv, inComponentRef, inPrevFrames) | ||
| 1541 | local | ||
| 1542 | SCode.Element c; | ||
| 1543 | String n,id; | ||
| 1544 | SCode.Encapsulated encflag; | ||
| 1545 | SCode.Restriction r; | ||
| 1546 | FCore.Graph env2,env3,env5,env,p_env,componentEnv; | ||
| 1547 | FCore.Scope prevFrames, fs; | ||
| 1548 | ClassInf.State ci_state; | ||
| 1549 | DAE.Attributes attr; | ||
| 1550 | DAE.Type ty; | ||
| 1551 | DAE.Binding bind; | ||
| 1552 | DAE.ComponentRef cref,cr; | ||
| 1553 | FCore.Ref f, rr; | ||
| 1554 | Option<FCore.Ref> of; | ||
| 1555 | FCore.Cache cache; | ||
| 1556 | Option<DAE.Const> cnstForRange; | ||
| 1557 | Absyn.Path scope; | ||
| 1558 | FCore.Children ht; | ||
| 1559 | DAE.Mod mod; | ||
| 1560 | |||
| 1561 | // If we search for A1.A2....An.x while in scope A1.A2...An, just search for x. | ||
| 1562 | // Must do like this to ensure finite recursion | ||
| 1563 | case (cache, env, DAE.CREF_QUAL(ident = id,subscriptLst = {},componentRef = cref), prevFrames) | ||
| 1564 | algorithm | ||
| 1565 | 1100296 | (of,prevFrames) := lookupPrevFrames(id,prevFrames); | |
| 1566 | () := match of | ||
| 1567 | // first part of name is a previous frame | ||
| 1568 | case SOME(f) | ||
| 1569 | algorithm | ||
| 1570 | 78895 | Mutable.update(inState,true); | |
| 1571 | 78895 | env5 := FGraph.pushScopeRef(env, f); | |
| 1572 | then | ||
| 1573 | (); | ||
| 1574 | // no prev frame | ||
| 1575 | case NONE() | ||
| 1576 | algorithm | ||
| 1577 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 106689 times.
|
1021401 | (cache,(c as SCode.CLASS(name=n,encapsulatedPrefix=encflag,restriction=r)),env2,prevFrames) := |
| 1578 | lookupClassInEnv(cache, | ||
| 1579 | env, | ||
| 1580 | id, | ||
| 1581 | prevFrames, | ||
| 1582 | Mutable.create(true), // In order to use the prevFrames, we need to make sure we can't instantiate one of the classes too soon! | ||
| 1583 | NONE()); | ||
| 1584 | 106689 | Mutable.update(inState,true); | |
| 1585 | // see if we have an instance of a component! | ||
| 1586 | 106689 | rr := FNode.child(FGraph.lastScopeRef(env2), id); | |
| 1587 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 106689 times.
|
106689 | if FNode.isRefInstance(rr) // is an instance, use it |
| 1588 | then | ||
| 1589 | ✗ | (cache, env5) := Inst.getCachedInstance(cache, env2, id, rr); | |
| 1590 | else // not an instance, instantiate it - lookup of constants on form A.B in packages. instantiate package and look inside. | ||
| 1591 | 106689 | env3 := FGraph.openScope(env2, encflag, n, FGraph.restrictionToScopeType(r)); | |
| 1592 | 106689 | ci_state := ClassInfUtil.start(r, FGraph.getGraphName(env3)); | |
| 1593 | // fprintln(Flags.INST_TRACE, "LOOKUP VAR IN PACKAGES ICD: " + FGraph.printGraphPathStr(env3) + " var: " + ComponentReferenceBasics.printComponentRefStr(cref)); | ||
| 1594 | 106689 | mod := Mod.getClassModifier(env2, n); | |
| 1595 | 106689 | (cache,env5,_,_,_,_,_,_,_,_,_,_) := | |
| 1596 | Inst.instClassIn(cache,env3,InnerOuter.emptyInstHierarchy,UnitAbsyn.noStore, | ||
| 1597 | mod, DAE.NOPRE(), ci_state, c, SCode.PUBLIC(), {}, | ||
| 1598 | /*true*/false, InstTypes.INNER_CALL(), ConnectionGraph.EMPTY, | ||
| 1599 | Connect.emptySet, NONE()); | ||
| 1600 | end if; | ||
| 1601 | then (); | ||
| 1602 | end match; | ||
| 1603 | 185582 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env5,cref,prevFrames,inState); | |
| 1604 | // Add the class name to the spliced exp so that the name is correct. | ||
| 1605 | 117400 | splicedExpData := prefixSplicedExp(ComponentReferenceBasics.crefFirstCref(inComponentRef), splicedExpData); | |
| 1606 | 117400 | then | |
| 1607 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name); | ||
| 1608 | |||
| 1609 | // Why is this done? It is already done done in lookupVar! | ||
| 1610 | // BZ: This is due to recursive call when it might become DAE.CREF_IDENT calls. | ||
| 1611 | case (cache, env, (cr as DAE.CREF_IDENT()), _) | ||
| 1612 | algorithm | ||
| 1613 | 1244226 | (cache,env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackagesIdent(cache, env, cr.ident, cr.subscriptLst, inPrevFrames, inState); | |
| 1614 | then | ||
| 1615 | (cache,env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name); | ||
| 1616 | |||
| 1617 | // Lookup where the first identifier is a component. | ||
| 1618 | case (cache, env, cr as DAE.CREF_QUAL(), _) | ||
| 1619 | algorithm | ||
| 1620 | 987913 | ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env))); | |
| 1621 | 868685 | (cache, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name) := lookupVarF(cache, ht, cr, env); | |
| 1622 | 474 | then | |
| 1623 | (cache, env, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name); | ||
| 1624 | |||
| 1625 | // Search parent scopes | ||
| 1626 | case (cache, FCore.G(scope = f::fs), cr as DAE.CREF_QUAL(), prevFrames) | ||
| 1627 | algorithm | ||
| 1628 |
2/2✓ Branch 1 taken 68184 times.
✓ Branch 2 taken 800027 times.
|
868211 | false := Mutable.access(inState); |
| 1629 | 800027 | env := FGraph.setScope(inEnv, fs); | |
| 1630 | 800027 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cr,f::prevFrames,inState); | |
| 1631 | then | ||
| 1632 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name); | ||
| 1633 | |||
| 1634 | else | ||
| 1635 | algorithm | ||
| 1636 | //true = Flags.isSet(Flags.FAILTRACE); | ||
| 1637 | //Debug.traceln("- Lookup.lookupVarInPackages failed on exp:" + ComponentReferenceBasics.printComponentRefStr(cr) + " in scope: " + FGraph.printGraphPathStr(env)); | ||
| 1638 | then | ||
| 1639 | fail(); | ||
| 1640 | end matchcontinue; | ||
| 1641 | end lookupVarInPackages; | ||
| 1642 | |||
| 1643 | public function lookupVarInPackagesIdent "This function is called when a lookup of a variable with qualified names | ||
| 1644 | does not have the first element as a component, e.g. A.B.C is looked up | ||
| 1645 | where A is not a component. This implies that A is a class, and this | ||
| 1646 | class should be temporary instantiated, and the lookup should | ||
| 1647 | be performed within that class. I.e. the function performs lookup of | ||
| 1648 | variables in the class hierarchy. | ||
| 1649 | |||
| 1650 | Note: the splicedExpData is currently not relevant, since constants are always evaluated to a value. | ||
| 1651 | However, this might change in the future since it makes more sense to calculate the constants | ||
| 1652 | during setup in runtime (to gain precision and postpone choice of precision to runtime)." | ||
| 1653 | input FCore.Cache inCache; | ||
| 1654 | input FCore.Graph inEnv; | ||
| 1655 | input String id; | ||
| 1656 | input list<DAE.Subscript> ss; | ||
| 1657 | input FCore.Scope inPrevFrames "Environment in reverse order. Contains frames we previously had in the scope. Will be looked up instead of the environment in order to avoid infinite recursion."; | ||
| 1658 | input Mutable<Boolean> inState "If true, we have found a class. If the path was qualified, we should no longer look in a lower scope."; | ||
| 1659 | output FCore.Cache outCache; | ||
| 1660 | output FCore.Graph outClassEnv; | ||
| 1661 | output DAE.Attributes outAttributes; | ||
| 1662 | output DAE.Type outType; | ||
| 1663 | output DAE.Binding outBinding; | ||
| 1664 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 1665 | output InstTypes.SplicedExpData splicedExpData "currently not relevant for constants, but might be used in the future"; | ||
| 1666 | output FCore.Graph outComponentEnv; | ||
| 1667 | output String name "We only return the environment the component was found in; not its FQ name."; | ||
| 1668 | algorithm | ||
| 1669 | (outCache,outClassEnv,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) := | ||
| 1670 | matchcontinue (inCache, inEnv, inPrevFrames) | ||
| 1671 | local | ||
| 1672 | FCore.Graph env,p_env,componentEnv; | ||
| 1673 | FCore.Scope prevFrames, fs; | ||
| 1674 | FCore.Node node; | ||
| 1675 | DAE.Attributes attr; | ||
| 1676 | DAE.Type ty; | ||
| 1677 | DAE.Binding bind; | ||
| 1678 | DAE.ComponentRef cr; | ||
| 1679 | FCore.Ref f; | ||
| 1680 | FCore.Cache cache; | ||
| 1681 | Option<DAE.Const> cnstForRange; | ||
| 1682 | Absyn.Path scope; | ||
| 1683 | Boolean unique; | ||
| 1684 | FCore.Children ht; | ||
| 1685 | list<Absyn.Import> qimports, uqimports; | ||
| 1686 | |||
| 1687 | // Why is this done? It is already done done in lookupVar! | ||
| 1688 | // BZ: This is due to recursive call when it might become DAE.CREF_IDENT calls. | ||
| 1689 | case (cache, env, _) | ||
| 1690 | algorithm | ||
| 1691 | 4719056 | (cache,attr,ty,bind,cnstForRange,splicedExpData,_,componentEnv,name) := lookupVarInternalIdent(cache, env, id, ss); | |
| 1692 | 60068 | Mutable.update(inState,true); | |
| 1693 | 60068 | then | |
| 1694 | (cache,env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name); | ||
| 1695 | |||
| 1696 | // Lookup where the first identifier is a component. | ||
| 1697 | case (cache, env, _) | ||
| 1698 | algorithm | ||
| 1699 | 4658988 | ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env))); | |
| 1700 | 3674703 | (cache, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name) := lookupVarFIdent(cache, ht, id, ss, env); | |
| 1701 | ✗ | then | |
| 1702 | (cache, env, attr, ty, bind, cnstForRange, splicedExpData, componentEnv, name); | ||
| 1703 | |||
| 1704 | // Search among imports | ||
| 1705 | case (cache, env, prevFrames) | ||
| 1706 | algorithm | ||
| 1707 | 4658988 | node := FNode.fromRef(FGraph.lastScopeRef(env)); | |
| 1708 | 3674703 | (qimports, uqimports) := FNode.imports(node); | |
| 1709 | try | ||
| 1710 | // Search among qualified imports, e.g. import A.B; or import D=A.B; | ||
| 1711 |
2/2✓ Branch 0 taken 222 times.
✓ Branch 1 taken 94537 times.
|
94759 | false := listEmpty(qimports); |
| 1712 | 94537 | cr := lookupQualifiedImportedVarInFrame(qimports, id); | |
| 1713 | 91649 | Mutable.update(inState,true); | |
| 1714 | // if the first name of the import A.B is equal with the scope we are in, skip it! | ||
| 1715 |
3/4✓ Branch 4 taken 3752 times.
✓ Branch 5 taken 87897 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3752 times.
|
91649 | cr := if FNode.name(FNode.fromRef(FGraph.lastScopeRef(env))) == ComponentReferenceBasics.crefFirstIdent(cr) |
| 1716 | then ComponentReference.crefStripFirstIdent(cr) | ||
| 1717 | else cr; | ||
| 1718 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 91649 times.
|
91649 | f::prevFrames := listReverse(FGraph.currentScope(env)); |
| 1719 | 91649 | env := FGraph.setScope(env, {f}); | |
| 1720 | 91649 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackages(cache,env,cr,prevFrames,inState); | |
| 1721 | else | ||
| 1722 | // Search among unqualified imports, e.g. import A.B.* | ||
| 1723 |
2/2✓ Branch 0 taken 94059 times.
✓ Branch 1 taken 700 times.
|
94759 | false := listEmpty(uqimports); |
| 1724 | 700 | (cache,p_env,attr,ty,bind,cnstForRange,unique,splicedExpData,componentEnv,name) := lookupUnqualifiedImportedVarInFrame(cache, uqimports, env, id); | |
| 1725 | 66 | reportSeveralNamesError(unique,id); | |
| 1726 | 66 | Mutable.update(inState,true); | |
| 1727 | end try; | ||
| 1728 | 66 | then | |
| 1729 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name); | ||
| 1730 | |||
| 1731 | // Search parent scopes | ||
| 1732 | case (cache, FCore.G(scope = f::fs), prevFrames) | ||
| 1733 | algorithm | ||
| 1734 |
2/2✓ Branch 1 taken 215186 times.
✓ Branch 2 taken 3459451 times.
|
3674637 | false := Mutable.access(inState); |
| 1735 | 3459451 | env := FGraph.setScope(inEnv, fs); | |
| 1736 | 3459451 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name) := lookupVarInPackagesIdent(cache,env,id,ss,f::prevFrames,inState); | |
| 1737 | then | ||
| 1738 | (cache,p_env,attr,ty,bind,cnstForRange,splicedExpData,componentEnv,name); | ||
| 1739 | |||
| 1740 | else | ||
| 1741 | algorithm | ||
| 1742 | //true = Flags.isSet(Flags.FAILTRACE); | ||
| 1743 | //Debug.traceln("- Lookup.lookupVarInPackages failed on exp:" + ComponentReferenceBasics.printComponentRefStr(cr) + " in scope: " + FGraph.printGraphPathStr(env)); | ||
| 1744 | then | ||
| 1745 | fail(); | ||
| 1746 | end matchcontinue; | ||
| 1747 | end lookupVarInPackagesIdent; | ||
| 1748 | |||
| 1749 | public function lookupVarLocal | ||
| 1750 | "This function is very similar to `lookup_var\', but it only looks | ||
| 1751 | in the topmost environment frame, which means that it only finds | ||
| 1752 | names defined in the local scope. | ||
| 1753 | ----EXCEPTION---: When the topmost scope is the scope of a for loop, the lookup | ||
| 1754 | continues on the next scope. This to allow variables in the local scope to | ||
| 1755 | also be found even if inside a for scope. | ||
| 1756 | Arg1: The environment to search in | ||
| 1757 | Arg2: The variable to search for." | ||
| 1758 | input FCore.Cache inCache; | ||
| 1759 | input FCore.Graph inEnv; | ||
| 1760 | input DAE.ComponentRef inComponentRef; | ||
| 1761 | output FCore.Cache outCache; | ||
| 1762 | output DAE.Attributes outAttributes; | ||
| 1763 | output DAE.Type outType; | ||
| 1764 | output DAE.Binding outBinding; | ||
| 1765 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 1766 | output InstTypes.SplicedExpData splicedExpData; | ||
| 1767 | output FCore.Graph outClassEnv; | ||
| 1768 | output FCore.Graph outComponentEnv; | ||
| 1769 | output String name; | ||
| 1770 | algorithm | ||
| 1771 | // adrpo: use lookupVarInternal as is the SAME but it doesn't search in the builtin scope! | ||
| 1772 | 39754 | (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outClassEnv,outComponentEnv,name) := | |
| 1773 | lookupVarInternal(inCache, inEnv, inComponentRef, InstTypes.SEARCH_LOCAL_ONLY()); | ||
| 1774 | end lookupVarLocal; | ||
| 1775 | |||
| 1776 | public function lookupIdentLocal "Searches for a variable in the local scope." | ||
| 1777 | input FCore.Cache inCache; | ||
| 1778 | input FCore.Graph inEnv; | ||
| 1779 | input SCode.Ident inIdent; | ||
| 1780 | output FCore.Cache outCache; | ||
| 1781 | output DAE.Var outVar; | ||
| 1782 | output SCode.Element outElement; | ||
| 1783 | output DAE.Mod outMod; | ||
| 1784 | output FCore.Status instStatus; | ||
| 1785 | output FCore.Graph outComponentEnv; | ||
| 1786 | algorithm | ||
| 1787 | (outCache,outVar,outElement,outMod,instStatus,outComponentEnv):= | ||
| 1788 | matchcontinue (inCache,inEnv,inIdent) | ||
| 1789 | local | ||
| 1790 | DAE.Var fv; | ||
| 1791 | SCode.Element c; | ||
| 1792 | DAE.Mod m; | ||
| 1793 | FCore.Status i; | ||
| 1794 | FCore.Ref r; | ||
| 1795 | FCore.Graph env,componentEnv; | ||
| 1796 | FCore.Children ht; | ||
| 1797 | String id; | ||
| 1798 | FCore.Cache cache; | ||
| 1799 | |||
| 1800 | // component environment | ||
| 1801 | case (cache, FCore.G(scope = r::_), id) | ||
| 1802 | algorithm | ||
| 1803 | 799031 | ht := FNode.children(FNode.fromRef(r)); | |
| 1804 | 799031 | (fv,c,m,i,componentEnv) := lookupVar2(ht, id, inEnv); | |
| 1805 | 589437 | then | |
| 1806 | (cache,fv,c,m,i,componentEnv); | ||
| 1807 | |||
| 1808 | // Look in the next frame, if the current frame is a for loop scope. | ||
| 1809 | case (cache, FCore.G(scope = r::_), id) | ||
| 1810 | algorithm | ||
| 1811 |
2/2✓ Branch 1 taken 209593 times.
✓ Branch 2 taken 1 time.
|
209594 | true := FNode.isImplicitRefName(r); |
| 1812 | 1 | (env, _) := FGraph.stripLastScopeRef(inEnv); | |
| 1813 | 1 | (cache,fv,c,m,i,componentEnv) := lookupIdentLocal(cache, env, id); | |
| 1814 | then | ||
| 1815 | (cache,fv,c,m,i,componentEnv); | ||
| 1816 | |||
| 1817 | end matchcontinue; | ||
| 1818 | end lookupIdentLocal; | ||
| 1819 | |||
| 1820 | public function lookupClassLocal "Searches for a class definition in the local scope." | ||
| 1821 | input FCore.Graph inEnv; | ||
| 1822 | input SCode.Ident inIdent; | ||
| 1823 | output SCode.Element outClass; | ||
| 1824 | output FCore.Graph outEnv; | ||
| 1825 | algorithm | ||
| 1826 | (outClass,outEnv) := match(inEnv,inIdent) | ||
| 1827 | local | ||
| 1828 | SCode.Element cl; | ||
| 1829 | FCore.Graph env; | ||
| 1830 | FCore.Children ht; | ||
| 1831 | String id; | ||
| 1832 | FCore.Ref r; | ||
| 1833 | |||
| 1834 | case (env as FCore.G(scope = r::_),id) | ||
| 1835 | algorithm | ||
| 1836 | 149362 | ht := FNode.children(FNode.fromRef(r)); | |
| 1837 | 149362 | r := FCore.RefTree.get(ht, id); | |
| 1838 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 16743 times.
✓ Branch 3 taken 13478 times.
✓ Branch 4 taken 3265 times.
|
16743 | FCore.N(data = FCore.CL(e = cl)) := FNode.fromRef(r); |
| 1839 | then | ||
| 1840 | (cl,env); | ||
| 1841 | end match; | ||
| 1842 | end lookupClassLocal; | ||
| 1843 | |||
| 1844 | public function lookupIdent | ||
| 1845 | "Same as lookupIdentLocal, except check all frames" | ||
| 1846 | input FCore.Cache inCache; | ||
| 1847 | input FCore.Graph inEnv; | ||
| 1848 | input SCode.Ident inIdent; | ||
| 1849 | output FCore.Cache outCache; | ||
| 1850 | output DAE.Var outVar; | ||
| 1851 | output SCode.Element outElement; | ||
| 1852 | output DAE.Mod outMod; | ||
| 1853 | output FCore.Status instStatus; | ||
| 1854 | output FCore.Graph outEnv "the env where we found the ident"; | ||
| 1855 | algorithm | ||
| 1856 | (outCache,outVar,outElement,outMod,instStatus,outEnv):= | ||
| 1857 | matchcontinue (inCache,inEnv,inIdent) | ||
| 1858 | local | ||
| 1859 | DAE.Var fv; | ||
| 1860 | SCode.Element c; | ||
| 1861 | DAE.Mod m; | ||
| 1862 | FCore.Status i; | ||
| 1863 | FCore.Children ht; | ||
| 1864 | String id; | ||
| 1865 | FCore.Graph e; | ||
| 1866 | FCore.Cache cache; | ||
| 1867 | FCore.Ref r; | ||
| 1868 | |||
| 1869 | case (cache,FCore.G(scope = r::_),id) | ||
| 1870 | algorithm | ||
| 1871 | 520317 | ht := FNode.children(FNode.fromRef(r)); | |
| 1872 | 520317 | (fv,c,m,i,_) := lookupVar2(ht, id, inEnv); | |
| 1873 | 84558 | then | |
| 1874 | (cache,fv,c,m,i,inEnv); | ||
| 1875 | |||
| 1876 | case (cache, FCore.G(scope = _::_),id) | ||
| 1877 | algorithm | ||
| 1878 | 435759 | (e, _) := FGraph.stripLastScopeRef(inEnv); | |
| 1879 | 435759 | (cache,fv,c,m,i,e) := lookupIdent(cache, e, id); | |
| 1880 | then | ||
| 1881 | (cache,fv,c,m,i,e); | ||
| 1882 | |||
| 1883 | end matchcontinue; | ||
| 1884 | end lookupIdent; | ||
| 1885 | |||
| 1886 | // Function lookup | ||
| 1887 | public function lookupFunctionsInEnv | ||
| 1888 | "Returns a list of types that the function has." | ||
| 1889 | input FCore.Cache inCache; | ||
| 1890 | input FCore.Graph inEnv; | ||
| 1891 | input Absyn.Path inId; | ||
| 1892 | input SourceInfo inInfo; | ||
| 1893 | output FCore.Cache outCache; | ||
| 1894 | output list<DAE.Type> outTypesTypeLst; | ||
| 1895 | algorithm | ||
| 1896 | (outCache,outTypesTypeLst) := matchcontinue (inCache,inEnv,inId,inInfo) | ||
| 1897 | local | ||
| 1898 | FCore.Graph env_1, cenv, env; | ||
| 1899 | list<DAE.Type> res; | ||
| 1900 | list<Absyn.Path> names; | ||
| 1901 | FCore.Children httypes; | ||
| 1902 | FCore.Children ht; | ||
| 1903 | String str, name; | ||
| 1904 | FCore.Cache cache; | ||
| 1905 | Absyn.Path id; | ||
| 1906 | SourceInfo info; | ||
| 1907 | |||
| 1908 | /* | ||
| 1909 | case (cache,env,id,info) | ||
| 1910 | algorithm | ||
| 1911 | print("Looking up: " + AbsynUtil.pathString(id) + " in env: " + FGraph.printGraphPathStr(env) + "\n"); | ||
| 1912 | then | ||
| 1913 | fail();*/ | ||
| 1914 | |||
| 1915 | /*/ strip env if path is fully qualified in env | ||
| 1916 | case (cache,env,id,info) | ||
| 1917 | algorithm | ||
| 1918 | id = Env.pathStripEnvIfFullyQualifedInEnv(id, env); | ||
| 1919 | (cache,res) = lookupFunctionsInEnv(cache,env,id,info); | ||
| 1920 | then | ||
| 1921 | (cache,res);*/ | ||
| 1922 | |||
| 1923 | // we might have a component reference, i.e. world.gravityAcceleration | ||
| 1924 | case (cache,env,Absyn.QUALIFIED(name, id),info) | ||
| 1925 | algorithm | ||
| 1926 | 52370 | ErrorExt.setCheckpoint("functionViaComponentRef"); | |
| 1927 | 52370 | (cache,_,_,_,_,_,_,cenv,_) := lookupVarIdent(cache, env, name, {}); | |
| 1928 | 11128 | (cache, res) := lookupFunctionsInEnv(cache, cenv, id, info); | |
| 1929 | 11128 | ErrorExt.rollBack("functionViaComponentRef"); | |
| 1930 | 11128 | then | |
| 1931 | (cache,res); | ||
| 1932 | |||
| 1933 | case (_,_,Absyn.QUALIFIED(_, _),_) | ||
| 1934 | algorithm | ||
| 1935 | 41242 | ErrorExt.rollBack("functionViaComponentRef"); | |
| 1936 | 41242 | then | |
| 1937 | fail(); | ||
| 1938 | |||
| 1939 | // here we do some bad things which unfortunately are needed for some MSL models (MoistAir1) | ||
| 1940 | // we search the environment in reverse instead of finding out where the first id of the path is | ||
| 1941 | case (cache,env,id,_) | ||
| 1942 | algorithm | ||
| 1943 | 74956 | env := FGraph.selectScope(env, id); | |
| 1944 | 233 | name := AbsynUtil.pathLastIdent(id); | |
| 1945 | 233 | (cache, res) := lookupFunctionsInEnv(cache, env, Absyn.IDENT(name), inInfo); | |
| 1946 | then | ||
| 1947 | (cache,res); | ||
| 1948 | |||
| 1949 | // Builtin operators are looked up in top frame directly | ||
| 1950 | case (cache,env,(Absyn.IDENT(name = str)),info) | ||
| 1951 | algorithm | ||
| 1952 | 29544 | Static.elabBuiltinHandler(str) "Check for builtin operators"; | |
| 1953 | 4367 | env := FGraph.topScope(env); | |
| 1954 | 4367 | ht := FNode.children(FNode.fromRef(FGraph.lastScopeRef(env))); | |
| 1955 | 4367 | httypes := getHtTypes(FGraph.lastScopeRef(env)); | |
| 1956 | 4367 | (cache,res) := lookupFunctionsInFrame(cache, ht, httypes, env, str, info); | |
| 1957 | then | ||
| 1958 | (cache,res); | ||
| 1959 | |||
| 1960 | // Check for cardinality that can not be represented in the environment. | ||
| 1961 | case (cache,env,Absyn.IDENT(name = str as "cardinality"),_) | ||
| 1962 | algorithm | ||
| 1963 | ✗ | env := FGraph.topScope(env); | |
| 1964 | ✗ | res := createGenericBuiltinFunctions(env, str); | |
| 1965 | ✗ | then | |
| 1966 | (cache,res); | ||
| 1967 | |||
| 1968 | // not fully qualified! | ||
| 1969 | case (cache,env,id,info) | ||
| 1970 | algorithm | ||
| 1971 |
3/4✓ Branch 0 taken 70357 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 66292 times.
✓ Branch 3 taken 4065 times.
|
70357 | failure(Absyn.FULLYQUALIFIED(_) := id); |
| 1972 | 66292 | (cache,res) := lookupFunctionsInEnv2(cache,env,id,false,info); | |
| 1973 | then | ||
| 1974 | (cache,res); | ||
| 1975 | |||
| 1976 | // fullyqual | ||
| 1977 | case (cache,env,Absyn.FULLYQUALIFIED(id),info) | ||
| 1978 | algorithm | ||
| 1979 | 4065 | env := FGraph.topScope(env); | |
| 1980 | 4065 | (cache,res) := lookupFunctionsInEnv2(cache,env,id,true,info); | |
| 1981 | then | ||
| 1982 | (cache,res); | ||
| 1983 | |||
| 1984 | case (cache,env,id,_) | ||
| 1985 | algorithm | ||
| 1986 | id := match id | ||
| 1987 | case Absyn.IDENT("Clock") then Absyn.QUALIFIED("OpenModelica",Absyn.QUALIFIED("Internal",Absyn.IDENT("ClockConstructor"))); | ||
| 1988 | else id; | ||
| 1989 | end match; | ||
| 1990 |
3/4✗ Branch 1 not taken.
✓ Branch 2 taken 4843 times.
✓ Branch 3 taken 3962 times.
✓ Branch 4 taken 881 times.
|
17168 | (cache,SCode.CLASS(classDef=SCode.OVERLOAD(pathLst=names),info=info),env_1) := lookupClass(cache,env,id); |
| 1991 | 881 | (cache,res) := lookupFunctionsListInEnv(cache,env_1,names,info,{}); | |
| 1992 | // print(stringDelimitList(List.map(res,TypesDump.unparseType),"\n###\n")); | ||
| 1993 | then (cache,res); | ||
| 1994 | |||
| 1995 | 16287 | case (cache,_,_,_) then (cache,{}); | |
| 1996 | |||
| 1997 | case (_,_,id,_) | ||
| 1998 | algorithm | ||
| 1999 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 2000 | ✗ | Debug.traceln("lookupFunctionsInEnv failed on: " + AbsynUtil.pathString(id)); | |
| 2001 | ✗ | then | |
| 2002 | fail(); | ||
| 2003 | |||
| 2004 | end matchcontinue; | ||
| 2005 | end lookupFunctionsInEnv; | ||
| 2006 | |||
| 2007 | public function lookupFunctionsListInEnv | ||
| 2008 | input FCore.Cache inCache; | ||
| 2009 | input FCore.Graph inEnv; | ||
| 2010 | input list<Absyn.Path> inIds; | ||
| 2011 | input SourceInfo info; | ||
| 2012 | input list<DAE.Type> inAcc; | ||
| 2013 | output FCore.Cache outCache; | ||
| 2014 | output list<DAE.Type> outTypesTypeLst; | ||
| 2015 | algorithm | ||
| 2016 | (outCache,outTypesTypeLst) := matchcontinue (inCache, inEnv, inIds, inAcc) | ||
| 2017 | local | ||
| 2018 | Absyn.Path id; | ||
| 2019 | list<DAE.Type> res; | ||
| 2020 | String str; | ||
| 2021 | FCore.Cache cache; | ||
| 2022 | FCore.Graph env; | ||
| 2023 | list<Absyn.Path> ids; | ||
| 2024 | list<DAE.Type> acc; | ||
| 2025 | |||
| 2026 | 980 | case (cache, _, {}, acc) then (cache,listReverse(acc)); | |
| 2027 | case (cache, env, id::ids, acc) | ||
| 2028 | algorithm | ||
| 2029 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1870 times.
|
1870 | (cache,res as _::_) := lookupFunctionsInEnv(cache,env,id,info); |
| 2030 | |||
| 2031 | 1870 | (cache,acc) := lookupFunctionsListInEnv(cache,env,ids,info,listAppend(res,acc)); | |
| 2032 | then (cache,acc); | ||
| 2033 | case (_, env, id::_, _) | ||
| 2034 | algorithm | ||
| 2035 | ✗ | str := AbsynUtil.pathString(id) + " not found in scope: " + FGraph.printGraphPathStr(env); | |
| 2036 | ✗ | Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, info); | |
| 2037 | ✗ | then fail(); | |
| 2038 | end matchcontinue; | ||
| 2039 | end lookupFunctionsListInEnv; | ||
| 2040 | |||
| 2041 | protected function lookupFunctionsInEnv2 | ||
| 2042 | "Returns a list of types that the function has." | ||
| 2043 | input FCore.Cache inCache; | ||
| 2044 | input FCore.Graph inEnv; | ||
| 2045 | input Absyn.Path inPath; | ||
| 2046 | input Boolean followedQual "cannot pop frames if we followed a qualified path at any point"; | ||
| 2047 | input SourceInfo info; | ||
| 2048 | output FCore.Cache outCache; | ||
| 2049 | output list<DAE.Type> outTypesTypeLst; | ||
| 2050 | algorithm | ||
| 2051 | (outCache,outTypesTypeLst) := matchcontinue (inCache, inEnv, inPath, followedQual) | ||
| 2052 | local | ||
| 2053 | Absyn.Path id,path; | ||
| 2054 | FCore.Children httypes; | ||
| 2055 | FCore.Children ht; | ||
| 2056 | list<DAE.Type> res; | ||
| 2057 | FCore.Graph env,env_1,env2,env_2; | ||
| 2058 | String pack,str; | ||
| 2059 | SCode.Element c; | ||
| 2060 | SCode.Encapsulated encflag; | ||
| 2061 | SCode.Restriction restr; | ||
| 2062 | ClassInf.State ci_state; | ||
| 2063 | FCore.Ref r; | ||
| 2064 | FCore.Cache cache; | ||
| 2065 | DAE.Mod mod; | ||
| 2066 | |||
| 2067 | // Simple name, search frame | ||
| 2068 | case (cache, FCore.G(scope = r::_), Absyn.IDENT(name = str), _) | ||
| 2069 | algorithm | ||
| 2070 | 127450 | ht := FNode.children(FNode.fromRef(r)); | |
| 2071 | 127450 | httypes := getHtTypes(r); | |
| 2072 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 64981 times.
|
127450 | (cache,res as _::_):= lookupFunctionsInFrame(cache, ht, httypes, inEnv, str, info); |
| 2073 | 64981 | then | |
| 2074 | (cache,res); | ||
| 2075 | |||
| 2076 | // Simple name, if class with restriction function found in frame instantiate to get type. | ||
| 2077 | case (cache, FCore.G(scope = r::_), id as Absyn.IDENT(), _) | ||
| 2078 | algorithm | ||
| 2079 | // adrpo: do not search in the entire environment as we anyway recurse with the fs argument! | ||
| 2080 | // just search in {f} not f::fs as otherwise we might get us in an infinite loop | ||
| 2081 | // Bjozac: Readded the f::fs search frame, otherwise we might get caught in a inifinite loop! | ||
| 2082 | // Did not investigate this further then that it can crasch the kernel. | ||
| 2083 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 23598 times.
|
62573 | (cache,(c as SCode.CLASS(name=str,restriction=restr)),env_1) := lookupClass(cache, inEnv, id); |
| 2084 |
2/2✓ Branch 1 taken 104 times.
✓ Branch 2 taken 23494 times.
|
23598 | true := SCodeUtil.isFunctionRestriction(restr); |
| 2085 | // get function dae from instantiation | ||
| 2086 | // fprintln(Flags.INST_TRACE, "LOOKUP FUNCTIONS IN ENV ID ICD: " + FGraph.printGraphPathStr(env_1) + "." + str); | ||
| 2087 |
2/4✗ Branch 1 not taken.
✓ Branch 2 taken 19567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19567 times.
|
23494 | (cache,env_2 as FCore.G(scope = r::_),_) |
| 2088 | := InstFunction.implicitFunctionTypeInstantiation(cache,env_1,InnerOuter.emptyInstHierarchy, c); | ||
| 2089 | 19567 | ht := FNode.children(FNode.fromRef(r)); | |
| 2090 | 19567 | httypes := getHtTypes(r); | |
| 2091 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 14003 times.
|
19567 | (cache,res as _::_):= lookupFunctionsInFrame(cache, ht, httypes, env_2, str, info); |
| 2092 | 14003 | then | |
| 2093 | (cache,res); | ||
| 2094 | |||
| 2095 | // For qualified function names, e.g. Modelica.Math.sin | ||
| 2096 | case (cache, FCore.G(scope = r::_), Absyn.QUALIFIED(name = pack,path = path), _) | ||
| 2097 | algorithm | ||
| 2098 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 94219 times.
|
94582 | (cache,(c as SCode.CLASS(name=str,encapsulatedPrefix=encflag,restriction=restr)),env_1) := lookupClass(cache, inEnv, Absyn.IDENT(pack)); |
| 2099 | |||
| 2100 | 94219 | r := FNode.child(FGraph.lastScopeRef(env_1), str); | |
| 2101 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 94219 times.
|
94219 | if FNode.isRefInstance(r) // we have an instance of a component |
| 2102 | then | ||
| 2103 | ✗ | (cache, env2) := Inst.getCachedInstance(cache, env_1, str, r); | |
| 2104 | else | ||
| 2105 | 94219 | env2 := FGraph.openScope(env_1, encflag, str, FGraph.restrictionToScopeType(restr)); | |
| 2106 | 94219 | ci_state := ClassInfUtil.start(restr, FGraph.getGraphName(env2)); | |
| 2107 | // fprintln(Flags.INST_TRACE, "LOOKUP FUNCTIONS IN ENV QUAL ICD: " + FGraph.printGraphPathStr(env2) + "." + str); | ||
| 2108 | 94219 | mod := Mod.getClassModifier(env_1, str); | |
| 2109 | 94219 | (cache,env2,_,_,_) := | |
| 2110 | Inst.partialInstClassIn( | ||
| 2111 | cache, env2, InnerOuter.emptyInstHierarchy, | ||
| 2112 | mod, DAE.NOPRE(), | ||
| 2113 | ci_state, c, SCode.PUBLIC(), {}, 0); | ||
| 2114 | end if; | ||
| 2115 | 94159 | (cache,res) := lookupFunctionsInEnv2(cache, env2, path, true, info); | |
| 2116 | then | ||
| 2117 | (cache,res); | ||
| 2118 | |||
| 2119 | // Did not match. Search next frame. | ||
| 2120 | case (cache, FCore.G(scope = r::_), id, false) | ||
| 2121 | algorithm | ||
| 2122 |
2/2✓ Branch 2 taken 142 times.
✓ Branch 3 taken 47794 times.
|
47936 | false := FNode.isEncapsulated(FNode.fromRef(r)); |
| 2123 | 47794 | (env, _) := FGraph.stripLastScopeRef(inEnv); | |
| 2124 | 47794 | (cache,res) := lookupFunctionsInEnv2(cache, env, id, false, info); | |
| 2125 | then | ||
| 2126 | (cache,res); | ||
| 2127 | |||
| 2128 | case (cache, FCore.G(scope = r::_), id as Absyn.IDENT(), false) | ||
| 2129 | algorithm | ||
| 2130 |
2/2✓ Branch 2 taken 43022 times.
✓ Branch 3 taken 76 times.
|
43098 | true := FNode.isEncapsulated(FNode.fromRef(r)); |
| 2131 | 76 | env := FGraph.topScope(inEnv); // (cache,env) = Builtin.initialGraph(cache); | |
| 2132 | 76 | (cache,res) := lookupFunctionsInEnv2(cache, env, id, true, info); | |
| 2133 | then | ||
| 2134 | (cache,res); | ||
| 2135 | |||
| 2136 | end matchcontinue; | ||
| 2137 | end lookupFunctionsInEnv2; | ||
| 2138 | |||
| 2139 | protected function createGenericBuiltinFunctions | ||
| 2140 | "author: PA | ||
| 2141 | This function creates function types on-the-fly for special builtin | ||
| 2142 | operators/functions which can not be represented in the builtin | ||
| 2143 | environment." | ||
| 2144 | input FCore.Graph inEnv; | ||
| 2145 | input String inString; | ||
| 2146 | output list<DAE.Type> outTypesTypeLst; | ||
| 2147 | algorithm | ||
| 2148 | outTypesTypeLst := match inString | ||
| 2149 | local | ||
| 2150 | // function_name cardinality | ||
| 2151 | case "cardinality" | ||
| 2152 | then {DAE.T_FUNCTION( | ||
| 2153 | {DAE.FUNCARG("x",DAE.T_COMPLEX(ClassInf.CONNECTOR(Absyn.IDENT("$$"),false),{},NONE(), false),DAE.C_VAR(),DAE.NON_PARALLEL(),NONE())}, | ||
| 2154 | DAE.T_INTEGER_DEFAULT, | ||
| 2155 | DAE.FUNCTION_ATTRIBUTES_DEFAULT, | ||
| 2156 | Absyn.IDENT("cardinality")), | ||
| 2157 | DAE.T_FUNCTION( | ||
| 2158 | {DAE.FUNCARG("x",DAE.T_COMPLEX(ClassInf.CONNECTOR(Absyn.IDENT("$$"),true),{},NONE(), false),DAE.C_VAR(),DAE.NON_PARALLEL(),NONE())}, | ||
| 2159 | DAE.T_INTEGER_DEFAULT, | ||
| 2160 | DAE.FUNCTION_ATTRIBUTES_DEFAULT, | ||
| 2161 | Absyn.IDENT("cardinality"))}; | ||
| 2162 | |||
| 2163 | end match; | ||
| 2164 | end createGenericBuiltinFunctions; | ||
| 2165 | |||
| 2166 | // - Internal functions | ||
| 2167 | // Type lookup | ||
| 2168 | |||
| 2169 | protected function lookupTypeInEnv | ||
| 2170 | "function: lookupTypeInEnv" | ||
| 2171 | input FCore.Cache inCache; | ||
| 2172 | input FCore.Graph inEnv; | ||
| 2173 | input String id; | ||
| 2174 | output FCore.Cache outCache; | ||
| 2175 | output DAE.Type outType; | ||
| 2176 | output FCore.Graph outEnv; | ||
| 2177 | algorithm | ||
| 2178 | (outCache,outType,outEnv):= | ||
| 2179 | matchcontinue (inCache,inEnv) | ||
| 2180 | local | ||
| 2181 | DAE.Type c; | ||
| 2182 | FCore.Graph env_1,env; | ||
| 2183 | FCore.Children httypes; | ||
| 2184 | FCore.Children ht; | ||
| 2185 | FCore.Cache cache; | ||
| 2186 | FCore.Ref r; | ||
| 2187 | |||
| 2188 | case (cache, env as FCore.G(scope = r::_)) | ||
| 2189 | algorithm | ||
| 2190 | 128752 | ht := FNode.children(FNode.fromRef(r)); | |
| 2191 | 128752 | httypes := getHtTypes(r); | |
| 2192 | 128752 | (cache,c,env_1) := lookupTypeInFrame(cache, ht, httypes, env, id); | |
| 2193 | then | ||
| 2194 | (cache,c,env_1); | ||
| 2195 | |||
| 2196 | case (cache,env as FCore.G(scope = r::_)) | ||
| 2197 | algorithm | ||
| 2198 | 117007 | (env, _) := FGraph.stripLastScopeRef(env); | |
| 2199 | 117007 | (cache,c,env_1) := lookupTypeInEnv(cache,env,id); | |
| 2200 | 7105 | env_1 := FGraph.pushScopeRef(env_1, r); | |
| 2201 | 7105 | then | |
| 2202 | (cache,c,env_1); | ||
| 2203 | end matchcontinue; | ||
| 2204 | end lookupTypeInEnv; | ||
| 2205 | |||
| 2206 | protected function getHtTypes | ||
| 2207 | input FCore.Ref inParentRef; | ||
| 2208 | output FCore.Children ht; | ||
| 2209 | algorithm | ||
| 2210 | ht := matchcontinue inParentRef | ||
| 2211 | local FCore.Ref r; | ||
| 2212 | |||
| 2213 | // there is a ty node | ||
| 2214 | case _ | ||
| 2215 | algorithm | ||
| 2216 | 280136 | r := FNode.child(inParentRef, FNode.tyNodeName); | |
| 2217 | 128557 | ht := FNode.children(FNode.fromRef(r)); | |
| 2218 | then | ||
| 2219 | ht; | ||
| 2220 | |||
| 2221 | // no ty node | ||
| 2222 | 151579 | else FCore.RefTree.new(); | |
| 2223 | end matchcontinue; | ||
| 2224 | end getHtTypes; | ||
| 2225 | |||
| 2226 | protected function lookupTypeInFrame | ||
| 2227 | "Searches a frame for a type." | ||
| 2228 | input FCore.Cache inCache; | ||
| 2229 | input FCore.Children inBinTree1; | ||
| 2230 | input FCore.Children inBinTree2; | ||
| 2231 | input FCore.Graph inEnv3; | ||
| 2232 | input SCode.Ident inIdent4; | ||
| 2233 | output FCore.Cache outCache; | ||
| 2234 | output DAE.Type outType; | ||
| 2235 | output FCore.Graph outEnv; | ||
| 2236 | algorithm | ||
| 2237 | (outCache,outType,outEnv):= | ||
| 2238 | match (inCache, inBinTree2, inEnv3, inIdent4) | ||
| 2239 | local | ||
| 2240 | DAE.Type t; | ||
| 2241 | FCore.Children httypes; | ||
| 2242 | FCore.Graph env; | ||
| 2243 | String id; | ||
| 2244 | FCore.Cache cache; | ||
| 2245 | FCore.Node item; | ||
| 2246 | |||
| 2247 | case (cache, httypes, env, id) | ||
| 2248 | algorithm | ||
| 2249 | 128752 | item := FNode.fromRef(FCore.RefTree.get(httypes, id)); | |
| 2250 | 11745 | (cache,t,env) := lookupTypeInFrame2(cache,item,env,id); | |
| 2251 | then | ||
| 2252 | (cache,t,env); | ||
| 2253 | end match; | ||
| 2254 | end lookupTypeInFrame; | ||
| 2255 | |||
| 2256 | protected function lookupTypeInFrame2 | ||
| 2257 | "Searches a frame for a type." | ||
| 2258 | input FCore.Cache inCache; | ||
| 2259 | input FCore.Node item; | ||
| 2260 | input FCore.Graph inEnv3; | ||
| 2261 | input SCode.Ident inIdent4; | ||
| 2262 | output FCore.Cache outCache; | ||
| 2263 | output DAE.Type outType; | ||
| 2264 | output FCore.Graph outEnv; | ||
| 2265 | algorithm | ||
| 2266 | (outCache,outType,outEnv):= | ||
| 2267 | match (inCache,item,inEnv3,inIdent4) | ||
| 2268 | local | ||
| 2269 | DAE.Type t,ty; | ||
| 2270 | FCore.Graph env,cenv,env_1,env_3; | ||
| 2271 | String id; | ||
| 2272 | SCode.Element cdef, comp; | ||
| 2273 | FCore.Cache cache; | ||
| 2274 | SourceInfo info; | ||
| 2275 | |||
| 2276 | 11745 | case (cache,FCore.N(data = FCore.FT(t :: _)),env,_) then (cache,t,env); | |
| 2277 | |||
| 2278 | case (_,FCore.N(data = FCore.CO(e = comp)),_,id) | ||
| 2279 | algorithm | ||
| 2280 | ✗ | info := SCodeUtil.elementInfo(comp); | |
| 2281 | ✗ | Error.addSourceMessage(Error.LOOKUP_TYPE_FOUND_COMP, {id}, info); | |
| 2282 | ✗ | then | |
| 2283 | fail(); | ||
| 2284 | |||
| 2285 | // Record constructor function | ||
| 2286 | case (cache,FCore.N(data = FCore.CL(e = cdef as SCode.CLASS(restriction=SCode.R_RECORD(_)))),env,_) | ||
| 2287 | algorithm | ||
| 2288 | ✗ | (cache,env_3,ty) := buildRecordType(cache,env,cdef); | |
| 2289 | ✗ | then | |
| 2290 | (cache,ty,env_3); | ||
| 2291 | |||
| 2292 | case (cache,FCore.N(data = FCore.CL(e = cdef as SCode.CLASS(restriction=SCode.R_METARECORD()))),env,_) | ||
| 2293 | algorithm | ||
| 2294 | ✗ | (cache,env_3,ty) := buildMetaRecordType(cache,env,cdef); | |
| 2295 | ✗ | then | |
| 2296 | (cache,ty,env_3); | ||
| 2297 | |||
| 2298 | // Found function | ||
| 2299 | case (cache,FCore.N(data = FCore.CL(e = cdef as SCode.CLASS(restriction=SCode.R_FUNCTION(_)))),env,id) | ||
| 2300 | algorithm | ||
| 2301 | // fprintln(Flags.INST_TRACE, "LOOKUP TYPE IN FRAME ICD: " + FGraph.printGraphPathStr(env) + " id:" + id); | ||
| 2302 | |||
| 2303 | // select the env if is the same as cenv as is updated! | ||
| 2304 | cenv := env; // selectUpdatedEnv(env, cenv); | ||
| 2305 | |||
| 2306 | ✗ | (cache ,env_1,_) := InstFunction.implicitFunctionInstantiation( | |
| 2307 | cache,cenv,InnerOuter.emptyInstHierarchy, | ||
| 2308 | DAE.NOMOD(), DAE.NOPRE(), cdef, {}); | ||
| 2309 | |||
| 2310 | ✗ | (cache,ty,env_3) := lookupTypeInEnv(cache, env_1, id); | |
| 2311 | then | ||
| 2312 | (cache,ty,env_3); | ||
| 2313 | |||
| 2314 | end match; | ||
| 2315 | end lookupTypeInFrame2; | ||
| 2316 | |||
| 2317 | protected function lookupFunctionsInFrame | ||
| 2318 | "This actually only looks up the function name and find all | ||
| 2319 | corresponding types that have this function name." | ||
| 2320 | input FCore.Cache inCache; | ||
| 2321 | input FCore.Children inClasses; | ||
| 2322 | input FCore.Children inFuncTypes; | ||
| 2323 | input FCore.Graph inEnv; | ||
| 2324 | input SCode.Ident inFuncName; | ||
| 2325 | input SourceInfo inInfo; | ||
| 2326 | output FCore.Cache outCache; | ||
| 2327 | output list<DAE.Type> outFuncTypes; | ||
| 2328 | protected | ||
| 2329 | FCore.Ref r; | ||
| 2330 | FNode.Data data; | ||
| 2331 | DAE.Type ty; | ||
| 2332 | algorithm | ||
| 2333 | try // Try to look up the function among the function types first. | ||
| 2334 | 151384 | r := FCore.RefTree.get(inFuncTypes, inFuncName); | |
| 2335 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 57347 times.
|
57347 | FCore.N(data = FCore.FT(outFuncTypes)) := FNode.fromRef(r); |
| 2336 | outCache := inCache; | ||
| 2337 | else // If not found, try to look the function up in the environment instead. | ||
| 2338 | 94037 | r := FCore.RefTree.get(inClasses, inFuncName); | |
| 2339 | 30850 | FCore.N(data = data) := FNode.fromRef(r); | |
| 2340 | |||
| 2341 | (outCache, outFuncTypes) := matchcontinue data | ||
| 2342 | local | ||
| 2343 | SCode.Element cl; | ||
| 2344 | list<DAE.Type> tps; | ||
| 2345 | FCore.Cache cache; | ||
| 2346 | FCore.Graph env; | ||
| 2347 | |||
| 2348 | // MetaModelica partial functions. | ||
| 2349 | case _ | ||
| 2350 | algorithm | ||
| 2351 | 30850 | DAE.TYPES_VAR(ty = ty) := FNode.refInstVar(r); | |
| 2352 | ty := match ty | ||
| 2353 | case DAE.T_FUNCTION() | ||
| 2354 | algorithm | ||
| 2355 | 368 | ty.path := Absyn.IDENT(inFuncName); | |
| 2356 | then ty; | ||
| 2357 | end match; | ||
| 2358 | 184 | then | |
| 2359 | (inCache, {ty}); | ||
| 2360 | |||
| 2361 | // Found a component, print an error. | ||
| 2362 | case FCore.CO(__) | ||
| 2363 | algorithm | ||
| 2364 | 3 | Error.addSourceMessage(Error.LOOKUP_TYPE_FOUND_COMP, {inFuncName}, inInfo); | |
| 2365 | 3 | then | |
| 2366 | fail(); | ||
| 2367 | |||
| 2368 | // A record, create a record constructor. | ||
| 2369 | case FCore.CL(e = cl as SCode.CLASS(restriction = SCode.R_RECORD(__))) | ||
| 2370 | algorithm | ||
| 2371 | 2 | (cache, _, ty) := buildRecordType(inCache, inEnv, cl); | |
| 2372 | 2 | then | |
| 2373 | (cache, {ty}); | ||
| 2374 | |||
| 2375 | // A function, instantiate to get the type. | ||
| 2376 | case FCore.CL(e = cl) guard(SCodeUtil.isFunction(cl)) | ||
| 2377 | algorithm | ||
| 2378 | 30591 | (cache, env) := InstFunction.implicitFunctionTypeInstantiation( | |
| 2379 | inCache, inEnv, InnerOuter.emptyInstHierarchy, cl); | ||
| 2380 | 26676 | (cache, tps) := lookupFunctionsInEnv2(cache, env, | |
| 2381 | Absyn.IDENT(inFuncName), true, inInfo); | ||
| 2382 | then | ||
| 2383 | (cache, tps); | ||
| 2384 | |||
| 2385 | // An external object. | ||
| 2386 | case FCore.CL(e = cl) guard(SCodeUtil.classIsExternalObject(cl)) | ||
| 2387 | algorithm | ||
| 2388 | 22 | (cache, env) := Inst.instClass(inCache, inEnv, | |
| 2389 | InnerOuter.emptyInstHierarchy, UnitAbsyn.noStore, DAE.NOMOD(), | ||
| 2390 | DAE.NOPRE(), cl, {}, false, InstTypes.TOP_CALL(), | ||
| 2391 | ConnectionGraph.EMPTY, Connect.emptySet); | ||
| 2392 | 22 | (cache, ty) := lookupTypeInEnv(cache, env, inFuncName); | |
| 2393 | 22 | then | |
| 2394 | (cache, {ty}); | ||
| 2395 | |||
| 2396 | end matchcontinue; | ||
| 2397 | end try; | ||
| 2398 | end lookupFunctionsInFrame; | ||
| 2399 | |||
| 2400 | public function selectUpdatedEnv | ||
| 2401 | input FCore.Graph inNewEnv; | ||
| 2402 | input FCore.Graph inOldEnv; | ||
| 2403 | output FCore.Graph outEnv; | ||
| 2404 | algorithm | ||
| 2405 | // return the new env only if it is not top scope and points to the same env | ||
| 2406 | ✗ | outEnv := if not FGraph.isTopScope(inNewEnv) and | |
| 2407 | stringEq(FGraph.getGraphNameStr(inNewEnv), FGraph.getGraphNameStr(inOldEnv)) | ||
| 2408 | then inNewEnv else inOldEnv; | ||
| 2409 | end selectUpdatedEnv; | ||
| 2410 | |||
| 2411 | protected function buildRecordType "" | ||
| 2412 | input FCore.Cache cache; | ||
| 2413 | input FCore.Graph env; | ||
| 2414 | input SCode.Element icdef; | ||
| 2415 | output FCore.Cache outCache; | ||
| 2416 | output FCore.Graph outEnv; | ||
| 2417 | output DAE.Type ftype; | ||
| 2418 | protected | ||
| 2419 | String name; | ||
| 2420 | SCode.Element cdef; | ||
| 2421 | algorithm | ||
| 2422 | 7 | (outCache,_,cdef) := buildRecordConstructorClass(cache,env,icdef); | |
| 2423 | 7 | name := SCodeUtil.className(cdef); | |
| 2424 | // fprintln(Flags.INST_TRACE", "LOOKUP BUILD RECORD TY ICD: " + FGraph.printGraphPathStr(env) + "." + name); | ||
| 2425 | 7 | (outCache,outEnv,_) := InstFunction.implicitFunctionTypeInstantiation( | |
| 2426 | outCache,env,InnerOuter.emptyInstHierarchy, cdef); | ||
| 2427 | 7 | (outCache,ftype,_) := lookupTypeInEnv(outCache,outEnv,name); | |
| 2428 | end buildRecordType; | ||
| 2429 | |||
| 2430 | protected function buildRecordConstructorClass | ||
| 2431 | " | ||
| 2432 | Creates the record constructor class, i.e. a function, from the record | ||
| 2433 | class given as argument." | ||
| 2434 | input FCore.Cache inCache; | ||
| 2435 | input FCore.Graph inEnv; | ||
| 2436 | input SCode.Element inClass; | ||
| 2437 | output FCore.Cache outCache; | ||
| 2438 | output FCore.Graph outEnv; | ||
| 2439 | output SCode.Element outClass; | ||
| 2440 | algorithm | ||
| 2441 | (outCache,outEnv,outClass) := | ||
| 2442 | matchcontinue (inCache,inEnv,inClass) | ||
| 2443 | local | ||
| 2444 | list<SCode.Element> funcelts; | ||
| 2445 | SCode.Element reselt; | ||
| 2446 | SCode.Element cl; | ||
| 2447 | String id; | ||
| 2448 | SourceInfo info; | ||
| 2449 | FCore.Cache cache; | ||
| 2450 | FCore.Graph env; | ||
| 2451 | |||
| 2452 | case (cache,env,cl as SCode.CLASS(name=id,info=info)) | ||
| 2453 | algorithm | ||
| 2454 | 20 | (cache,env,funcelts,_) := buildRecordConstructorClass2(cache,env,cl,DAE.NOMOD()); | |
| 2455 | 20 | reselt := buildRecordConstructorResultElt(funcelts,id,env,info); | |
| 2456 | 20 | cl := SCode.CLASS(id,SCode.defaultPrefixes,SCode.NOT_ENCAPSULATED(),SCode.NOT_PARTIAL(),SCode.R_FUNCTION(SCode.FR_RECORD_CONSTRUCTOR()),SCode.PARTS((reselt :: funcelts),{},{},{},{},{},{},NONE()),SCode.noComment,info); | |
| 2457 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
|
20 | then |
| 2458 | (cache,env,cl); | ||
| 2459 | else | ||
| 2460 | algorithm | ||
| 2461 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 2462 | ✗ | Debug.trace("buildRecordConstructorClass failed\n"); | |
| 2463 | ✗ | then fail(); | |
| 2464 | end matchcontinue; | ||
| 2465 | end buildRecordConstructorClass; | ||
| 2466 | |||
| 2467 | protected function buildRecordConstructorClass2 | ||
| 2468 | input FCore.Cache inCache; | ||
| 2469 | input FCore.Graph inEnv; | ||
| 2470 | input SCode.Element cl; | ||
| 2471 | input DAE.Mod mods; | ||
| 2472 | output FCore.Cache outCache; | ||
| 2473 | output FCore.Graph outEnv; | ||
| 2474 | output list<SCode.Element> funcelts; | ||
| 2475 | output list<SCode.Element> elts; | ||
| 2476 | algorithm | ||
| 2477 | (outCache,outEnv,funcelts,elts) := matchcontinue(inCache, inEnv, cl) | ||
| 2478 | local | ||
| 2479 | list<SCode.Element> cdefelts,classExtendsElts,extendsElts,compElts; | ||
| 2480 | list<tuple<SCode.Element,DAE.Mod>> eltsMods; | ||
| 2481 | String name; | ||
| 2482 | Absyn.Path fpath; | ||
| 2483 | SourceInfo info; | ||
| 2484 | FCore.Cache cache; | ||
| 2485 | FCore.Graph env,env1; | ||
| 2486 | |||
| 2487 | // a class with parts | ||
| 2488 | case (cache, env, SCode.CLASS(name = name,info = info)) | ||
| 2489 | algorithm | ||
| 2490 | 20 | (cache,env,_,elts,_,_,_,_,_) := InstExtends.instDerivedClasses(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOMOD(),DAE.NOPRE(),cl,true,info); | |
| 2491 | 20 | env := FGraph.openScope(env, SCode.NOT_ENCAPSULATED(), name, SOME(FCore.CLASS_SCOPE())); | |
| 2492 | 20 | fpath := FGraph.getGraphName(env); | |
| 2493 | 20 | (cdefelts,classExtendsElts,extendsElts,compElts) := InstUtil.splitElts(elts); | |
| 2494 | 20 | (cache,env,_,_,eltsMods,_,_,_,_) := InstExtends.instExtendsAndClassExtendsList(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOMOD(), DAE.NOPRE(), extendsElts, classExtendsElts, elts, ClassInf.RECORD(fpath), name, true, false); | |
| 2495 | 20 | eltsMods := listAppend(eltsMods,InstUtil.addNomod(compElts)) annotation(__OpenModelica_DisableListAppendWarning=true); | |
| 2496 | // print("Record Elements: " + | ||
| 2497 | // stringDelimitList( | ||
| 2498 | // List.map( | ||
| 2499 | // List.map( | ||
| 2500 | // eltsMods, | ||
| 2501 | // Util.tuple21), | ||
| 2502 | // SCodeDump.printElementStr), "\n")); | ||
| 2503 | 20 | (cache, env1, _) := InstUtil.addClassdefsToEnv(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), cdefelts, false, NONE()); | |
| 2504 | 20 | (cache, env1, _) := InstUtil.addComponentsToEnv(cache, env1, InnerOuter.emptyInstHierarchy, mods, DAE.NOPRE(), ClassInf.RECORD(fpath), eltsMods, true); | |
| 2505 | 20 | (cache, env1, funcelts) := buildRecordConstructorElts(cache,env1,eltsMods,mods); | |
| 2506 |
1/2✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
|
20 | then (cache,env1,funcelts,elts); |
| 2507 | |||
| 2508 | // fail | ||
| 2509 | else algorithm | ||
| 2510 | ✗ | Debug.traceln("buildRecordConstructorClass2 failed, cl:"+SCodeDump.unparseElementStr(cl,SCodeDump.defaultOptions)+"\n"); | |
| 2511 | ✗ | then fail(); | |
| 2512 | /* TODO: short class defs */ | ||
| 2513 | end matchcontinue; | ||
| 2514 | end buildRecordConstructorClass2; | ||
| 2515 | |||
| 2516 | protected function selectModifier | ||
| 2517 | "@author: adrpo | ||
| 2518 | if the first modifier is empty (NOMOD) use the second one!" | ||
| 2519 | input DAE.Mod inModID; | ||
| 2520 | input DAE.Mod inModNoID; | ||
| 2521 | output DAE.Mod outMod; | ||
| 2522 | algorithm | ||
| 2523 | outMod := match inModID | ||
| 2524 | case DAE.NOMOD() then inModNoID; | ||
| 2525 | else inModID; | ||
| 2526 | end match; | ||
| 2527 | end selectModifier; | ||
| 2528 | |||
| 2529 | protected function buildRecordConstructorElts | ||
| 2530 | "Helper function to build_record_constructor_class. Creates the elements | ||
| 2531 | of the function class. | ||
| 2532 | |||
| 2533 | TODO: This function should be replaced by a proper instantiation using instClassIn instead, followed by a | ||
| 2534 | traversal of the DAE.Var changing direction to input. | ||
| 2535 | Reason for not doing that now: records can contain arrays with unknown dimensions." | ||
| 2536 | input FCore.Cache inCache; | ||
| 2537 | input FCore.Graph inEnv; | ||
| 2538 | input list<tuple<SCode.Element,DAE.Mod>> inSCodeElementLst; | ||
| 2539 | input DAE.Mod mods; | ||
| 2540 | output FCore.Cache outCache; | ||
| 2541 | output FCore.Graph outEnv; | ||
| 2542 | output list<SCode.Element> outSCodeElementLst; | ||
| 2543 | algorithm | ||
| 2544 | (outCache, outEnv, outSCodeElementLst) := matchcontinue (inCache, inEnv, inSCodeElementLst) | ||
| 2545 | local | ||
| 2546 | FCore.Cache cache; | ||
| 2547 | FCore.Graph env; | ||
| 2548 | list<tuple<SCode.Element,DAE.Mod>> rest; | ||
| 2549 | list<SCode.Element> res; | ||
| 2550 | SCode.Element comp; | ||
| 2551 | String id; | ||
| 2552 | SCode.ConnectorType ct; | ||
| 2553 | SCode.Replaceable repl; | ||
| 2554 | SCode.Visibility vis; | ||
| 2555 | SCode.Final f; | ||
| 2556 | SCode.Redeclare redecl; | ||
| 2557 | Absyn.InnerOuter io; | ||
| 2558 | list<Absyn.Subscript> d; | ||
| 2559 | SCode.Parallelism prl; | ||
| 2560 | SCode.Variability var; | ||
| 2561 | Absyn.IsField isf; | ||
| 2562 | Absyn.Direction dir; | ||
| 2563 | Absyn.TypeSpec tp; | ||
| 2564 | SCode.Comment comment; | ||
| 2565 | Option<Absyn.Exp> cond; | ||
| 2566 | SCode.Mod mod,umod; | ||
| 2567 | DAE.Mod mod_1, compMod, fullMod, selectedMod, cmod; | ||
| 2568 | SourceInfo info; | ||
| 2569 | |||
| 2570 | case (cache, env, {}) then (cache,env,{}); | ||
| 2571 | |||
| 2572 | // final becomes protected, Modelica Spec 3.2, Section 12.6, Record Constructor Functions, page 140 | ||
| 2573 | case (cache, env, ((( SCode.COMPONENT( | ||
| 2574 | id, | ||
| 2575 | SCode.PREFIXES(_, redecl, f as SCode.FINAL(), io, repl), | ||
| 2576 | SCode.ATTR(d,ct,prl,var,_,isf),tp,mod,comment,cond,info)),cmod) :: rest)) | ||
| 2577 | algorithm | ||
| 2578 | ✗ | (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info); | |
| 2579 | ✗ | mod_1 := Mod.merge(mods,mod_1); | |
| 2580 | // adrpo: this was wrong, you won't find any id modification there!!! | ||
| 2581 | // bjozac: This was right, you will find id modification unless modifers does not belong to component! | ||
| 2582 | // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty! | ||
| 2583 | ✗ | compMod := Mod.lookupCompModification(mod_1,id); | |
| 2584 | ✗ | fullMod := mod_1; | |
| 2585 | ✗ | selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one. | |
| 2586 | ✗ | (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info); | |
| 2587 | ✗ | selectedMod := Mod.merge(cmod,selectedMod); | |
| 2588 | ✗ | umod := Mod.unelabMod(selectedMod); | |
| 2589 | ✗ | (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods); | |
| 2590 | // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed. | ||
| 2591 | // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability! | ||
| 2592 | // mahge: 2013-01-15 : direction should be set to bidir. | ||
| 2593 | // var = SCode.VAR(); | ||
| 2594 | dir := Absyn.BIDIR(); | ||
| 2595 | vis := SCode.PROTECTED(); | ||
| 2596 | ✗ | then | |
| 2597 | (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis,redecl, f,io,repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res); | ||
| 2598 | |||
| 2599 | // constants become protected, Modelica Spec 3.2, Section 12.6, Record Constructor Functions, page 140 | ||
| 2600 | // mahge: 2013-01-15 : only if they have bindings. otherwise they are still modifiable. | ||
| 2601 | case (cache, env, ((( SCode.COMPONENT( | ||
| 2602 | id, | ||
| 2603 | SCode.PREFIXES(vis, redecl, _, io, repl), | ||
| 2604 | SCode.ATTR(d,ct,prl,SCode.CONST(),_,isf),tp,mod as SCode.NOMOD(),comment,cond,info)), cmod) :: rest)) | ||
| 2605 | algorithm | ||
| 2606 | ✗ | (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info); | |
| 2607 | ✗ | mod_1 := Mod.merge(mods,mod_1); | |
| 2608 | // adrpo: this was wrong, you won't find any id modification there!!! | ||
| 2609 | // bjozac: This was right, you will find id modification unless modifers does not belong to component! | ||
| 2610 | // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty! | ||
| 2611 | ✗ | compMod := Mod.lookupCompModification(mod_1,id); | |
| 2612 | ✗ | fullMod := mod_1; | |
| 2613 | ✗ | selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one. | |
| 2614 | ✗ | (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info); | |
| 2615 | ✗ | selectedMod := Mod.merge(cmod,selectedMod); | |
| 2616 | ✗ | umod := Mod.unelabMod(selectedMod); | |
| 2617 | ✗ | (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods); | |
| 2618 | // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed. | ||
| 2619 | // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability! | ||
| 2620 | var := SCode.VAR(); | ||
| 2621 | dir := Absyn.INPUT(); | ||
| 2622 | vis := SCode.PUBLIC(); | ||
| 2623 | f := SCode.NOT_FINAL(); | ||
| 2624 | ✗ | then | |
| 2625 | (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis,redecl,f,io,repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res); | ||
| 2626 | |||
| 2627 | |||
| 2628 | case (cache, env, ((( SCode.COMPONENT( | ||
| 2629 | id, | ||
| 2630 | SCode.PREFIXES(_, redecl, f, io, repl), | ||
| 2631 | SCode.ATTR(d,ct,prl,var as SCode.CONST(),_,isf),tp,mod,comment,cond,info)),cmod) :: rest)) | ||
| 2632 | algorithm | ||
| 2633 | ✗ | (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info); | |
| 2634 | ✗ | mod_1 := Mod.merge(mods,mod_1); | |
| 2635 | // adrpo: this was wrong, you won't find any id modification there!!! | ||
| 2636 | // bjozac: This was right, you will find id modification unless modifers does not belong to component! | ||
| 2637 | // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty! | ||
| 2638 | ✗ | compMod := Mod.lookupCompModification(mod_1,id); | |
| 2639 | ✗ | fullMod := mod_1; | |
| 2640 | ✗ | selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one. | |
| 2641 | ✗ | (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info); | |
| 2642 | ✗ | selectedMod := Mod.merge(cmod,selectedMod); | |
| 2643 | ✗ | umod := Mod.unelabMod(selectedMod); | |
| 2644 | ✗ | (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods); | |
| 2645 | // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed. | ||
| 2646 | // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability! | ||
| 2647 | // mahge: 2013-01-15 : direction should be set to bidir. | ||
| 2648 | // var = SCode.VAR(); | ||
| 2649 | dir := Absyn.BIDIR(); | ||
| 2650 | vis := SCode.PROTECTED(); | ||
| 2651 | ✗ | then | |
| 2652 | (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis,redecl,f,io,repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res); | ||
| 2653 | |||
| 2654 | // all others, add input see Modelica Spec 3.2, Section 12.6, Record Constructor Functions, page 140 | ||
| 2655 | case (cache, env, ((( SCode.COMPONENT( | ||
| 2656 | id, | ||
| 2657 | SCode.PREFIXES(_, redecl, _, io, repl), | ||
| 2658 | SCode.ATTR(d,ct,prl,_,_,isf),tp,mod,comment,cond,info)),cmod) :: rest)) | ||
| 2659 | algorithm | ||
| 2660 | 147 | (cache,mod_1) := Mod.elabMod(cache, env, InnerOuter.emptyInstHierarchy, DAE.NOPRE(), mod, true, Mod.COMPONENT(id), info); | |
| 2661 | 147 | mod_1 := Mod.merge(mods,mod_1); | |
| 2662 | // adrpo: this was wrong, you won't find any id modification there!!! | ||
| 2663 | // bjozac: This was right, you will find id modification unless modifers does not belong to component! | ||
| 2664 | // adrpo 2009-11-23 -> solved by selecting the full modifier if the component modifier is empty! | ||
| 2665 | 147 | compMod := Mod.lookupCompModification(mod_1,id); | |
| 2666 | 147 | fullMod := mod_1; | |
| 2667 | 147 | selectedMod := selectModifier(compMod, fullMod); // if the first one is empty use the other one. | |
| 2668 | 147 | (cache,cmod) := Mod.updateMod(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOPRE(),cmod,true,info); | |
| 2669 | 147 | selectedMod := Mod.merge(cmod,selectedMod); | |
| 2670 | 147 | umod := Mod.unelabMod(selectedMod); | |
| 2671 | 147 | (cache, env, res) := buildRecordConstructorElts(cache, env, rest, mods); | |
| 2672 | // - Prefixes (constant, parameter, final, discrete, input, output, ...) of the remaining record components are removed. | ||
| 2673 | // adrpo: 2010-11-09 : TODO! FIXME! why is this?? keep the variability! | ||
| 2674 | var := SCode.VAR(); | ||
| 2675 | vis := SCode.PUBLIC(); | ||
| 2676 | f := SCode.NOT_FINAL(); | ||
| 2677 | dir := Absyn.INPUT(); | ||
| 2678 | 147 | then | |
| 2679 | (cache, env, SCode.COMPONENT(id,SCode.PREFIXES(vis, redecl, f, io, repl),SCode.ATTR(d,ct,prl,var,dir,isf),tp,umod,comment,cond,info) :: res); | ||
| 2680 | |||
| 2681 | case (_, _, (comp,cmod)::_) | ||
| 2682 | algorithm | ||
| 2683 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 2684 | ✗ | Debug.traceln("- Lookup.buildRecordConstructorElts failed " + SCodeDump.unparseElementStr(comp,SCodeDump.defaultOptions) + " with mod: " + Mod.printModStr(cmod) + " and: " + Mod.printModStr(mods)); | |
| 2685 | ✗ | then fail(); | |
| 2686 | end matchcontinue; | ||
| 2687 | end buildRecordConstructorElts; | ||
| 2688 | |||
| 2689 | protected function buildRecordConstructorResultElt | ||
| 2690 | "This function builds the result element of a | ||
| 2691 | record constructor function, i.e. the returned variable" | ||
| 2692 | input list<SCode.Element> elts; | ||
| 2693 | input SCode.Ident id; | ||
| 2694 | input FCore.Graph env; | ||
| 2695 | input SourceInfo info; | ||
| 2696 | output SCode.Element outElement; | ||
| 2697 | algorithm | ||
| 2698 | //print(" creating element of type: " + id + "\n"); | ||
| 2699 | //print(" with generated mods:" + SCodeUtil.printSubs1Str(submodlst) + "\n"); | ||
| 2700 | //print(" creating element of type: " + id + "\n"); | ||
| 2701 | //print(" with generated mods:" + SCodeUtil.printSubs1Str(submodlst) + "\n"); | ||
| 2702 | ✗ | outElement := SCode.COMPONENT("result",SCode.defaultPrefixes, | |
| 2703 | SCode.ATTR({},SCode.POTENTIAL(),SCode.NON_PARALLEL(),SCode.VAR(),Absyn.OUTPUT(),Absyn.NONFIELD()), | ||
| 2704 | Absyn.TPATH(Absyn.IDENT(id),NONE()), | ||
| 2705 | SCode.NOMOD(),SCode.noComment,NONE(),info); | ||
| 2706 | annotation(__OpenModelica_EarlyInline = true); | ||
| 2707 | end buildRecordConstructorResultElt; | ||
| 2708 | |||
| 2709 | protected function lookupClassInEnv | ||
| 2710 | "Helper function to lookupClass2. Searches the environment for the class. | ||
| 2711 | It first checks the current scope, and then base classes. The specification | ||
| 2712 | says that we first search elements in the current scope (+ the ones inherited | ||
| 2713 | from base classes)" | ||
| 2714 | input FCore.Cache inCache; | ||
| 2715 | input FCore.Graph inEnv; | ||
| 2716 | input String id; | ||
| 2717 | input FCore.Scope inPrevFrames; | ||
| 2718 | input Mutable<Boolean> inState; | ||
| 2719 | input Option<SourceInfo> inInfo; | ||
| 2720 | output FCore.Cache outCache; | ||
| 2721 | output SCode.Element outClass; | ||
| 2722 | output FCore.Graph outEnv; | ||
| 2723 | output FCore.Scope outPrevFrames; | ||
| 2724 | algorithm | ||
| 2725 | (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inEnv, inPrevFrames, inInfo) | ||
| 2726 | local | ||
| 2727 | SCode.Element c; | ||
| 2728 | FCore.Graph env_1,env,i_env; | ||
| 2729 | FCore.Scope prevFrames; | ||
| 2730 | FCore.Node frame; | ||
| 2731 | FCore.Ref r; | ||
| 2732 | String sid,scope; | ||
| 2733 | FCore.Cache cache; | ||
| 2734 | SourceInfo info; | ||
| 2735 | |||
| 2736 | case (cache, env as FCore.G(scope = r::_), prevFrames, _) | ||
| 2737 | algorithm | ||
| 2738 | 9871673 | frame := FNode.fromRef(r); | |
| 2739 | 9871673 | (cache,c,env_1,prevFrames) := lookupClassInFrame(cache, frame, env, id, prevFrames, inState, inInfo); | |
| 2740 | 3884447 | Mutable.update(inState,true); | |
| 2741 | 3884447 | then | |
| 2742 | (cache,c,env_1,prevFrames); | ||
| 2743 | |||
| 2744 | case (cache, env as FCore.G(scope = r :: _), prevFrames, _) | ||
| 2745 | algorithm | ||
| 2746 |
2/2✓ Branch 1 taken 474653 times.
✓ Branch 2 taken 5512573 times.
|
5987226 | false := FNode.isRefTop(r); |
| 2747 | 5512573 | frame := FNode.fromRef(r); | |
| 2748 | 5512573 | sid := FNode.refName(r); | |
| 2749 |
2/2✓ Branch 1 taken 5244699 times.
✓ Branch 2 taken 267874 times.
|
5512573 | true := FNode.isEncapsulated(frame); |
| 2750 |
4/4✓ Branch 0 taken 9922 times.
✓ Branch 1 taken 257952 times.
✓ Branch 3 taken 7020 times.
✓ Branch 4 taken 2902 times.
|
267874 | true := stringEq(id, sid) "Special case if looking up the class that -is- encapsulated. That must be allowed." ; |
| 2751 | 7020 | (env, _) := FGraph.stripLastScopeRef(env); | |
| 2752 | 7020 | (cache,c,env,prevFrames) := lookupClassInEnv(cache, env, id, r::prevFrames, inState, inInfo); | |
| 2753 | 7020 | Mutable.update(inState,true); | |
| 2754 | 7020 | then | |
| 2755 | (cache,c,env,prevFrames); | ||
| 2756 | |||
| 2757 | // lookup stops at encapsulated classes except for builtin | ||
| 2758 | // scope, if not found in builtin scope, error | ||
| 2759 | case (cache, env as FCore.G(scope = r :: _), _, SOME(info)) | ||
| 2760 | algorithm | ||
| 2761 |
2/2✓ Branch 1 taken 45 times.
✓ Branch 2 taken 2613331 times.
|
2613376 | false := FNode.isRefTop(r); |
| 2762 | 2613331 | frame := FNode.fromRef(r); | |
| 2763 |
2/2✓ Branch 1 taken 2427354 times.
✓ Branch 2 taken 185977 times.
|
2613331 | true := FNode.isEncapsulated(frame); |
| 2764 | 185977 | i_env := FGraph.topScope(env); | |
| 2765 |
2/2✓ Branch 0 taken 185977 times.
✓ Branch 1 taken 22 times.
|
185999 | failure(lookupClassInEnv(cache, i_env, id, {}, inState, NONE())); |
| 2766 | 22 | scope := FGraph.printGraphPathStr(env); | |
| 2767 | 22 | Error.addSourceMessage(Error.LOOKUP_ERROR, {id,scope}, info); | |
| 2768 | 22 | then | |
| 2769 | fail(); | ||
| 2770 | |||
| 2771 | // lookup stops at encapsulated classes, except for builtin scope | ||
| 2772 | case (cache, env as FCore.G(scope = r::_), prevFrames, _) | ||
| 2773 | algorithm | ||
| 2774 | 5980206 | frame := FNode.fromRef(r); | |
| 2775 |
2/2✓ Branch 1 taken 5719352 times.
✓ Branch 2 taken 260854 times.
|
5980206 | true := FNode.isEncapsulated(frame); |
| 2776 | 260854 | i_env := FGraph.topScope(env); | |
| 2777 | 260854 | (cache,c,env_1,prevFrames) := lookupClassInEnv(cache, i_env, id, {}, inState, inInfo); | |
| 2778 | 223477 | Mutable.update(inState,true); | |
| 2779 | 223477 | then | |
| 2780 | (cache,c,env_1,prevFrames); | ||
| 2781 | |||
| 2782 | // if not found and not encapsulated, and no ident has been previously found, look in next enclosing scope | ||
| 2783 | case (cache, env as FCore.G(scope = r::_), prevFrames, _) | ||
| 2784 | algorithm | ||
| 2785 |
2/2✓ Branch 1 taken 474653 times.
✓ Branch 2 taken 5282076 times.
|
5756729 | false := FNode.isRefTop(r); |
| 2786 | 5282076 | frame := FNode.fromRef(r); | |
| 2787 |
2/2✓ Branch 1 taken 37377 times.
✓ Branch 2 taken 5244699 times.
|
5282076 | false := FNode.isEncapsulated(frame); |
| 2788 |
2/2✓ Branch 1 taken 686407 times.
✓ Branch 2 taken 4558292 times.
|
5244699 | false := Mutable.access(inState); |
| 2789 | 4558292 | (env, _) := FGraph.stripLastScopeRef(env); | |
| 2790 | 4558292 | (cache,c,env_1,prevFrames) := lookupClassInEnv(cache, env, id, r::prevFrames, inState, inInfo); | |
| 2791 | 3512445 | Mutable.update(inState, true); | |
| 2792 | 3512445 | then | |
| 2793 | (cache,c,env_1,prevFrames); | ||
| 2794 | |||
| 2795 | end matchcontinue; | ||
| 2796 | end lookupClassInEnv; | ||
| 2797 | |||
| 2798 | protected function lookupClassInFrame "Search for a class within one frame." | ||
| 2799 | input FCore.Cache inCache; | ||
| 2800 | input FCore.Node inFrame; | ||
| 2801 | input FCore.Graph inEnv; | ||
| 2802 | input SCode.Ident inIdent; | ||
| 2803 | input FCore.Scope inPrevFrames; | ||
| 2804 | input Mutable<Boolean> inState; | ||
| 2805 | input Option<SourceInfo> inInfo; | ||
| 2806 | output FCore.Cache outCache; | ||
| 2807 | output SCode.Element outClass; | ||
| 2808 | output FCore.Graph outEnv; | ||
| 2809 | output FCore.Scope outPrevFrames; | ||
| 2810 | algorithm | ||
| 2811 | (outCache,outClass,outEnv,outPrevFrames) := matchcontinue (inCache, inFrame, inEnv, inIdent, inPrevFrames) | ||
| 2812 | local | ||
| 2813 | SCode.Element c; | ||
| 2814 | FCore.Graph totenv,env_1; | ||
| 2815 | FCore.Scope prevFrames; | ||
| 2816 | FCore.Ref r; | ||
| 2817 | FCore.Children ht; | ||
| 2818 | String name; | ||
| 2819 | list<Absyn.Import> qimports, uqimports; | ||
| 2820 | FCore.Cache cache; | ||
| 2821 | Boolean unique; | ||
| 2822 | |||
| 2823 | // Check this scope for class | ||
| 2824 | case (cache, FCore.N(children = ht), totenv, name, prevFrames) | ||
| 2825 | algorithm | ||
| 2826 | 9871673 | r := FCore.RefTree.get(ht, name); | |
| 2827 |
2/2✓ Branch 1 taken 126954 times.
✓ Branch 2 taken 3767623 times.
|
3894577 | FCore.N(data = FCore.CL(e = c)) := FNode.fromRef(r); |
| 2828 | 3767623 | then | |
| 2829 | (cache,c,totenv,prevFrames); | ||
| 2830 | |||
| 2831 | // Search in imports | ||
| 2832 | case (cache, _, totenv, name, _) | ||
| 2833 | algorithm | ||
| 2834 | 6104050 | (qimports, uqimports) := FNode.imports(inFrame); | |
| 2835 | try | ||
| 2836 | // Search among the qualified imports, e.g. import A.B; or import D=A.B; | ||
| 2837 |
2/2✓ Branch 0 taken 680 times.
✓ Branch 1 taken 325531 times.
|
326211 | false := listEmpty(qimports); |
| 2838 | 325531 | (cache,c,env_1,prevFrames) := lookupQualifiedImportedClassInFrame(cache,qimports,totenv,name,inState,inInfo); | |
| 2839 | else | ||
| 2840 | // Search among the unqualified imports, e.g. import A.B.*; | ||
| 2841 |
2/2✓ Branch 0 taken 208760 times.
✓ Branch 1 taken 1627 times.
|
210387 | false := listEmpty(uqimports); |
| 2842 | 1627 | (cache,c,env_1,prevFrames,unique) := lookupUnqualifiedImportedClassInFrame(cache,uqimports,totenv,name,inInfo); | |
| 2843 | 1000 | Mutable.update(inState,true); | |
| 2844 | 1000 | reportSeveralNamesError(unique,name); | |
| 2845 | end try; | ||
| 2846 | 116824 | then | |
| 2847 | (cache,c,env_1,prevFrames); | ||
| 2848 | |||
| 2849 | end matchcontinue; | ||
| 2850 | end lookupClassInFrame; | ||
| 2851 | |||
| 2852 | protected function reportSeveralNamesError | ||
| 2853 | "given a boolean, report error message of importing several names | ||
| 2854 | if boolean flag is false and fail. If flag is true succeed and do nothing." | ||
| 2855 | input Boolean unique; | ||
| 2856 | input String name; | ||
| 2857 | algorithm | ||
| 2858 | () := match unique | ||
| 2859 | |||
| 2860 | case true then (); | ||
| 2861 | |||
| 2862 | case false | ||
| 2863 | algorithm | ||
| 2864 | ✗ | Error.addMessage(Error.IMPORT_SEVERAL_NAMES, {name}); | |
| 2865 | then (); | ||
| 2866 | |||
| 2867 | end match; | ||
| 2868 | end reportSeveralNamesError; | ||
| 2869 | |||
| 2870 | protected function lookupVar2 | ||
| 2871 | "Helper function to lookupVarF and lookupIdent." | ||
| 2872 | input FCore.Children inBinTree; | ||
| 2873 | input SCode.Ident inIdent; | ||
| 2874 | input FCore.Graph inGraph; | ||
| 2875 | output DAE.Var outVar; | ||
| 2876 | output SCode.Element outElement; | ||
| 2877 | output DAE.Mod outMod; | ||
| 2878 | output FCore.Status instStatus; | ||
| 2879 | output FCore.Graph outEnv; | ||
| 2880 | protected | ||
| 2881 | FCore.Ref r; | ||
| 2882 | FCore.Scope s; | ||
| 2883 | FCore.Node n; | ||
| 2884 | String name; | ||
| 2885 | algorithm | ||
| 2886 | 13640687 | r := FCore.RefTree.get(inBinTree, inIdent); | |
| 2887 | 4524783 | outVar := FNode.refInstVar(r); | |
| 2888 | 3284366 | s := FNode.refRefTargetScope(r); | |
| 2889 | 3284366 | n := FNode.fromRef(r); | |
| 2890 | |||
| 2891 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 3284366 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
3284366 | if not FNode.isComponent(n) and Flags.isSet(Flags.LOOKUP) then |
| 2892 | // MetaModelica function references generate too much failtrace... | ||
| 2893 | ✗ | false := Config.acceptMetaModelicaGrammar(); | |
| 2894 | ✗ | FCore.N(data = FCore.CL(e = SCode.CLASS(name = name))) := n; | |
| 2895 | ✗ | name := inIdent + " = " + FGraph.printGraphPathStr(inGraph) + "." + name; | |
| 2896 | ✗ | Debug.traceln("- Lookup.lookupVar2 failed because we found a class instead of a variable: " + name); | |
| 2897 | ✗ | fail(); | |
| 2898 | end if; | ||
| 2899 | |||
| 2900 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3284366 times.
|
3284366 | FCore.N(data = FCore.CO(outElement, outMod, _, instStatus)) := n; |
| 2901 | 3284366 | outEnv := FGraph.setScope(inGraph, s); | |
| 2902 | end lookupVar2; | ||
| 2903 | |||
| 2904 | protected function checkSubscripts "This function checks a list of subscripts agains type, and removes | ||
| 2905 | dimensions from the type according to the subscripting." | ||
| 2906 | input DAE.Type inType; | ||
| 2907 | input list<DAE.Subscript> inExpSubscriptLst; | ||
| 2908 | output DAE.Type outType; | ||
| 2909 | algorithm | ||
| 2910 | outType := matchcontinue (inType,inExpSubscriptLst) | ||
| 2911 | local | ||
| 2912 | DAE.Type t,t_1; | ||
| 2913 | DAE.Dimension dim; | ||
| 2914 | list<DAE.Subscript> ys,s; | ||
| 2915 | Integer sz,ind,dim_int; | ||
| 2916 | list<DAE.Exp> se; | ||
| 2917 | DAE.Exp e; | ||
| 2918 | |||
| 2919 | // empty case | ||
| 2920 | case (t,{}) then t; | ||
| 2921 | |||
| 2922 | case (DAE.T_ARRAY(dims = {dim},ty = t),(DAE.WHOLEDIM() :: ys)) | ||
| 2923 | algorithm | ||
| 2924 | 1533 | t_1 := checkSubscripts(t, ys); | |
| 2925 | 1533 | then | |
| 2926 | DAE.T_ARRAY(t_1,{dim}); | ||
| 2927 | |||
| 2928 | case (DAE.T_ARRAY(dims = {_}, ty = t), | ||
| 2929 | DAE.SLICE(exp = e as DAE.RANGE()) :: ys) | ||
| 2930 | algorithm | ||
| 2931 | 44 | t_1 := checkSubscripts(t, ys); | |
| 2932 | 44 | dim_int := Expression.rangeSize(e); | |
| 2933 | ✗ | then | |
| 2934 | DAE.T_ARRAY(t_1, {DAE.DIM_INTEGER(dim_int)}); | ||
| 2935 | |||
| 2936 | case (DAE.T_ARRAY(dims = {dim}, ty = t), | ||
| 2937 | (DAE.SLICE(exp = DAE.ARRAY(array = se)) :: ys)) | ||
| 2938 | algorithm | ||
| 2939 | 995 | Expression.dimensionSize(dim); | |
| 2940 | 991 | t_1 := checkSubscripts(t, ys); | |
| 2941 | 991 | dim_int := listLength(se) "FIXME: Check range IMPLEMENTED 2007-05-18 BZ" ; | |
| 2942 | 1982 | then | |
| 2943 | DAE.T_ARRAY(t_1,{DAE.DIM_INTEGER(dim_int)}); | ||
| 2944 | |||
| 2945 | case (DAE.T_ARRAY(dims = {_}, ty = t), | ||
| 2946 | (DAE.SLICE(exp = e) :: ys)) | ||
| 2947 | algorithm | ||
| 2948 |
3/6✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 49 times.
|
49 | DAE.T_ARRAY(dims={dim}) := Expression.typeof(e); |
| 2949 | 49 | t_1 := checkSubscripts(t, ys); | |
| 2950 | 49 | then | |
| 2951 | DAE.T_ARRAY(t_1, {dim}); | ||
| 2952 | |||
| 2953 | case (DAE.T_ARRAY(dims = {dim}, ty = t), | ||
| 2954 | (DAE.INDEX(exp = DAE.ICONST(integer = ind)) :: ys)) | ||
| 2955 | algorithm | ||
| 2956 | 342904 | sz := Expression.dimensionSize(dim); | |
| 2957 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 342434 times.
|
342435 | true := (ind > 0); |
| 2958 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 342434 times.
|
342434 | true := (ind <= sz); |
| 2959 | 342434 | t_1 := checkSubscripts(t, ys); | |
| 2960 | then | ||
| 2961 | t_1; | ||
| 2962 | |||
| 2963 | // HJ: Subscripts needn't be constant. No range-checking can be done | ||
| 2964 | case (DAE.T_ARRAY(dims = {dim}, ty = t), | ||
| 2965 | (DAE.INDEX() :: ys)) | ||
| 2966 | algorithm | ||
| 2967 |
2/2✓ Branch 1 taken 878 times.
✓ Branch 2 taken 7474 times.
|
8352 | true := Expression.dimensionKnown(dim); |
| 2968 | 7474 | t_1 := checkSubscripts(t, ys); | |
| 2969 | then | ||
| 2970 | t_1; | ||
| 2971 | |||
| 2972 | case (DAE.T_ARRAY(dims = {DAE.DIM_UNKNOWN()}, ty = t), | ||
| 2973 | (DAE.INDEX() :: ys)) | ||
| 2974 | algorithm | ||
| 2975 | 642 | t_1 := checkSubscripts(t, ys); | |
| 2976 | then | ||
| 2977 | t_1; | ||
| 2978 | |||
| 2979 | case (DAE.T_ARRAY(dims = {DAE.DIM_EXP()}, ty = t), | ||
| 2980 | (DAE.INDEX() :: ys)) | ||
| 2981 | algorithm | ||
| 2982 | 236 | t_1 := checkSubscripts(t, ys); | |
| 2983 | then | ||
| 2984 | t_1; | ||
| 2985 | |||
| 2986 | case (DAE.T_ARRAY(ty = t), | ||
| 2987 | (DAE.WHOLEDIM() :: ys)) | ||
| 2988 | algorithm | ||
| 2989 | ✗ | t_1 := checkSubscripts(t, ys); | |
| 2990 | then | ||
| 2991 | t_1; | ||
| 2992 | |||
| 2993 | case (DAE.T_SUBTYPE_BASIC(complexType = t),ys) | ||
| 2994 | 25 | then checkSubscripts(t,ys); | |
| 2995 | |||
| 2996 | case(t as DAE.T_UNKNOWN(), _) then t; | ||
| 2997 | |||
| 2998 | ✗ | case (DAE.T_METAARRAY(), {DAE.INDEX()}) then inType.ty; | |
| 2999 | case (DAE.T_METAARRAY(), {_}) then inType; | ||
| 3000 | |||
| 3001 | case (t,s) | ||
| 3002 | algorithm | ||
| 3003 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 3004 | ✗ | Debug.trace("- Lookup.checkSubscripts failed (tp: "); | |
| 3005 | ✗ | Debug.trace(TypesDump.printTypeStr(t)); | |
| 3006 | ✗ | Debug.trace(" subs:"); | |
| 3007 | ✗ | Debug.trace(stringDelimitList(List.map(s,ExpressionBasics.printSubscriptStr),",")); | |
| 3008 | ✗ | Debug.trace(")\n"); | |
| 3009 | ✗ | then | |
| 3010 | fail(); | ||
| 3011 | end matchcontinue; | ||
| 3012 | end checkSubscripts; | ||
| 3013 | |||
| 3014 | protected function lookupVarF | ||
| 3015 | "This function looks in a frame to find a declared variable. If | ||
| 3016 | the name being looked up is qualified, the first part of the name | ||
| 3017 | is looked up, and lookupVar2 is used to for further lookup in | ||
| 3018 | the result of that lookup. | ||
| 3019 | 2007-05-29 If we can construct a expression, we do after expanding the | ||
| 3020 | subscript with dimensions to fill the Cref." | ||
| 3021 | input FCore.Cache inCache; | ||
| 3022 | input FCore.Children inBinTree; | ||
| 3023 | input DAE.ComponentRef inComponentRef; | ||
| 3024 | input FCore.Graph inEnv; | ||
| 3025 | output FCore.Cache outCache; | ||
| 3026 | output DAE.Attributes outAttributes; | ||
| 3027 | output DAE.Type outType; | ||
| 3028 | output DAE.Binding outBinding; | ||
| 3029 | output Option<DAE.Const> constOfForIteratorRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 3030 | output InstTypes.SplicedExpData splicedExpData; | ||
| 3031 | output FCore.Graph outComponentEnv; | ||
| 3032 | output String name; | ||
| 3033 | algorithm | ||
| 3034 | (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) := | ||
| 3035 | match (inCache, inBinTree, inComponentRef) | ||
| 3036 | local | ||
| 3037 | String id; | ||
| 3038 | DAE.ConnectorType ct; | ||
| 3039 | SCode.Parallelism prl; | ||
| 3040 | SCode.Variability vt,vt2; | ||
| 3041 | Absyn.Direction di; | ||
| 3042 | DAE.Type ty,idTp,ty2_2, tyParent, tyChild, ty1; | ||
| 3043 | DAE.Binding binding, parentBinding; | ||
| 3044 | FCore.Children ht; | ||
| 3045 | list<DAE.Subscript> ss; | ||
| 3046 | FCore.Graph componentEnv; | ||
| 3047 | DAE.ComponentRef ids; | ||
| 3048 | FCore.Cache cache; | ||
| 3049 | Absyn.InnerOuter io; | ||
| 3050 | Option<DAE.Exp> texp; | ||
| 3051 | DAE.ComponentRef xCref,tCref; | ||
| 3052 | list<DAE.ComponentRef> ltCref; | ||
| 3053 | DAE.Exp splicedExp; | ||
| 3054 | DAE.Type eType; | ||
| 3055 | Option<DAE.Const> cnstForRange; | ||
| 3056 | SCode.Visibility vis; | ||
| 3057 | DAE.Attributes attr; | ||
| 3058 | Option<DAE.Exp> oSplicedExp; | ||
| 3059 | |||
| 3060 | // Simple identifier | ||
| 3061 | case (_, _, DAE.CREF_IDENT(ident = id,subscriptLst = ss)) | ||
| 3062 | algorithm | ||
| 3063 | 2469542 | (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name) := lookupVarFIdent(inCache,inBinTree,id,ss,inEnv); | |
| 3064 | then (outCache,outAttributes,outType,outBinding,constOfForIteratorRange,splicedExpData,outComponentEnv,name); | ||
| 3065 | |||
| 3066 | // Qualified variables looked up through component environment with or without spliced exp | ||
| 3067 | case (cache, ht, DAE.CREF_QUAL(ident = id,subscriptLst = ss,componentRef = ids)) | ||
| 3068 | algorithm | ||
| 3069 | 1359783 | (DAE.TYPES_VAR(_,DAE.ATTR(variability = vt2),tyParent,parentBinding,_),_,_,_,componentEnv) := lookupVar2(ht, id, inEnv); | |
| 3070 | |||
| 3071 | // leave just the last scope from component env as it SHOULD BE ONLY THERE, i.e. don't go on searching the parents! | ||
| 3072 | // componentEnv = FGraph.setScope(componentEnv, List.create(FGraph.lastScopeRef(componentEnv))); | ||
| 3073 | |||
| 3074 | (attr,ty,binding,cnstForRange,componentEnv,name) := match tyParent | ||
| 3075 | case DAE.T_METAARRAY() | ||
| 3076 | algorithm | ||
| 3077 | ✗ | true := listLength(TypesDump.getDimensions(tyParent)) == listLength(ss); | |
| 3078 | ✗ | (cache,attr,ty,binding,cnstForRange,name) := lookupVarFMetaModelica(cache, componentEnv, ids, Types.metaArrayElementType(tyParent)); | |
| 3079 | ✗ | splicedExpData := InstTypes.SPLICEDEXPDATA(NONE(),ty); | |
| 3080 | ✗ | then (attr,ty,binding,cnstForRange,componentEnv,name); | |
| 3081 | case _ guard Types.isBoxedType(tyParent) and not Types.isUnknownType(tyParent) | ||
| 3082 | algorithm | ||
| 3083 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1520 times.
|
1520 | {} := ss; |
| 3084 | 1520 | (cache,attr,ty,binding,cnstForRange,name) := lookupVarFMetaModelica(cache, componentEnv, ids, tyParent); | |
| 3085 | 1520 | splicedExpData := InstTypes.SPLICEDEXPDATA(NONE(),ty); | |
| 3086 | 1520 | then (attr,ty,binding,cnstForRange,componentEnv,name); | |
| 3087 | else | ||
| 3088 | algorithm | ||
| 3089 | 492067 | (cache,DAE.ATTR(ct,prl,vt,di,io,vis),tyChild,binding,cnstForRange,InstTypes.SPLICEDEXPDATA(texp,idTp),_,componentEnv,name) := lookupVar(cache, componentEnv, ids); | |
| 3090 | |||
| 3091 | 273410 | ltCref := elabComponentRecursive((texp)); | |
| 3092 | 273410 | ty := tyChild; // In case it's an unspliced expression | |
| 3093 | oSplicedExp := match ltCref | ||
| 3094 | case tCref::_ // with a spliced exp | ||
| 3095 | algorithm | ||
| 3096 | 273410 | ty1 := checkSubscripts(tyParent, ss); | |
| 3097 | 273410 | ty := sliceDimensionType(ty1,tyChild); | |
| 3098 | 273410 | ty2_2 := Types.simplifyType(tyParent); | |
| 3099 | 273410 | ss := addArrayDimensions(ty2_2,ss); | |
| 3100 | 273410 | xCref := ComponentReferenceBasics.makeCrefQual(id,ty2_2,ss,tCref); | |
| 3101 | 273410 | eType := Types.simplifyType(ty); | |
| 3102 | 273410 | splicedExp := Expression.makeCrefExp(xCref,eType); | |
| 3103 | then SOME(splicedExp); | ||
| 3104 | case {} // without spliced Expression | ||
| 3105 | then NONE(); | ||
| 3106 | end match; | ||
| 3107 | 273410 | vt := SCodeUtil.variabilityOr(vt,vt2); | |
| 3108 | 273410 | binding := lookupBinding(inComponentRef, tyParent, ty, parentBinding, binding); | |
| 3109 | 273410 | splicedExpData := InstTypes.SPLICEDEXPDATA(oSplicedExp,idTp); | |
| 3110 | 273410 | then | |
| 3111 | (DAE.ATTR(ct,prl,vt,di,io,vis),ty,binding,cnstForRange,componentEnv,name); | ||
| 3112 | end match; | ||
| 3113 | 274930 | then (cache,attr,ty,binding,cnstForRange,splicedExpData,componentEnv,name); | |
| 3114 | |||
| 3115 | end match; | ||
| 3116 | end lookupVarF; | ||
| 3117 | |||
| 3118 | protected function lookupVarFIdent | ||
| 3119 | "This function looks in a frame to find a declared variable. If | ||
| 3120 | the name being looked up is qualified, the first part of the name | ||
| 3121 | is looked up, and lookupVar2 is used to for further lookup in | ||
| 3122 | the result of that lookup. | ||
| 3123 | 2007-05-29 If we can construct a expression, we do after expanding the | ||
| 3124 | subscript with dimensions to fill the Cref." | ||
| 3125 | input output FCore.Cache cache; | ||
| 3126 | input FCore.Children ht; | ||
| 3127 | input String ident; | ||
| 3128 | input list<DAE.Subscript> ss; | ||
| 3129 | input FCore.Graph inEnv; | ||
| 3130 | output DAE.Attributes attr; | ||
| 3131 | output DAE.Type ty_1; | ||
| 3132 | output DAE.Binding bind; | ||
| 3133 | output Option<DAE.Const> cnstForRange "SOME(constant-ness) of the range if this is a for iterator, NONE() if this is not a for iterator"; | ||
| 3134 | output InstTypes.SplicedExpData splicedExpData; | ||
| 3135 | output FCore.Graph componentEnv; | ||
| 3136 | output String name; | ||
| 3137 | protected | ||
| 3138 | DAE.Type tty, ty; | ||
| 3139 | list<DAE.Subscript> ss_1; | ||
| 3140 | algorithm | ||
| 3141 | 10749923 | (DAE.TYPES_VAR(name,attr,ty,bind,_,cnstForRange),_,_,_,componentEnv) := lookupVar2(ht, ident, inEnv); | |
| 3142 | 1913285 | ty_1 := checkSubscripts(ty, ss); | |
| 3143 | 1913285 | tty := Types.simplifyType(ty); | |
| 3144 | 1913285 | ss_1 := addArrayDimensions(tty,ss); | |
| 3145 | 3826570 | splicedExpData := InstTypes.SPLICEDEXPDATA(SOME(Expression.makeCrefExp(ComponentReferenceBasics.makeCrefIdent(ident,tty,ss_1),tty)),ty); | |
| 3146 | end lookupVarFIdent; | ||
| 3147 | |||
| 3148 | |||
| 3149 | protected function lookupVarFMetaModelica | ||
| 3150 | input FCore.Cache inCache; | ||
| 3151 | input FCore.Graph inEnv; | ||
| 3152 | input DAE.ComponentRef cr; | ||
| 3153 | input DAE.Type inType; | ||
| 3154 | output FCore.Cache cache = inCache; | ||
| 3155 | output DAE.Attributes attr; | ||
| 3156 | output DAE.Type ty; | ||
| 3157 | output DAE.Binding binding; | ||
| 3158 | output Option<DAE.Const> cnstForRange; | ||
| 3159 | output String name; | ||
| 3160 | algorithm | ||
| 3161 | (attr,ty,binding,cnstForRange,name) := match cr | ||
| 3162 | local | ||
| 3163 | list<DAE.Var> fields; | ||
| 3164 | case DAE.CREF_IDENT() | ||
| 3165 | algorithm | ||
| 3166 | 1520 | fields := Types.getMetaRecordFields(inType); | |
| 3167 | 1520 | DAE.TYPES_VAR(name,attr,ty,binding,_,cnstForRange) := listGet(fields,Types.findVarIndex(cr.ident,fields)+1); | |
| 3168 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1520 times.
|
1520 | for s in cr.subscriptLst loop |
| 3169 | ty := match ty | ||
| 3170 | ✗ | case DAE.T_METAARRAY() then ty.ty; | |
| 3171 | end match; | ||
| 3172 | end for; | ||
| 3173 | 1520 | ty := Types.getMetaRecordIfSingleton(ty); | |
| 3174 | 1520 | then (attr,ty,binding,cnstForRange,name); | |
| 3175 | case DAE.CREF_QUAL() | ||
| 3176 | algorithm | ||
| 3177 | ✗ | fields := Types.getMetaRecordFields(inType); | |
| 3178 | ✗ | DAE.TYPES_VAR(name,attr,ty,binding,_,cnstForRange) := listGet(fields,Types.findVarIndex(cr.ident,fields)+1); | |
| 3179 | ✗ | for s in cr.subscriptLst loop | |
| 3180 | ty := match ty | ||
| 3181 | ✗ | case DAE.T_METAARRAY() then ty.ty; | |
| 3182 | end match; | ||
| 3183 | end for; | ||
| 3184 | ✗ | ty := Types.getMetaRecordIfSingleton(ty); | |
| 3185 | ✗ | (cache,attr,ty,binding,cnstForRange,name) := lookupVarFMetaModelica(cache, inEnv, cr.componentRef, ty); | |
| 3186 | ✗ | then (attr,ty,binding,cnstForRange,name); | |
| 3187 | end match; | ||
| 3188 | end lookupVarFMetaModelica; | ||
| 3189 | |||
| 3190 | protected function lookupBinding | ||
| 3191 | "@author: adrpo | ||
| 3192 | this function uses the binding of the parent | ||
| 3193 | if the parent is an array of records" | ||
| 3194 | input DAE.ComponentRef inCref; | ||
| 3195 | input DAE.Type inParentType; | ||
| 3196 | input DAE.Type inChildType; | ||
| 3197 | input DAE.Binding inParentBinding; | ||
| 3198 | input DAE.Binding inChildBinding; | ||
| 3199 | output DAE.Binding outBinding; | ||
| 3200 | algorithm | ||
| 3201 | outBinding := matchcontinue(inCref, inParentBinding) | ||
| 3202 | local | ||
| 3203 | DAE.Type tyElement; | ||
| 3204 | DAE.Binding b; | ||
| 3205 | DAE.Exp e; | ||
| 3206 | Values.Value v; | ||
| 3207 | DAE.Const c; | ||
| 3208 | DAE.BindingSource s; | ||
| 3209 | list<DAE.Subscript> ss; | ||
| 3210 | String cId; | ||
| 3211 | list<DAE.Exp> exps; | ||
| 3212 | list<String> comp; | ||
| 3213 | |||
| 3214 | case (DAE.CREF_QUAL(_, _, ss, DAE.CREF_IDENT(cId, _, {})), DAE.EQBOUND(e, _, c, s)) | ||
| 3215 | algorithm | ||
| 3216 |
2/2✓ Branch 1 taken 3580 times.
✓ Branch 2 taken 309 times.
|
3889 | true := Types.isArray(inParentType); |
| 3217 | 309 | tyElement := Types.arrayElementType(inParentType); | |
| 3218 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 309 times.
|
309 | true := Types.isRecord(tyElement); |
| 3219 | |||
| 3220 | // print("CREF EB: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nTyParent: " + TypesDump.printTypeStr(inParentType) + "\nParent:\n" + TypesDump.printBindingStr(inParentBinding) + "\nChild:\n" + TypesDump.printBindingStr(inChildBinding) + "\n"); | ||
| 3221 | |||
| 3222 |
2/2✓ Branch 1 taken 89 times.
✓ Branch 2 taken 220 times.
|
309 | DAE.RECORD(_, exps, comp, _) := Expression.applyExpSubscripts(e, ss); |
| 3223 | |||
| 3224 | 220 | e := listGet(exps, List.position(cId, comp)); | |
| 3225 | 220 | b := DAE.EQBOUND(e, NONE(), c, s); | |
| 3226 | |||
| 3227 | // print("CREF EB RESULT: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nBinding:\n" + TypesDump.printBindingStr(b) + "\n"); | ||
| 3228 | then | ||
| 3229 | b; | ||
| 3230 | |||
| 3231 | /* | ||
| 3232 | case (DAE.CREF_QUAL(id, _, ss, DAE.CREF_IDENT(cId, _, {})), _, _, DAE.EQBOUND(e, ov, c, s), _) | ||
| 3233 | algorithm | ||
| 3234 | true = Types.isArray(inParentType); | ||
| 3235 | tyElement = Types.arrayElementType(inParentType); | ||
| 3236 | true = Types.isRecord(tyElement); | ||
| 3237 | // e = Expression.makeCrefExp(inCref, Expression.typeof(e)); | ||
| 3238 | // b = DAE.EQBOUND(e, NONE(), c, s); | ||
| 3239 | then | ||
| 3240 | inChildBinding;*/ | ||
| 3241 | |||
| 3242 | case (DAE.CREF_QUAL(_, _, ss, DAE.CREF_IDENT(cId, _, {})), DAE.VALBOUND(v, s)) | ||
| 3243 | algorithm | ||
| 3244 |
1/2✓ Branch 1 taken 19915 times.
✗ Branch 2 not taken.
|
19915 | true := Types.isArray(inParentType); |
| 3245 | ✗ | tyElement := Types.arrayElementType(inParentType); | |
| 3246 | ✗ | true := Types.isRecord(tyElement); | |
| 3247 | // print("CREF VB: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nTyParent: " + TypesDump.printTypeStr(inParentType) + "\nParent:\n" + TypesDump.printBindingStr(inParentBinding) + "\nChild:\n" + TypesDump.printBindingStr(inChildBinding) + "\n"); | ||
| 3248 | ✗ | e := ValuesUtil.valueExp(v); | |
| 3249 | ✗ | DAE.RECORD(_, exps, comp, _) := Expression.applyExpSubscripts(e, ss); | |
| 3250 | |||
| 3251 | ✗ | e := listGet(exps, List.position(cId, comp)); | |
| 3252 | |||
| 3253 | ✗ | b := DAE.EQBOUND(e, NONE(), DAE.C_CONST(), s); | |
| 3254 | // print("CREF VB RESULT: " + ComponentReferenceBasics.printComponentRefStr(inCref) + "\nBinding:\n" + TypesDump.printBindingStr(b) + "\n"); | ||
| 3255 | then | ||
| 3256 | b; | ||
| 3257 | |||
| 3258 | /* | ||
| 3259 | case (DAE.CREF_QUAL(id, _, ss, DAE.CREF_IDENT(cId, _, {})), _, _, DAE.VALBOUND(v, s), _) | ||
| 3260 | algorithm | ||
| 3261 | true = Types.isArray(inParentType); | ||
| 3262 | tyElement = Types.arrayElementType(inParentType); | ||
| 3263 | true = Types.isRecord(tyElement); | ||
| 3264 | //e = Expression.makeCrefExp(inCref, inChildType); | ||
| 3265 | //b = DAE.EQBOUND(e, NONE(), DAE.C_CONST(), s); | ||
| 3266 | then | ||
| 3267 | inChildBinding;*/ | ||
| 3268 | |||
| 3269 | else inChildBinding; | ||
| 3270 | |||
| 3271 | end matchcontinue; | ||
| 3272 | end lookupBinding; | ||
| 3273 | |||
| 3274 | protected function elabComponentRecursive " | ||
| 3275 | Helper function for lookupvarF, to return an ComponentRef if there is one." | ||
| 3276 | input Option<DAE.Exp> oCref; | ||
| 3277 | output list<DAE.ComponentRef> lref; | ||
| 3278 | algorithm | ||
| 3279 | lref := match oCref | ||
| 3280 | local | ||
| 3281 | DAE.ComponentRef ecpr; | ||
| 3282 | |||
| 3283 | // expression is an unqualified component reference | ||
| 3284 | case SOME(DAE.CREF(ecpr as DAE.CREF_IDENT(_,_,_),_ )) then (ecpr::{}); | ||
| 3285 | |||
| 3286 | // expression is an qualified component reference | ||
| 3287 | case SOME(DAE.CREF(ecpr as DAE.CREF_QUAL(_,_,_,_),_ )) then (ecpr::{}); | ||
| 3288 | |||
| 3289 | else {}; | ||
| 3290 | end match; | ||
| 3291 | end elabComponentRecursive; | ||
| 3292 | |||
| 3293 | protected function addArrayDimensions "This is the function where we add arrays representing the dimension of the type. | ||
| 3294 | In type {array 2[array 3 ]] Will generate 2 arrays. {1,2} and {1,2,3}" | ||
| 3295 | input DAE.Type tySub; | ||
| 3296 | input list<DAE.Subscript> ss; | ||
| 3297 | output list<DAE.Subscript> outType; | ||
| 3298 | algorithm | ||
| 3299 | outType := | ||
| 3300 | matchcontinue ss | ||
| 3301 | local | ||
| 3302 | list<DAE.Subscript> subs; | ||
| 3303 | DAE.Dimensions dims; | ||
| 3304 | case _ | ||
| 3305 | algorithm | ||
| 3306 |
2/2✓ Branch 1 taken 1644702 times.
✓ Branch 2 taken 541993 times.
|
2186695 | true := Types.isArray(tySub); |
| 3307 | 541993 | dims := TypesDump.getDimensions(tySub); | |
| 3308 | 541993 | subs := List.map(dims, makeDimensionSubscript); | |
| 3309 | 534206 | subs := expandWholeDimSubScript(ss,subs); | |
| 3310 | then subs; | ||
| 3311 | else ss; // non array, return | ||
| 3312 | end matchcontinue; | ||
| 3313 | end addArrayDimensions; | ||
| 3314 | |||
| 3315 | protected function makeDimensionSubscript | ||
| 3316 | "Creates a slice with all indices of the dimension." | ||
| 3317 | input DAE.Dimension inDim; | ||
| 3318 | output DAE.Subscript outSub; | ||
| 3319 | algorithm | ||
| 3320 | outSub := match inDim | ||
| 3321 | local | ||
| 3322 | list<DAE.Exp> expl; | ||
| 3323 | Absyn.Path enum_name; | ||
| 3324 | list<String> l; | ||
| 3325 | |||
| 3326 | // Special case when addressing array[0]. | ||
| 3327 | case DAE.DIM_INTEGER(integer = 0) | ||
| 3328 | then DAE.SLICE(DAE.ARRAY(DAE.T_INTEGER_DEFAULT, true, {DAE.ICONST(0)})); | ||
| 3329 | |||
| 3330 | // Array with integer dimension. | ||
| 3331 | case DAE.DIM_INTEGER() | ||
| 3332 | 1177892 | then DAE.SLICE(DAE.RANGE( | |
| 3333 | DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT, {DAE.DIM_INTEGER(inDim.integer)}), | ||
| 3334 | DAE.ICONST(1), NONE(), DAE.ICONST(inDim.integer))); | ||
| 3335 | |||
| 3336 | // Array with boolean dimension. | ||
| 3337 | case DAE.DIM_BOOLEAN() | ||
| 3338 | algorithm | ||
| 3339 | expl := {DAE.BCONST(false), DAE.BCONST(true)}; | ||
| 3340 | 15 | then | |
| 3341 | DAE.SLICE(DAE.ARRAY(DAE.T_BOOL_DEFAULT, true, expl)); | ||
| 3342 | |||
| 3343 | // Array with enumeration dimension. | ||
| 3344 | case DAE.DIM_ENUM(enumTypeName = enum_name, literals = l) | ||
| 3345 | algorithm | ||
| 3346 | 690 | expl := makeEnumLiteralIndices(enum_name, l, 1); | |
| 3347 | 690 | then DAE.SLICE(DAE.ARRAY(DAE.T_ENUMERATION(NONE(), enum_name, l, {}, {}), true, expl)); | |
| 3348 | end match; | ||
| 3349 | end makeDimensionSubscript; | ||
| 3350 | |||
| 3351 | protected function makeEnumLiteralIndices | ||
| 3352 | "Creates a list of enumeration literal expressions from an enumeration." | ||
| 3353 | input Absyn.Path enumTypeName; | ||
| 3354 | input list<String> enumLiterals; | ||
| 3355 | input Integer enumIndex; | ||
| 3356 | output list<DAE.Exp> enumIndices; | ||
| 3357 | algorithm | ||
| 3358 | enumIndices := match enumLiterals | ||
| 3359 | local | ||
| 3360 | String l; | ||
| 3361 | list<String> ls; | ||
| 3362 | DAE.Exp e; | ||
| 3363 | list<DAE.Exp> expl; | ||
| 3364 | Absyn.Path enum_type_name; | ||
| 3365 | case {} then {}; | ||
| 3366 | case l :: ls | ||
| 3367 | algorithm | ||
| 3368 | 5513 | enum_type_name := AbsynUtil.joinPaths(enumTypeName, Absyn.IDENT(l)); | |
| 3369 | 5513 | e := DAE.ENUM_LITERAL(enum_type_name, enumIndex); | |
| 3370 | 5513 | expl := makeEnumLiteralIndices(enumTypeName, ls, enumIndex + 1); | |
| 3371 | then | ||
| 3372 | e :: expl; | ||
| 3373 | end match; | ||
| 3374 | end makeEnumLiteralIndices; | ||
| 3375 | |||
| 3376 | protected function expandWholeDimSubScript " Function expandWholeDimSubScript | ||
| 3377 | This function replaces Wholedim(if possible) with the expanded dimension. | ||
| 3378 | If there exist a subscript, the subscript is used instead of the expanded dimension. | ||
| 3379 | " | ||
| 3380 | input list<DAE.Subscript> inSubs; | ||
| 3381 | input list<DAE.Subscript> inSlice; | ||
| 3382 | output list<DAE.Subscript> outSubs; | ||
| 3383 | algorithm | ||
| 3384 | outSubs := | ||
| 3385 | matchcontinue(inSubs,inSlice) | ||
| 3386 | local | ||
| 3387 | DAE.Subscript sub1,sub2; | ||
| 3388 | list<DAE.Subscript> subs1,subs2; | ||
| 3389 | // If a for-iterator is used as subscript we get a cref subscript in inSubs, | ||
| 3390 | // but nothing in inSlice because it only contains integers (see | ||
| 3391 | // addArrayDimensions above). This case makes sure that for-iterators are | ||
| 3392 | // not lost here. | ||
| 3393 | case (((sub1 as DAE.INDEX(exp = DAE.CREF())) :: subs1), | ||
| 3394 | subs2) | ||
| 3395 | algorithm | ||
| 3396 | 7027 | subs2 := expandWholeDimSubScript(subs1, subs2); | |
| 3397 | then | ||
| 3398 | (sub1 :: subs2); | ||
| 3399 | case(_,{}) then {}; | ||
| 3400 | case({},subs2) then subs2; | ||
| 3401 | case(((DAE.WHOLEDIM())::subs1), (sub2::subs2)) | ||
| 3402 | algorithm | ||
| 3403 | 1469 | subs2 := expandWholeDimSubScript(subs1,subs2); | |
| 3404 | then | ||
| 3405 | (sub2::subs2); | ||
| 3406 | case((sub1::subs1), (_::subs2)) | ||
| 3407 | algorithm | ||
| 3408 | 343527 | subs2 := expandWholeDimSubScript(subs1,subs2); | |
| 3409 | then | ||
| 3410 | (sub1::subs2); | ||
| 3411 | end matchcontinue; | ||
| 3412 | end expandWholeDimSubScript; | ||
| 3413 | |||
| 3414 | protected function sliceDimensionType "Lifts an type to spcified dimension by type2 | ||
| 3415 | " | ||
| 3416 | input DAE.Type inTypeD; | ||
| 3417 | input DAE.Type inTypeL; | ||
| 3418 | output DAE.Type outType; | ||
| 3419 | |||
| 3420 | algorithm | ||
| 3421 | outType := match (inTypeD,inTypeL) | ||
| 3422 | local | ||
| 3423 | DAE.Type t,tOrg; | ||
| 3424 | list<Integer> dimensions; | ||
| 3425 | DAE.Dimensions dim2; | ||
| 3426 | case(t, tOrg) | ||
| 3427 | algorithm | ||
| 3428 | 273410 | dimensions := Types.getDimensionSizes(t); | |
| 3429 | 273410 | dim2 := List.map(dimensions, Expression.intDimension); | |
| 3430 | 273410 | dim2 := listReverse(dim2); | |
| 3431 | 273410 | t := ((List.foldr(dim2,Types.liftArray, tOrg))); | |
| 3432 | then | ||
| 3433 | t; | ||
| 3434 | end match; | ||
| 3435 | end sliceDimensionType; | ||
| 3436 | |||
| 3437 | |||
| 3438 | public function buildMetaRecordType "common function when looking up the type of a metarecord" | ||
| 3439 | input FCore.Cache inCache; | ||
| 3440 | input FCore.Graph inEnv; | ||
| 3441 | input SCode.Element cdef; | ||
| 3442 | output FCore.Cache outCache; | ||
| 3443 | output FCore.Graph outEnv; | ||
| 3444 | output DAE.Type ftype; | ||
| 3445 | protected | ||
| 3446 | String id; | ||
| 3447 | FCore.Graph env; | ||
| 3448 | Absyn.Path utPath,path; | ||
| 3449 | Integer index; | ||
| 3450 | list<DAE.Var> varlst; | ||
| 3451 | list<SCode.Element> els; | ||
| 3452 | Boolean singleton; | ||
| 3453 | FCore.Cache cache; | ||
| 3454 | list<DAE.Type> typeVarsType; | ||
| 3455 | list<String> typeVars; | ||
| 3456 | algorithm | ||
| 3457 |
3/6✗ Branch 0 not taken.
✓ Branch 1 taken 48727 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48727 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48727 times.
|
48727 | SCode.CLASS(name=id,restriction=SCode.R_METARECORD(name=utPath,index=index,singleton=singleton,typeVars=typeVars),classDef=SCode.PARTS(elementLst = els)) := cdef; |
| 3458 | 48727 | env := FGraph.openScope(inEnv, SCode.NOT_ENCAPSULATED(), id, SOME(FCore.CLASS_SCOPE())); | |
| 3459 | // print("buildMetaRecordType " + id + " in scope " + FGraph.printGraphPathStr(env) + "\n"); | ||
| 3460 | 48727 | (cache,utPath) := Inst.makeFullyQualified(inCache,env,utPath); | |
| 3461 | 48727 | path := AbsynUtil.joinPaths(utPath, Absyn.IDENT(id)); | |
| 3462 | 48727 | (outCache,outEnv,_,_,_,_,_,varlst,_,_) := Inst.instElementList( | |
| 3463 | cache,env,InnerOuter.emptyInstHierarchy, UnitAbsyn.noStore, | ||
| 3464 | DAE.NOMOD(),DAE.NOPRE(), | ||
| 3465 | ClassInf.META_RECORD(Absyn.IDENT("")), List.map1(els,Util.makeTuple,DAE.NOMOD()), | ||
| 3466 | {}, false, InstTypes.INNER_CALL(), ConnectionGraph.EMPTY, Connect.emptySet, true); | ||
| 3467 | 48705 | varlst := Types.boxVarLst(varlst); | |
| 3468 | // for v in varlst loop print(TypesDump.unparseType(v.ty)+"\n"); end for; | ||
| 3469 |
4/4✓ Branch 0 taken 44 times.
✓ Branch 1 taken 48705 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 48705 times.
|
48749 | typeVarsType := list(DAE.T_METAPOLYMORPHIC(tv) for tv in typeVars); |
| 3470 |
2/2✓ Branch 0 taken 41196 times.
✓ Branch 1 taken 7509 times.
|
89901 | ftype := DAE.T_METARECORD(path,utPath,typeVarsType,index,varlst,singleton); |
| 3471 | // print("buildMetaRecordType " + id + " in scope " + FGraph.printGraphPathStr(env) + " OK " + TypesDump.unparseType(ftype) +"\n"); | ||
| 3472 | end buildMetaRecordType; | ||
| 3473 | |||
| 3474 | public function isIterator | ||
| 3475 | "Looks up a cref and returns SOME(true) if it references an iterator, | ||
| 3476 | SOME(false) if it references an element in the current scope, and NONE() if | ||
| 3477 | the name couldn't be found in the current scope at all." | ||
| 3478 | input FCore.Cache inCache; | ||
| 3479 | input FCore.Graph inEnv; | ||
| 3480 | input DAE.ComponentRef inCref; | ||
| 3481 | output Option<Boolean> outIsIterator; | ||
| 3482 | output FCore.Cache outCache; | ||
| 3483 | algorithm | ||
| 3484 | (outIsIterator, outCache) := matchcontinue(inCache, inEnv) | ||
| 3485 | local | ||
| 3486 | String id; | ||
| 3487 | FCore.Cache cache; | ||
| 3488 | FCore.Graph env; | ||
| 3489 | FCore.Children ht; | ||
| 3490 | Option<Boolean> res; | ||
| 3491 | Option<DAE.Const> ic; | ||
| 3492 | FCore.Ref ref; | ||
| 3493 | Boolean b; | ||
| 3494 | |||
| 3495 | // Look in the current scope. | ||
| 3496 | case (cache, FCore.G(scope = ref::_)) | ||
| 3497 | algorithm | ||
| 3498 | 135996 | ht := FNode.children(FNode.fromRef(ref)); | |
| 3499 | // Only look up the first part of the cref, we're only interested in if | ||
| 3500 | // it exists and if it's an iterator or not. | ||
| 3501 | 135996 | id := ComponentReferenceBasics.crefFirstIdent(inCref); | |
| 3502 | 135996 | (DAE.TYPES_VAR(constOfForIteratorRange = ic),_,_,_,_) := lookupVar2(ht, id, inEnv); | |
| 3503 |
3/4✗ Branch 0 not taken.
✓ Branch 1 taken 129968 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 129649 times.
|
129968 | b := isSome(ic); |
| 3504 | 129968 | then | |
| 3505 | (SOME(b), cache); | ||
| 3506 | |||
| 3507 | // If not found, look in the next scope only if the current scope is implicit. | ||
| 3508 | case (cache, FCore.G(scope = ref::_)) | ||
| 3509 | algorithm | ||
| 3510 |
2/2✓ Branch 2 taken 331 times.
✓ Branch 3 taken 5697 times.
|
6028 | true := frameIsImplAddedScope(FNode.fromRef(ref)); |
| 3511 | 5697 | (env, _) := FGraph.stripLastScopeRef(inEnv); | |
| 3512 | 5697 | (res, cache) := isIterator(cache, env, inCref); | |
| 3513 | then | ||
| 3514 | (res, cache); | ||
| 3515 | |||
| 3516 | 331 | else (NONE(), inCache); | |
| 3517 | |||
| 3518 | end matchcontinue; | ||
| 3519 | end isIterator; | ||
| 3520 | |||
| 3521 | public function isFunctionCallViaComponent | ||
| 3522 | input FCore.Cache inCache; | ||
| 3523 | input FCore.Graph inEnv; | ||
| 3524 | input Absyn.Path inPath; | ||
| 3525 | output Boolean yes; | ||
| 3526 | algorithm | ||
| 3527 | yes := matchcontinue inPath | ||
| 3528 | local | ||
| 3529 | Absyn.Ident name; | ||
| 3530 | // see if the first path ident is a component | ||
| 3531 | // we might have a component reference, i.e. world.gravityAcceleration | ||
| 3532 | case Absyn.QUALIFIED(name, _) | ||
| 3533 | algorithm | ||
| 3534 | 35075 | ErrorExt.setCheckpoint("functionViaComponentRef10"); | |
| 3535 | 35075 | lookupVarIdent(inCache, inEnv, name, {}); | |
| 3536 | 622 | ErrorExt.rollBack("functionViaComponentRef10"); | |
| 3537 | then | ||
| 3538 | true; | ||
| 3539 | |||
| 3540 | case Absyn.QUALIFIED(_, _) | ||
| 3541 | algorithm | ||
| 3542 | 34453 | ErrorExt.rollBack("functionViaComponentRef10"); | |
| 3543 | 34453 | then | |
| 3544 | fail(); | ||
| 3545 | |||
| 3546 | else false; | ||
| 3547 | |||
| 3548 | end matchcontinue; | ||
| 3549 | end isFunctionCallViaComponent; | ||
| 3550 | |||
| 3551 | protected function prefixSplicedExp | ||
| 3552 | "Prefixes a spliced exp that contains a cref with another cref." | ||
| 3553 | input DAE.ComponentRef inCref; | ||
| 3554 | input InstTypes.SplicedExpData inSplicedExp; | ||
| 3555 | output InstTypes.SplicedExpData outSplicedExp; | ||
| 3556 | algorithm | ||
| 3557 | outSplicedExp := match inSplicedExp | ||
| 3558 | local | ||
| 3559 | DAE.Type ety, ty; | ||
| 3560 | DAE.ComponentRef cref; | ||
| 3561 | |||
| 3562 | case InstTypes.SPLICEDEXPDATA(SOME(DAE.CREF(cref, ety)), ty) | ||
| 3563 | algorithm | ||
| 3564 | 117400 | cref := ComponentReference.joinCrefs(inCref, cref); | |
| 3565 | 234800 | then | |
| 3566 | InstTypes.SPLICEDEXPDATA(SOME(DAE.CREF(cref, ety)), ty); | ||
| 3567 | |||
| 3568 | else inSplicedExp; | ||
| 3569 | end match; | ||
| 3570 | end prefixSplicedExp; | ||
| 3571 | |||
| 3572 | public function isArrayType | ||
| 3573 | input FCore.Cache inCache; | ||
| 3574 | input FCore.Graph inEnv; | ||
| 3575 | input Absyn.Path inPath; | ||
| 3576 | output FCore.Cache outCache = inCache; | ||
| 3577 | output Boolean outIsArray; | ||
| 3578 | protected | ||
| 3579 | SCode.Element el; | ||
| 3580 | Absyn.Path p; | ||
| 3581 | FCore.Graph env; | ||
| 3582 | algorithm | ||
| 3583 | try | ||
| 3584 | 2 | (outCache, el, env) := lookupClass(inCache, inEnv, inPath); | |
| 3585 | |||
| 3586 | outIsArray := match el | ||
| 3587 | case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = Absyn.TPATH(arrayDim = SOME(_)))) | ||
| 3588 | then true; | ||
| 3589 | |||
| 3590 | case SCode.CLASS(classDef = SCode.DERIVED(attributes = SCode.ATTR(arrayDims = _ :: _))) | ||
| 3591 | then true; | ||
| 3592 | |||
| 3593 | case SCode.CLASS(classDef = SCode.DERIVED(typeSpec = Absyn.TPATH(path = p))) | ||
| 3594 | algorithm | ||
| 3595 | ✗ | (outCache, outIsArray) := isArrayType(outCache, env, p); | |
| 3596 | ✗ | then | |
| 3597 | outIsArray; | ||
| 3598 | |||
| 3599 | else false; | ||
| 3600 | end match; | ||
| 3601 | else | ||
| 3602 | ✗ | outIsArray := false; | |
| 3603 | end try; | ||
| 3604 | end isArrayType; | ||
| 3605 | |||
| 3606 | annotation(__OpenModelica_Interface="frontend"); | ||
| 3607 | end Lookup; | ||
| 3608 |