OMCompiler/Compiler/FrontEnd/NFSCodeCheck.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 NFSCodeCheck | ||
| 37 | " file: NFSCodeCheck.mo | ||
| 38 | package: NFSCodeCheck | ||
| 39 | description: SCode checking | ||
| 40 | |||
| 41 | |||
| 42 | This module checks the SCode representation for conformance " | ||
| 43 | |||
| 44 | public import Absyn; | ||
| 45 | public import AbsynUtil; | ||
| 46 | public import NFInstTypes; | ||
| 47 | public import SCode; | ||
| 48 | public import NFSCodeEnv; | ||
| 49 | |||
| 50 | protected import Debug; | ||
| 51 | protected import Dump; | ||
| 52 | protected import Error; | ||
| 53 | protected import Flags; | ||
| 54 | protected import NFInstDump; | ||
| 55 | protected import SCodeDump; | ||
| 56 | import SCodeUtil; | ||
| 57 | |||
| 58 | import NFSCodeEnv.EnvTree; | ||
| 59 | |||
| 60 | public function checkRecursiveShortDefinition | ||
| 61 | input Absyn.TypeSpec inTypeSpec; | ||
| 62 | input String inTypeName; | ||
| 63 | input NFSCodeEnv.Env inTypeEnv; | ||
| 64 | input SourceInfo inInfo; | ||
| 65 | algorithm | ||
| 66 | () := matchcontinue inTypeEnv | ||
| 67 | local | ||
| 68 | Absyn.Path ts_path, ty_path; | ||
| 69 | String ty; | ||
| 70 | |||
| 71 | case {} then (); | ||
| 72 | |||
| 73 | case _ :: _ | ||
| 74 | algorithm | ||
| 75 | 104189 | ts_path := AbsynUtil.typeSpecPath(inTypeSpec); | |
| 76 | 104189 | ty_path := NFSCodeEnv.getEnvPath(inTypeEnv); | |
| 77 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 104188 times.
|
104189 | false := isSelfReference(inTypeName, ty_path, ts_path); |
| 78 | then | ||
| 79 | (); | ||
| 80 | |||
| 81 | else | ||
| 82 | algorithm | ||
| 83 | 1 | ty := Dump.unparseTypeSpec(inTypeSpec); | |
| 84 | 1 | Error.addSourceMessage(Error.RECURSIVE_SHORT_CLASS_DEFINITION, | |
| 85 | {inTypeName, ty}, inInfo); | ||
| 86 | 1 | then | |
| 87 | fail(); | ||
| 88 | |||
| 89 | end matchcontinue; | ||
| 90 | end checkRecursiveShortDefinition; | ||
| 91 | |||
| 92 | protected function isSelfReference | ||
| 93 | input String inTypeName; | ||
| 94 | input Absyn.Path inTypePath; | ||
| 95 | input Absyn.Path inReferencedName; | ||
| 96 | output Boolean selfRef; | ||
| 97 | algorithm | ||
| 98 | selfRef := match(inTypePath, inReferencedName) | ||
| 99 | local | ||
| 100 | Absyn.Path p1, p2; | ||
| 101 | |||
| 102 | case (p1, Absyn.FULLYQUALIFIED(p2)) | ||
| 103 | 20 | then AbsynUtil.pathEqual(AbsynUtil.joinPaths(p1, Absyn.IDENT(inTypeName)), p2); | |
| 104 | |||
| 105 | case (_, p2) | ||
| 106 |
4/4✓ Branch 2 taken 6391 times.
✓ Branch 3 taken 99820 times.
✓ Branch 7 taken 6390 times.
✓ Branch 8 taken 1 time.
|
106211 | then stringEqual(AbsynUtil.pathLastIdent(inTypePath), AbsynUtil.pathFirstIdent(p2)); |
| 107 | |||
| 108 | end match; | ||
| 109 | end isSelfReference; | ||
| 110 | |||
| 111 | public function checkClassExtendsReplaceability | ||
| 112 | input NFSCodeEnv.Item inBaseClass; | ||
| 113 | input SourceInfo inOriginInfo; | ||
| 114 | algorithm | ||
| 115 | () := match inBaseClass | ||
| 116 | local | ||
| 117 | case NFSCodeEnv.CLASS(cls = SCode.CLASS(prefixes = SCode.PREFIXES( | ||
| 118 | replaceablePrefix = SCode.REPLACEABLE()))) | ||
| 119 | then (); | ||
| 120 | end match; | ||
| 121 | end checkClassExtendsReplaceability; | ||
| 122 | |||
| 123 | public function checkRedeclareModifier | ||
| 124 | input NFSCodeEnv.Redeclaration inModifier; | ||
| 125 | input Absyn.Path inBaseClass; | ||
| 126 | input NFSCodeEnv.Env inEnv; | ||
| 127 | algorithm | ||
| 128 | () := match inModifier | ||
| 129 | local | ||
| 130 | SCode.Element e; | ||
| 131 | |||
| 132 | case NFSCodeEnv.RAW_MODIFIER(e as SCode.CLASS(classDef = | ||
| 133 | SCode.DERIVED())) | ||
| 134 | algorithm | ||
| 135 | 2042 | checkRedeclareModifier2(e, inBaseClass, inEnv); | |
| 136 | then | ||
| 137 | (); | ||
| 138 | |||
| 139 | else (); | ||
| 140 | end match; | ||
| 141 | end checkRedeclareModifier; | ||
| 142 | |||
| 143 | public function checkRedeclareModifier2 | ||
| 144 | input SCode.Element inModifier; | ||
| 145 | input Absyn.Path inBaseClass; | ||
| 146 | input NFSCodeEnv.Env inEnv; | ||
| 147 | algorithm | ||
| 148 | () := matchcontinue inModifier | ||
| 149 | local | ||
| 150 | Absyn.TypeSpec ty; | ||
| 151 | SourceInfo info; | ||
| 152 | String name, ty_str; | ||
| 153 | Absyn.Path ty_path; | ||
| 154 | |||
| 155 | case SCode.CLASS(name = name, | ||
| 156 | classDef = SCode.DERIVED(typeSpec = ty)) | ||
| 157 | algorithm | ||
| 158 | 2042 | ty_path := AbsynUtil.typeSpecPath(ty); | |
| 159 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2042 times.
|
2042 | false := isSelfReference(name, inBaseClass, ty_path); |
| 160 | then | ||
| 161 | (); | ||
| 162 | |||
| 163 | case SCode.CLASS(name = name, | ||
| 164 | classDef = SCode.DERIVED(typeSpec = ty), info = info) | ||
| 165 | algorithm | ||
| 166 | ✗ | ty_str := Dump.unparseTypeSpec(ty); | |
| 167 | ✗ | Error.addSourceMessage(Error.RECURSIVE_SHORT_CLASS_DEFINITION, | |
| 168 | {name, ty_str}, info); | ||
| 169 | ✗ | then | |
| 170 | fail(); | ||
| 171 | |||
| 172 | end matchcontinue; | ||
| 173 | end checkRedeclareModifier2; | ||
| 174 | |||
| 175 | public function checkModifierIfRedeclare | ||
| 176 | input NFSCodeEnv.Item inItem; | ||
| 177 | input SCode.Mod inModifier; | ||
| 178 | input SourceInfo inInfo; | ||
| 179 | algorithm | ||
| 180 | () := match inModifier | ||
| 181 | local | ||
| 182 | SCode.Element el; | ||
| 183 | |||
| 184 | case SCode.REDECL(element = el) | ||
| 185 | algorithm | ||
| 186 | 199 | checkRedeclaredElementPrefix(inItem, el, inInfo); | |
| 187 | then | ||
| 188 | (); | ||
| 189 | |||
| 190 | else (); | ||
| 191 | end match; | ||
| 192 | end checkModifierIfRedeclare; | ||
| 193 | |||
| 194 | public function checkRedeclaredElementPrefix | ||
| 195 | "Checks that an element that is being redeclared is declared as replaceable | ||
| 196 | and non-final, otherwise an error is printed." | ||
| 197 | input NFSCodeEnv.Item inItem; | ||
| 198 | input SCode.Element inReplacement; | ||
| 199 | input SourceInfo inInfo; | ||
| 200 | algorithm | ||
| 201 | () := match(inItem, inReplacement) | ||
| 202 | local | ||
| 203 | SCode.Replaceable repl; | ||
| 204 | SCode.Final fin; | ||
| 205 | SCode.Ident name; | ||
| 206 | SourceInfo info; | ||
| 207 | SCode.Variability var; | ||
| 208 | SCode.Restriction res; | ||
| 209 | String ty; | ||
| 210 | Absyn.TypeSpec ty1, ty2; | ||
| 211 | Boolean ok; | ||
| 212 | |||
| 213 | case (NFSCodeEnv.VAR(var = | ||
| 214 | SCode.COMPONENT(name = name, prefixes = SCode.PREFIXES( | ||
| 215 | finalPrefix = fin, replaceablePrefix = repl), | ||
| 216 | attributes = SCode.ATTR(variability = var), typeSpec = ty1, info = info)), | ||
| 217 | SCode.COMPONENT(prefixes = SCode.PREFIXES(), typeSpec = ty2)) | ||
| 218 | algorithm | ||
| 219 | ty := "component"; | ||
| 220 | 47 | ok := checkCompRedeclarationReplaceable(name, repl, ty1, ty2, inInfo, info); | |
| 221 |
3/4✓ Branch 1 taken 45 times.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 4 taken 45 times.
|
46 | ok := checkRedeclarationFinal(name, ty, fin, inInfo, info) and ok; |
| 222 |
4/4✓ Branch 1 taken 45 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 44 times.
✓ Branch 4 taken 1 time.
|
46 | ok := checkRedeclarationVariability(name, ty, var, inInfo, info) and ok; |
| 223 | //checkRedeclarationVisibility(name, ty, vis1, vis2, inInfo, info); | ||
| 224 | 2 | true := ok; | |
| 225 | then | ||
| 226 | (); | ||
| 227 | |||
| 228 | case (NFSCodeEnv.CLASS(cls = | ||
| 229 | SCode.CLASS(name = name, prefixes = SCode.PREFIXES( | ||
| 230 | finalPrefix = fin, replaceablePrefix = repl), | ||
| 231 | restriction = res, info = info)), | ||
| 232 | SCode.CLASS(prefixes = SCode.PREFIXES())) | ||
| 233 | algorithm | ||
| 234 | 152 | ty := SCodeDump.restrictionStringPP(res); | |
| 235 | 152 | ok := checkClassRedeclarationReplaceable(name, repl, inInfo, info); | |
| 236 |
2/4✓ Branch 1 taken 152 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 152 times.
|
152 | ok := checkRedeclarationFinal(name, ty, fin, inInfo, info) and ok; |
| 237 | //checkRedeclarationVisibility(name, ty, vis1, vis2, inInfo, info); | ||
| 238 | ✗ | true := ok; | |
| 239 | then | ||
| 240 | (); | ||
| 241 | |||
| 242 | case (NFSCodeEnv.VAR(var = SCode.COMPONENT(name = name, info = info)), | ||
| 243 | SCode.CLASS(restriction = res)) | ||
| 244 | algorithm | ||
| 245 | ✗ | ty := SCodeDump.restrictionStringPP(res); | |
| 246 | ✗ | ty := "a " + ty; | |
| 247 | ✗ | Error.addMultiSourceMessage(Error.INVALID_REDECLARE_AS, | |
| 248 | {"component", name, ty}, {inInfo, info}); | ||
| 249 | ✗ | then | |
| 250 | fail(); | ||
| 251 | |||
| 252 | case (NFSCodeEnv.CLASS(cls = SCode.CLASS(restriction = res, info = info)), | ||
| 253 | SCode.COMPONENT(name = name)) | ||
| 254 | algorithm | ||
| 255 | ✗ | ty := SCodeDump.restrictionStringPP(res); | |
| 256 | ✗ | Error.addMultiSourceMessage(Error.INVALID_REDECLARE_AS, | |
| 257 | {ty, name, "a component"}, {inInfo, info}); | ||
| 258 | ✗ | then | |
| 259 | fail(); | ||
| 260 | |||
| 261 | else (); | ||
| 262 | end match; | ||
| 263 | end checkRedeclaredElementPrefix; | ||
| 264 | |||
| 265 | protected function checkClassRedeclarationReplaceable | ||
| 266 | input SCode.Ident inName; | ||
| 267 | input SCode.Replaceable inReplaceable; | ||
| 268 | input SourceInfo inOriginInfo; | ||
| 269 | input SourceInfo inInfo; | ||
| 270 | output Boolean isValid; | ||
| 271 | algorithm | ||
| 272 | isValid := match inReplaceable | ||
| 273 | case SCode.NOT_REPLACEABLE() guard not Flags.getConfigBool(Flags.IGNORE_REPLACEABLE) | ||
| 274 | algorithm | ||
| 275 | ✗ | Error.addMultiSourceMessage(Error.REDECLARE_NON_REPLACEABLE, | |
| 276 | {inName}, {inOriginInfo, inInfo}); | ||
| 277 | then | ||
| 278 | false; | ||
| 279 | |||
| 280 | else true; | ||
| 281 | |||
| 282 | end match; | ||
| 283 | end checkClassRedeclarationReplaceable; | ||
| 284 | |||
| 285 | protected function checkCompRedeclarationReplaceable | ||
| 286 | input SCode.Ident inName; | ||
| 287 | input SCode.Replaceable inReplaceable; | ||
| 288 | input Absyn.TypeSpec inType1; | ||
| 289 | input Absyn.TypeSpec inType2; | ||
| 290 | input SourceInfo inOriginInfo; | ||
| 291 | input SourceInfo inInfo; | ||
| 292 | output Boolean isValid; | ||
| 293 | algorithm | ||
| 294 | isValid := match inReplaceable | ||
| 295 | case SCode.NOT_REPLACEABLE() | ||
| 296 | guard AbsynUtil.pathEqual(AbsynUtil.typeSpecPath(inType1), | ||
| 297 | AbsynUtil.typeSpecPath(inType2)) | ||
| 298 | then | ||
| 299 | true; | ||
| 300 | |||
| 301 | case SCode.NOT_REPLACEABLE() guard not Flags.getConfigBool(Flags.IGNORE_REPLACEABLE) | ||
| 302 | algorithm | ||
| 303 | 1 | Error.addMultiSourceMessage(Error.REDECLARE_NON_REPLACEABLE, | |
| 304 | {inName}, {inOriginInfo, inInfo}); | ||
| 305 | 1 | then | |
| 306 | fail(); | ||
| 307 | |||
| 308 | else true; | ||
| 309 | |||
| 310 | end match; | ||
| 311 | end checkCompRedeclarationReplaceable; | ||
| 312 | |||
| 313 | protected function checkRedeclarationFinal | ||
| 314 | input SCode.Ident inName; | ||
| 315 | input String inType; | ||
| 316 | input SCode.Final inFinal; | ||
| 317 | input SourceInfo inOriginInfo; | ||
| 318 | input SourceInfo inInfo; | ||
| 319 | output Boolean isValid; | ||
| 320 | algorithm | ||
| 321 | isValid := match inFinal | ||
| 322 | case SCode.NOT_FINAL() then true; | ||
| 323 | |||
| 324 | case SCode.FINAL() | ||
| 325 | algorithm | ||
| 326 | 1 | Error.addMultiSourceMessage(Error.INVALID_REDECLARE, | |
| 327 | {"final", inType, inName}, {inOriginInfo, inInfo}); | ||
| 328 | then | ||
| 329 | false; | ||
| 330 | |||
| 331 | end match; | ||
| 332 | end checkRedeclarationFinal; | ||
| 333 | |||
| 334 | protected function checkRedeclarationVariability | ||
| 335 | input SCode.Ident inName; | ||
| 336 | input String inType; | ||
| 337 | input SCode.Variability inVariability; | ||
| 338 | input SourceInfo inOriginInfo; | ||
| 339 | input SourceInfo inInfo; | ||
| 340 | output Boolean isValid; | ||
| 341 | algorithm | ||
| 342 | isValid := match inVariability | ||
| 343 | case SCode.CONST() | ||
| 344 | algorithm | ||
| 345 | 1 | Error.addMultiSourceMessage(Error.INVALID_REDECLARE, | |
| 346 | {"constant", inType, inName}, {inOriginInfo, inInfo}); | ||
| 347 | then | ||
| 348 | false; | ||
| 349 | |||
| 350 | else true; | ||
| 351 | end match; | ||
| 352 | end checkRedeclarationVariability; | ||
| 353 | |||
| 354 | protected function checkRedeclarationVisibility | ||
| 355 | input SCode.Ident inName; | ||
| 356 | input String inType; | ||
| 357 | input SCode.Visibility inOriginalVisibility; | ||
| 358 | input SCode.Visibility inNewVisibility; | ||
| 359 | input SourceInfo inOriginInfo; | ||
| 360 | input SourceInfo inNewInfo; | ||
| 361 | output Boolean isValid; | ||
| 362 | algorithm | ||
| 363 | isValid := match (inOriginalVisibility, inNewVisibility) | ||
| 364 | case (SCode.PUBLIC(), SCode.PROTECTED()) | ||
| 365 | algorithm | ||
| 366 | ✗ | Error.addMultiSourceMessage(Error.INVALID_REDECLARE_AS, | |
| 367 | {"public element", inName, "protected"}, {inNewInfo, inOriginInfo}); | ||
| 368 | then | ||
| 369 | false; | ||
| 370 | |||
| 371 | case (SCode.PROTECTED(), SCode.PUBLIC()) | ||
| 372 | algorithm | ||
| 373 | ✗ | Error.addMultiSourceMessage(Error.INVALID_REDECLARE_AS, | |
| 374 | {"protected element", inName, "public"}, {inNewInfo, inOriginInfo}); | ||
| 375 | then | ||
| 376 | false; | ||
| 377 | |||
| 378 | else true; | ||
| 379 | end match; | ||
| 380 | end checkRedeclarationVisibility; | ||
| 381 | |||
| 382 | public function checkDuplicateRedeclarations | ||
| 383 | "Checks if a redeclaration already exists in a list of redeclarations." | ||
| 384 | input NFSCodeEnv.Redeclaration inRedeclare; | ||
| 385 | input list<NFSCodeEnv.Redeclaration> inRedeclarations; | ||
| 386 | protected | ||
| 387 | String el_name; | ||
| 388 | SourceInfo el_info; | ||
| 389 | algorithm | ||
| 390 | 69527 | (el_name, el_info) := NFSCodeEnv.getRedeclarationNameInfo(inRedeclare); | |
| 391 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 69526 times.
|
69527 | false := checkDuplicateRedeclarations2(el_name, el_info, inRedeclarations); |
| 392 | end checkDuplicateRedeclarations; | ||
| 393 | |||
| 394 | protected function checkDuplicateRedeclarations2 | ||
| 395 | "Helper function to checkDuplicateRedeclarations." | ||
| 396 | input String inRedeclareName; | ||
| 397 | input SourceInfo inRedeclareInfo; | ||
| 398 | input list<NFSCodeEnv.Redeclaration> inRedeclarations; | ||
| 399 | output Boolean outIsDuplicate; | ||
| 400 | algorithm | ||
| 401 | outIsDuplicate := matchcontinue inRedeclarations | ||
| 402 | local | ||
| 403 | NFSCodeEnv.Redeclaration redecl; | ||
| 404 | list<NFSCodeEnv.Redeclaration> rest_redecls; | ||
| 405 | String el_name; | ||
| 406 | SourceInfo el_info; | ||
| 407 | |||
| 408 | case {} then false; | ||
| 409 | |||
| 410 | case redecl :: _ | ||
| 411 | algorithm | ||
| 412 | 753087 | (el_name, el_info) := NFSCodeEnv.getRedeclarationNameInfo(redecl); | |
| 413 |
4/4✓ Branch 0 taken 53772 times.
✓ Branch 1 taken 699315 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 53771 times.
|
753087 | true := stringEqual(inRedeclareName, el_name); |
| 414 | 1 | Error.addSourceMessage(Error.ERROR_FROM_HERE, {}, el_info); | |
| 415 | 1 | Error.addSourceMessage(Error.DUPLICATE_REDECLARATION, | |
| 416 | {inRedeclareName}, inRedeclareInfo); | ||
| 417 | then | ||
| 418 | true; | ||
| 419 | |||
| 420 | case _ :: rest_redecls | ||
| 421 | 753086 | then checkDuplicateRedeclarations2(inRedeclareName, | |
| 422 | inRedeclareInfo, rest_redecls); | ||
| 423 | |||
| 424 | end matchcontinue; | ||
| 425 | end checkDuplicateRedeclarations2; | ||
| 426 | |||
| 427 | public function checkRecursiveComponentDeclaration | ||
| 428 | "Checks if a component is declared with a type that is one of the enclosing | ||
| 429 | classes, e.g: | ||
| 430 | class A | ||
| 431 | class B | ||
| 432 | A a; | ||
| 433 | end B; | ||
| 434 | end A; | ||
| 435 | " | ||
| 436 | input String inComponentName; | ||
| 437 | input SourceInfo inComponentInfo; | ||
| 438 | input NFSCodeEnv.Env inTypeEnv; | ||
| 439 | input NFSCodeEnv.Item inTypeItem; | ||
| 440 | input NFSCodeEnv.Env inComponentEnv; | ||
| 441 | algorithm | ||
| 442 | () := matchcontinue(inTypeEnv, inComponentEnv) | ||
| 443 | local | ||
| 444 | String cls_name, ty_name; | ||
| 445 | EnvTree.Tree tree; | ||
| 446 | SCode.Element el; | ||
| 447 | |||
| 448 | // No environment means one of the basic types. | ||
| 449 | case ({}, _) then (); | ||
| 450 | |||
| 451 | // Check that the environment of the components type is not an enclosing | ||
| 452 | // scope of the component itself. | ||
| 453 | case (_, _) | ||
| 454 | algorithm | ||
| 455 |
2/2✓ Branch 1 taken 292 times.
✓ Branch 2 taken 56910 times.
|
57202 | false := NFSCodeEnv.envPrefixOf(inTypeEnv, inComponentEnv); |
| 456 | then | ||
| 457 | (); | ||
| 458 | |||
| 459 | // Make an exception for components in functions | ||
| 460 | case (_, NFSCodeEnv.FRAME(name = SOME(cls_name)) :: | ||
| 461 | NFSCodeEnv.FRAME(clsAndVars = tree) :: _) | ||
| 462 | algorithm | ||
| 463 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 292 times.
|
292 | NFSCodeEnv.CLASS(cls = el) := EnvTree.get(tree, cls_name); |
| 464 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 291 times.
|
292 | true := SCodeUtil.isFunction(el); |
| 465 | then | ||
| 466 | (); | ||
| 467 | |||
| 468 | // Make an exception for components in uniontypes | ||
| 469 | case (_, NFSCodeEnv.FRAME(name = SOME(cls_name)) :: | ||
| 470 | NFSCodeEnv.FRAME(clsAndVars = tree) :: _) | ||
| 471 | algorithm | ||
| 472 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
|
1 | NFSCodeEnv.CLASS(cls = el) := EnvTree.get(tree, cls_name); |
| 473 |
1/2✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
|
1 | true := SCodeUtil.isUniontype(el); |
| 474 | then | ||
| 475 | (); | ||
| 476 | |||
| 477 | else | ||
| 478 | algorithm | ||
| 479 | 1 | ty_name := NFSCodeEnv.getItemName(inTypeItem); | |
| 480 | |||
| 481 | 1 | Error.addSourceMessage(Error.RECURSIVE_DEFINITION, | |
| 482 | {inComponentName, ty_name}, inComponentInfo); | ||
| 483 | 1 | then | |
| 484 | fail(); | ||
| 485 | |||
| 486 | end matchcontinue; | ||
| 487 | end checkRecursiveComponentDeclaration; | ||
| 488 | |||
| 489 | public function checkIdentNotEqTypeName | ||
| 490 | "Checks that a simple identifier is not the same as a type name." | ||
| 491 | input String inIdent; | ||
| 492 | input Absyn.TypeSpec inTypeName; | ||
| 493 | input SourceInfo inInfo; | ||
| 494 | output Boolean outIsNotEq; | ||
| 495 | algorithm | ||
| 496 | outIsNotEq := matchcontinue(inIdent, inTypeName) | ||
| 497 | local | ||
| 498 | String id, ty; | ||
| 499 | |||
| 500 | case (id, Absyn.TPATH(path = Absyn.IDENT(ty))) | ||
| 501 | algorithm | ||
| 502 | ✗ | true := stringEq(id, ty); | |
| 503 | ✗ | Error.addSourceMessage(Error.LOOKUP_TYPE_FOUND_COMP, {id}, inInfo); | |
| 504 | then | ||
| 505 | false; | ||
| 506 | |||
| 507 | else true; | ||
| 508 | end matchcontinue; | ||
| 509 | end checkIdentNotEqTypeName; | ||
| 510 | |||
| 511 | public function checkComponentsEqual | ||
| 512 | input NFInstTypes.Component inComponent1; | ||
| 513 | input NFInstTypes.Component inComponent2; | ||
| 514 | algorithm | ||
| 515 | () := match inComponent2 | ||
| 516 | case _ | ||
| 517 | algorithm | ||
| 518 | ✗ | print("Found duplicate component\n"); | |
| 519 | then | ||
| 520 | (); | ||
| 521 | |||
| 522 | end match; | ||
| 523 | end checkComponentsEqual; | ||
| 524 | |||
| 525 | public function checkInstanceRestriction | ||
| 526 | input NFSCodeEnv.Item inItem; | ||
| 527 | input NFInstTypes.Prefix inPrefix; | ||
| 528 | input SourceInfo inInfo; | ||
| 529 | algorithm | ||
| 530 | () := matchcontinue inItem | ||
| 531 | local | ||
| 532 | SCode.Restriction res; | ||
| 533 | String pre_str, res_str; | ||
| 534 | |||
| 535 | case NFSCodeEnv.CLASS(cls = SCode.CLASS(restriction = res)) | ||
| 536 | algorithm | ||
| 537 | ✗ | true := SCodeUtil.isInstantiableClassRestriction(res); | |
| 538 | then | ||
| 539 | (); | ||
| 540 | |||
| 541 | case NFSCodeEnv.CLASS(cls = SCode.CLASS(restriction = res)) | ||
| 542 | algorithm | ||
| 543 | ✗ | res_str := SCodeDump.restrictionStringPP(res); | |
| 544 | ✗ | pre_str := NFInstDump.prefixStr(inPrefix); | |
| 545 | ✗ | Error.addSourceMessage(Error.INVALID_CLASS_RESTRICTION, | |
| 546 | {res_str, pre_str}, inInfo); | ||
| 547 | ✗ | then | |
| 548 | fail(); | ||
| 549 | |||
| 550 | else | ||
| 551 | algorithm | ||
| 552 | ✗ | true := Flags.isSet(Flags.FAILTRACE); | |
| 553 | ✗ | Debug.traceln("- NFSCodeCheck.checkInstanceRestriction failed on unknown item."); | |
| 554 | ✗ | then | |
| 555 | fail(); | ||
| 556 | |||
| 557 | end matchcontinue; | ||
| 558 | end checkInstanceRestriction; | ||
| 559 | |||
| 560 | public function checkPartialInstance | ||
| 561 | "Checks if the given item is partial, and prints out an error message in that | ||
| 562 | case." | ||
| 563 | input NFSCodeEnv.Item inItem; | ||
| 564 | input SourceInfo inInfo; | ||
| 565 | algorithm | ||
| 566 | () := match inItem | ||
| 567 | local | ||
| 568 | String name; | ||
| 569 | |||
| 570 | case NFSCodeEnv.CLASS(cls = SCode.CLASS(name = name, partialPrefix = | ||
| 571 | SCode.PARTIAL())) | ||
| 572 | algorithm | ||
| 573 | ✗ | Error.addSourceMessage(Error.INST_PARTIAL_CLASS, {name}, inInfo); | |
| 574 | ✗ | then | |
| 575 | fail(); | ||
| 576 | |||
| 577 | else (); | ||
| 578 | end match; | ||
| 579 | end checkPartialInstance; | ||
| 580 | |||
| 581 | annotation(__OpenModelica_Interface="frontend"); | ||
| 582 | end NFSCodeCheck; | ||
| 583 |