aas-core-codegen 0.0.16__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (604) hide show
  1. aas_core_codegen/__init__.py +6 -0
  2. aas_core_codegen/__main__.py +8 -0
  3. aas_core_codegen/common.py +500 -0
  4. aas_core_codegen/cpp/__init__.py +1 -0
  5. aas_core_codegen/cpp/aas_common/__init__.py +6 -0
  6. aas_core_codegen/cpp/aas_common/_generate.py +713 -0
  7. aas_core_codegen/cpp/common.py +681 -0
  8. aas_core_codegen/cpp/constants/__init__.py +6 -0
  9. aas_core_codegen/cpp/constants/_generate.py +568 -0
  10. aas_core_codegen/cpp/description.py +654 -0
  11. aas_core_codegen/cpp/enhancing/__init__.py +4 -0
  12. aas_core_codegen/cpp/enhancing/_generate.py +993 -0
  13. aas_core_codegen/cpp/iteration/__init__.py +6 -0
  14. aas_core_codegen/cpp/iteration/_generate.py +2332 -0
  15. aas_core_codegen/cpp/jsonization/__init__.py +6 -0
  16. aas_core_codegen/cpp/jsonization/_generate.py +2619 -0
  17. aas_core_codegen/cpp/main.py +694 -0
  18. aas_core_codegen/cpp/naming.py +170 -0
  19. aas_core_codegen/cpp/optionaling.py +557 -0
  20. aas_core_codegen/cpp/pattern/__init__.py +6 -0
  21. aas_core_codegen/cpp/pattern/_generate.py +508 -0
  22. aas_core_codegen/cpp/revm/__init__.py +6 -0
  23. aas_core_codegen/cpp/revm/_generate.py +1149 -0
  24. aas_core_codegen/cpp/stringification/__init__.py +5 -0
  25. aas_core_codegen/cpp/stringification/_generate.py +955 -0
  26. aas_core_codegen/cpp/structure/__init__.py +7 -0
  27. aas_core_codegen/cpp/structure/_generate.py +1503 -0
  28. aas_core_codegen/cpp/transpilation.py +1383 -0
  29. aas_core_codegen/cpp/unrolling.py +159 -0
  30. aas_core_codegen/cpp/verification/__init__.py +6 -0
  31. aas_core_codegen/cpp/verification/_generate.py +3073 -0
  32. aas_core_codegen/cpp/visitation/__init__.py +6 -0
  33. aas_core_codegen/cpp/visitation/_generate.py +521 -0
  34. aas_core_codegen/cpp/wstringification/__init__.py +5 -0
  35. aas_core_codegen/cpp/wstringification/_generate.py +586 -0
  36. aas_core_codegen/cpp/xmlization/__init__.py +6 -0
  37. aas_core_codegen/cpp/xmlization/_generate.py +5373 -0
  38. aas_core_codegen/cpp/yielding.py +201 -0
  39. aas_core_codegen/csharp/__init__.py +1 -0
  40. aas_core_codegen/csharp/common.py +224 -0
  41. aas_core_codegen/csharp/constants/__init__.py +5 -0
  42. aas_core_codegen/csharp/constants/_generate.py +409 -0
  43. aas_core_codegen/csharp/copying/__init__.py +4 -0
  44. aas_core_codegen/csharp/copying/_generate.py +498 -0
  45. aas_core_codegen/csharp/description.py +1103 -0
  46. aas_core_codegen/csharp/enhancing/__init__.py +4 -0
  47. aas_core_codegen/csharp/enhancing/_generate.py +667 -0
  48. aas_core_codegen/csharp/jsonization/__init__.py +4 -0
  49. aas_core_codegen/csharp/jsonization/_generate.py +1630 -0
  50. aas_core_codegen/csharp/main.py +421 -0
  51. aas_core_codegen/csharp/naming.py +157 -0
  52. aas_core_codegen/csharp/reporting/__init__.py +4 -0
  53. aas_core_codegen/csharp/reporting/_generate.py +266 -0
  54. aas_core_codegen/csharp/stringification/__init__.py +4 -0
  55. aas_core_codegen/csharp/stringification/_generate.py +243 -0
  56. aas_core_codegen/csharp/structure/__init__.py +6 -0
  57. aas_core_codegen/csharp/structure/_generate.py +1341 -0
  58. aas_core_codegen/csharp/transpilation.py +990 -0
  59. aas_core_codegen/csharp/unrolling.py +211 -0
  60. aas_core_codegen/csharp/verification/__init__.py +6 -0
  61. aas_core_codegen/csharp/verification/_generate.py +1457 -0
  62. aas_core_codegen/csharp/visitation/__init__.py +5 -0
  63. aas_core_codegen/csharp/visitation/_generate.py +579 -0
  64. aas_core_codegen/csharp/xmlization/__init__.py +4 -0
  65. aas_core_codegen/csharp/xmlization/_generate.py +1980 -0
  66. aas_core_codegen/golang/__init__.py +1 -0
  67. aas_core_codegen/golang/aas_common/__init__.py +4 -0
  68. aas_core_codegen/golang/aas_common/_generate.py +152 -0
  69. aas_core_codegen/golang/common.py +303 -0
  70. aas_core_codegen/golang/constants/__init__.py +5 -0
  71. aas_core_codegen/golang/constants/_generate.py +339 -0
  72. aas_core_codegen/golang/description.py +501 -0
  73. aas_core_codegen/golang/enhancing/__init__.py +4 -0
  74. aas_core_codegen/golang/enhancing/_generate.py +527 -0
  75. aas_core_codegen/golang/jsonization/__init__.py +4 -0
  76. aas_core_codegen/golang/jsonization/_generate.py +1740 -0
  77. aas_core_codegen/golang/main.py +368 -0
  78. aas_core_codegen/golang/naming.py +412 -0
  79. aas_core_codegen/golang/pointering.py +631 -0
  80. aas_core_codegen/golang/reporting/__init__.py +4 -0
  81. aas_core_codegen/golang/reporting/_generate.py +218 -0
  82. aas_core_codegen/golang/stringification/__init__.py +4 -0
  83. aas_core_codegen/golang/stringification/_generate.py +394 -0
  84. aas_core_codegen/golang/structure/__init__.py +6 -0
  85. aas_core_codegen/golang/structure/_generate.py +1493 -0
  86. aas_core_codegen/golang/transpilation.py +1191 -0
  87. aas_core_codegen/golang/unrolling.py +159 -0
  88. aas_core_codegen/golang/verification/__init__.py +6 -0
  89. aas_core_codegen/golang/verification/_generate.py +1513 -0
  90. aas_core_codegen/golang/xmlization/__init__.py +4 -0
  91. aas_core_codegen/golang/xmlization/_generate.py +2507 -0
  92. aas_core_codegen/infer_for_schema/__init__.py +21 -0
  93. aas_core_codegen/infer_for_schema/_inline.py +693 -0
  94. aas_core_codegen/infer_for_schema/_len.py +527 -0
  95. aas_core_codegen/infer_for_schema/_pattern.py +311 -0
  96. aas_core_codegen/infer_for_schema/_set.py +394 -0
  97. aas_core_codegen/infer_for_schema/_stringify.py +201 -0
  98. aas_core_codegen/infer_for_schema/_types.py +135 -0
  99. aas_core_codegen/infer_for_schema/match.py +122 -0
  100. aas_core_codegen/intermediate/__init__.py +78 -0
  101. aas_core_codegen/intermediate/_hierarchy.py +397 -0
  102. aas_core_codegen/intermediate/_stringify.py +989 -0
  103. aas_core_codegen/intermediate/_translate.py +5128 -0
  104. aas_core_codegen/intermediate/_types.py +2901 -0
  105. aas_core_codegen/intermediate/construction.py +750 -0
  106. aas_core_codegen/intermediate/doc.py +344 -0
  107. aas_core_codegen/intermediate/pattern_verification.py +428 -0
  108. aas_core_codegen/intermediate/revm.py +985 -0
  109. aas_core_codegen/intermediate/type_inference.py +2266 -0
  110. aas_core_codegen/java/__init__.py +1 -0
  111. aas_core_codegen/java/common.py +197 -0
  112. aas_core_codegen/java/constants/__init__.py +5 -0
  113. aas_core_codegen/java/constants/_generate.py +334 -0
  114. aas_core_codegen/java/copying/__init__.py +4 -0
  115. aas_core_codegen/java/copying/_generate.py +502 -0
  116. aas_core_codegen/java/description.py +774 -0
  117. aas_core_codegen/java/enhancing/__init__.py +4 -0
  118. aas_core_codegen/java/enhancing/_generate.py +820 -0
  119. aas_core_codegen/java/generation/__init__.py +5 -0
  120. aas_core_codegen/java/generation/_generate.py +285 -0
  121. aas_core_codegen/java/jsonization/__init__.py +4 -0
  122. aas_core_codegen/java/jsonization/_generate.py +1472 -0
  123. aas_core_codegen/java/main.py +438 -0
  124. aas_core_codegen/java/naming.py +187 -0
  125. aas_core_codegen/java/optional.py +514 -0
  126. aas_core_codegen/java/reporting/__init__.py +4 -0
  127. aas_core_codegen/java/reporting/_generate.py +248 -0
  128. aas_core_codegen/java/stringification/__init__.py +4 -0
  129. aas_core_codegen/java/stringification/_generate.py +212 -0
  130. aas_core_codegen/java/structure/__init__.py +6 -0
  131. aas_core_codegen/java/structure/_generate.py +1767 -0
  132. aas_core_codegen/java/transpilation.py +1111 -0
  133. aas_core_codegen/java/verification/__init__.py +6 -0
  134. aas_core_codegen/java/verification/_generate.py +1536 -0
  135. aas_core_codegen/java/visitation/__init__.py +5 -0
  136. aas_core_codegen/java/visitation/_generate.py +689 -0
  137. aas_core_codegen/java/xmlization/__init__.py +4 -0
  138. aas_core_codegen/java/xmlization/_generate.py +2274 -0
  139. aas_core_codegen/jsonld/__init__.py +1 -0
  140. aas_core_codegen/jsonld/main.py +455 -0
  141. aas_core_codegen/jsonschema/__init__.py +1 -0
  142. aas_core_codegen/jsonschema/main.py +982 -0
  143. aas_core_codegen/main.py +245 -0
  144. aas_core_codegen/naming.py +133 -0
  145. aas_core_codegen/opcua/__init__.py +1 -0
  146. aas_core_codegen/opcua/main.py +1525 -0
  147. aas_core_codegen/opcua/naming.py +126 -0
  148. aas_core_codegen/parse/__init__.py +46 -0
  149. aas_core_codegen/parse/_rules.py +796 -0
  150. aas_core_codegen/parse/_stringify.py +532 -0
  151. aas_core_codegen/parse/_translate.py +3940 -0
  152. aas_core_codegen/parse/_types.py +973 -0
  153. aas_core_codegen/parse/retree/__init__.py +46 -0
  154. aas_core_codegen/parse/retree/_fix.py +434 -0
  155. aas_core_codegen/parse/retree/_parse.py +1143 -0
  156. aas_core_codegen/parse/retree/_render.py +298 -0
  157. aas_core_codegen/parse/retree/_stringify.py +199 -0
  158. aas_core_codegen/parse/retree/_types.py +362 -0
  159. aas_core_codegen/parse/retree/_visitor.py +70 -0
  160. aas_core_codegen/parse/tree.py +1303 -0
  161. aas_core_codegen/protobuf/__init__.py +1 -0
  162. aas_core_codegen/protobuf/common.py +225 -0
  163. aas_core_codegen/protobuf/description.py +1102 -0
  164. aas_core_codegen/protobuf/main.py +115 -0
  165. aas_core_codegen/protobuf/naming.py +143 -0
  166. aas_core_codegen/protobuf/structure/__init__.py +6 -0
  167. aas_core_codegen/protobuf/structure/_generate.py +502 -0
  168. aas_core_codegen/py.typed +1 -0
  169. aas_core_codegen/python/__init__.py +1 -0
  170. aas_core_codegen/python/aas_common/__init__.py +4 -0
  171. aas_core_codegen/python/aas_common/_generate.py +63 -0
  172. aas_core_codegen/python/common.py +406 -0
  173. aas_core_codegen/python/constants/__init__.py +5 -0
  174. aas_core_codegen/python/constants/_generate.py +377 -0
  175. aas_core_codegen/python/description.py +508 -0
  176. aas_core_codegen/python/jsonization/__init__.py +4 -0
  177. aas_core_codegen/python/jsonization/_generate.py +1391 -0
  178. aas_core_codegen/python/main.py +323 -0
  179. aas_core_codegen/python/naming.py +255 -0
  180. aas_core_codegen/python/stringification/__init__.py +4 -0
  181. aas_core_codegen/python/stringification/_generate.py +129 -0
  182. aas_core_codegen/python/structure/__init__.py +6 -0
  183. aas_core_codegen/python/structure/_generate.py +1801 -0
  184. aas_core_codegen/python/transpilation.py +958 -0
  185. aas_core_codegen/python/unrolling.py +156 -0
  186. aas_core_codegen/python/verification/__init__.py +6 -0
  187. aas_core_codegen/python/verification/_generate.py +1471 -0
  188. aas_core_codegen/python/xmlization/__init__.py +4 -0
  189. aas_core_codegen/python/xmlization/_generate.py +3003 -0
  190. aas_core_codegen/python_protobuf/__init__.py +1 -0
  191. aas_core_codegen/python_protobuf/main.py +1424 -0
  192. aas_core_codegen/python_protobuf/naming.py +85 -0
  193. aas_core_codegen/rdf_shacl/__init__.py +1 -0
  194. aas_core_codegen/rdf_shacl/_description.py +351 -0
  195. aas_core_codegen/rdf_shacl/common.py +206 -0
  196. aas_core_codegen/rdf_shacl/main.py +114 -0
  197. aas_core_codegen/rdf_shacl/naming.py +145 -0
  198. aas_core_codegen/rdf_shacl/rdf.py +435 -0
  199. aas_core_codegen/rdf_shacl/shacl.py +453 -0
  200. aas_core_codegen/run.py +124 -0
  201. aas_core_codegen/smoke/__init__.py +1 -0
  202. aas_core_codegen/smoke/main.py +219 -0
  203. aas_core_codegen/specific_implementations.py +72 -0
  204. aas_core_codegen/stringify.py +333 -0
  205. aas_core_codegen/typescript/__init__.py +1 -0
  206. aas_core_codegen/typescript/aas_common/__init__.py +4 -0
  207. aas_core_codegen/typescript/aas_common/_generate.py +472 -0
  208. aas_core_codegen/typescript/common.py +340 -0
  209. aas_core_codegen/typescript/constants/__init__.py +5 -0
  210. aas_core_codegen/typescript/constants/_generate.py +347 -0
  211. aas_core_codegen/typescript/description.py +530 -0
  212. aas_core_codegen/typescript/jsonization/__init__.py +4 -0
  213. aas_core_codegen/typescript/jsonization/_generate.py +1510 -0
  214. aas_core_codegen/typescript/main.py +258 -0
  215. aas_core_codegen/typescript/naming.py +189 -0
  216. aas_core_codegen/typescript/stringification/__init__.py +4 -0
  217. aas_core_codegen/typescript/stringification/_generate.py +367 -0
  218. aas_core_codegen/typescript/structure/__init__.py +6 -0
  219. aas_core_codegen/typescript/structure/_generate.py +2500 -0
  220. aas_core_codegen/typescript/transpilation.py +1051 -0
  221. aas_core_codegen/typescript/unrolling.py +159 -0
  222. aas_core_codegen/typescript/verification/__init__.py +6 -0
  223. aas_core_codegen/typescript/verification/_generate.py +1578 -0
  224. aas_core_codegen/xsd/__init__.py +1 -0
  225. aas_core_codegen/xsd/main.py +1187 -0
  226. aas_core_codegen/xsd/naming.py +83 -0
  227. aas_core_codegen/yielding/__init__.py +1 -0
  228. aas_core_codegen/yielding/flow.py +139 -0
  229. aas_core_codegen/yielding/linear.py +754 -0
  230. aas_core_codegen-0.0.16.dist-info/METADATA +211 -0
  231. aas_core_codegen-0.0.16.dist-info/RECORD +604 -0
  232. aas_core_codegen-0.0.16.dist-info/WHEEL +5 -0
  233. aas_core_codegen-0.0.16.dist-info/entry_points.txt +3 -0
  234. aas_core_codegen-0.0.16.dist-info/licenses/AUTHORS +9 -0
  235. aas_core_codegen-0.0.16.dist-info/licenses/LICENSE +23 -0
  236. aas_core_codegen-0.0.16.dist-info/top_level.txt +2 -0
  237. dev/continuous_integration/__init__.py +1 -0
  238. dev/continuous_integration/check_help_in_readme.py +208 -0
  239. dev/continuous_integration/check_init_and_pyproject_consistent.py +154 -0
  240. dev/continuous_integration/precommit.py +400 -0
  241. dev/dev_scripts/__init__.py +1 -0
  242. dev/dev_scripts/compare_rendered_regexes_against_source_py.py +42 -0
  243. dev/dev_scripts/copy_to_aas_core3_cpp.py +100 -0
  244. dev/dev_scripts/copy_to_aas_core3_java.py +90 -0
  245. dev/dev_scripts/download_latest_aas_core_meta_v3.py +114 -0
  246. dev/dev_scripts/draw_bipartite_graph_based_on_lines.py +37 -0
  247. dev/dev_scripts/run_tests_with_rerecord.py +69 -0
  248. dev/dev_scripts/update_to_aas_core_meta.py +174 -0
  249. dev/integration_tests/input/jsonschema/boilerplate/main.py +55 -0
  250. dev/integration_tests/input/meta_model.py +38 -0
  251. dev/integration_tests/input/python/boilerplate/main.py +153 -0
  252. dev/integration_tests/main.py +258 -0
  253. dev/test_data/csharp/test_structure/concrete_class_with_descendants/meta_model.py +15 -0
  254. dev/test_data/csharp/test_structure/constructor_without_arguments/all_properties_optional/meta_model.py +9 -0
  255. dev/test_data/csharp/test_structure/constructor_without_arguments/no_properties/meta_model.py +6 -0
  256. dev/test_data/csharp/test_verification/builtin_functions/len/on_list/meta_model.py +20 -0
  257. dev/test_data/csharp/test_verification/builtin_functions/len/on_str/meta_model.py +16 -0
  258. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_prefix/meta_model.py +8 -0
  259. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_suffix/meta_model.py +8 -0
  260. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_group_with_quantifier/meta_model.py +8 -0
  261. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_the_middle/meta_model.py +8 -0
  262. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_union/meta_model.py +8 -0
  263. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/single_utf32_literal/meta_model.py +8 -0
  264. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_within_group/meta_model.py +8 -0
  265. dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_without_group/meta_model.py +8 -0
  266. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_beginning/meta_model.py +8 -0
  267. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_end/meta_model.py +8 -0
  268. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/in_the_middle/meta_model.py +8 -0
  269. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/multiple/meta_model.py +8 -0
  270. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single/meta_model.py +8 -0
  271. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single_with_quantifier/meta_model.py +8 -0
  272. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/mixed_with_non_utf32/meta_model.py +8 -0
  273. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/more_than_two_high_surrogates/meta_model.py +8 -0
  274. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges/meta_model.py +8 -0
  275. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges_mixed_with_non_utf32/meta_model.py +8 -0
  276. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate/meta_model.py +8 -0
  277. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate_with_quantifier/meta_model.py +8 -0
  278. dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/two_high_surrogates/meta_model.py +8 -0
  279. dev/test_data/intermediate/expected/class/empty/meta_model.py +6 -0
  280. dev/test_data/intermediate/expected/class/implementation_specific_method/meta_model.py +8 -0
  281. dev/test_data/intermediate/expected/class/inheritance/meta_model.py +41 -0
  282. dev/test_data/intermediate/expected/class/methods_with_contracts/meta_model.py +15 -0
  283. dev/test_data/intermediate/expected/class/only_method_no_property/meta_model.py +7 -0
  284. dev/test_data/intermediate/expected/class/only_property_no_method/meta_model.py +9 -0
  285. dev/test_data/intermediate/expected/constant/constant_set/of_enum/meta_model.py +12 -0
  286. dev/test_data/intermediate/expected/constant/constant_set/of_str/meta_model.py +4 -0
  287. dev/test_data/intermediate/expected/constant/constant_set/with_description/meta_model.py +6 -0
  288. dev/test_data/intermediate/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
  289. dev/test_data/intermediate/expected/constant/constant_str/only_value/meta_model.py +7 -0
  290. dev/test_data/intermediate/expected/constant/constant_str/with_description/meta_model.py +5 -0
  291. dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_in_literal/meta_model.py +20 -0
  292. dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_outside_literal/meta_model.py +20 -0
  293. dev/test_data/intermediate/expected/empty/meta_model.py +2 -0
  294. dev/test_data/intermediate/expected/enumeration/meta_model.py +9 -0
  295. dev/test_data/intermediate/expected/interface/basic/meta_model.py +14 -0
  296. dev/test_data/intermediate/expected/interface/empty/meta_model.py +7 -0
  297. dev/test_data/intermediate/expected/interface/inheritance/meta_model.py +27 -0
  298. dev/test_data/intermediate/expected/interface/method_signature/meta_model.py +10 -0
  299. dev/test_data/intermediate/expected/interface/only_constructor/meta_model.py +11 -0
  300. dev/test_data/intermediate/expected/method/non_mutating/implementation_specific/meta_model.py +12 -0
  301. dev/test_data/intermediate/expected/method/non_mutating/understood/meta_model.py +11 -0
  302. dev/test_data/intermediate/expected/type_annotation/atomic/meta_model.py +9 -0
  303. dev/test_data/intermediate/expected/type_annotation/subscripted/class/meta_model.py +13 -0
  304. dev/test_data/intermediate/expected/type_annotation/subscripted/primitive/meta_model.py +9 -0
  305. dev/test_data/intermediate/unexpected/constant_set/of_enum/enumeration_literals_in_subset_outside_of_superset/meta_model.py +20 -0
  306. dev/test_data/intermediate/unexpected/constant_set/of_enum/invalid_literal/meta_model.py +11 -0
  307. dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_between_enumeration_and_literal/meta_model.py +30 -0
  308. dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_in_enumerations_between_subset_and_superset/meta_model.py +21 -0
  309. dev/test_data/intermediate/unexpected/constant_set/of_str/literals_in_subset_outside_of_superset/meta_model.py +18 -0
  310. dev/test_data/intermediate/unexpected/constant_set/of_str/mismatch_between_type_annotation_and_literals/meta_model.py +10 -0
  311. dev/test_data/intermediate/unexpected/constant_set/of_str/superset_and_subset_mismatch_in_type/meta_model.py +12 -0
  312. dev/test_data/intermediate/unexpected/constraints/dangling_constraintref/meta_model.py +18 -0
  313. dev/test_data/intermediate/unexpected/constraints/duplicate_constraints/meta_model.py +20 -0
  314. dev/test_data/intermediate/unexpected/documentation/unexpected_documentation_elements/meta_model.py +34 -0
  315. dev/test_data/intermediate/unexpected/invariant/class_invariant_uses_re/meta_model.py +10 -0
  316. dev/test_data/intermediate/unexpected/invariant/invariant_of_constrained_primitive_uses_re/meta_model.py +7 -0
  317. dev/test_data/intermediate/unexpected/invariant/unexpected_argument_count_to_len/meta_model.py +20 -0
  318. dev/test_data/intermediate/unexpected/invariant/unhandled_built_in_function/meta_model.py +16 -0
  319. dev/test_data/intermediate/unexpected/method_definitions/non_constant_default/meta_model.py +7 -0
  320. dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/default_non_none/meta_model.py +16 -0
  321. dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/no_default/meta_model.py +16 -0
  322. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/after_inheritance/meta_model.py +58 -0
  323. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/type_missmatch/meta_model.py +9 -0
  324. dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/within_class/meta_model.py +22 -0
  325. dev/test_data/jsonschema/test_main/regression_when_len_constraints_on_inherited_property/meta_model.py +28 -0
  326. dev/test_data/opcua/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
  327. dev/test_data/opcua/test_main/classes_with_invariants/meta_model.py +21 -0
  328. dev/test_data/opcua/test_main/concrete_class_with_descendant/meta_model.py +27 -0
  329. dev/test_data/opcua/test_main/concrete_class_with_enum/meta_model.py +21 -0
  330. dev/test_data/opcua/test_main/concrete_class_with_list_of_instances/meta_model.py +21 -0
  331. dev/test_data/opcua/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  332. dev/test_data/opcua/test_main/concrete_class_with_string/meta_model.py +13 -0
  333. dev/test_data/opcua/test_main/constrained_primitive/meta_model.py +20 -0
  334. dev/test_data/opcua/test_main/multiple_inheritance/meta_model.py +25 -0
  335. dev/test_data/parse/expected/constant/constant_set/of_enum/meta_model.py +12 -0
  336. dev/test_data/parse/expected/constant/constant_set/of_str/meta_model.py +4 -0
  337. dev/test_data/parse/expected/constant/constant_set/with_description/meta_model.py +6 -0
  338. dev/test_data/parse/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
  339. dev/test_data/parse/expected/constant/constant_str/only_value/meta_model.py +7 -0
  340. dev/test_data/parse/expected/constant/constant_str/with_description/meta_model.py +5 -0
  341. dev/test_data/parse/expected/enum/ok/meta_model.py +15 -0
  342. dev/test_data/parse/expected/implementation_specific_class/properties_and_methods_in_implementation_specific_class/meta_model.py +17 -0
  343. dev/test_data/parse/expected/inheritance/basic/meta_model.py +11 -0
  344. dev/test_data/parse/expected/inheritance/diamond/meta_model.py +26 -0
  345. dev/test_data/parse/expected/inheritance/inheritance_from_concrete_class/meta_model.py +10 -0
  346. dev/test_data/parse/expected/invariants/in_relation/meta_model.py +16 -0
  347. dev/test_data/parse/expected/method/arguments/meta_model.py +7 -0
  348. dev/test_data/parse/expected/method/basic/meta_model.py +7 -0
  349. dev/test_data/parse/expected/method/contracts/condition_as_keyword_argument/meta_model.py +8 -0
  350. dev/test_data/parse/expected/method/contracts/condition_as_positional_argument/meta_model.py +8 -0
  351. dev/test_data/parse/expected/method/contracts/description_as_keyword_argument/meta_model.py +8 -0
  352. dev/test_data/parse/expected/method/contracts/description_as_positional_argument/meta_model.py +8 -0
  353. dev/test_data/parse/expected/method/contracts/multiple_contracts_in_order/meta_model.py +17 -0
  354. dev/test_data/parse/expected/method/contracts/postcondition/basic/meta_model.py +10 -0
  355. dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_keyword_arguments/meta_model.py +9 -0
  356. dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_positional_arguments/meta_model.py +9 -0
  357. dev/test_data/parse/expected/method/default/meta_model.py +9 -0
  358. dev/test_data/parse/expected/method/description/meta_model.py +8 -0
  359. dev/test_data/parse/expected/method/is_implementation_specific/meta_model.py +8 -0
  360. dev/test_data/parse/expected/method/non_mutating/meta_model.py +11 -0
  361. dev/test_data/parse/expected/method/returns_none/meta_model.py +7 -0
  362. dev/test_data/parse/expected/method/returns_something/meta_model.py +7 -0
  363. dev/test_data/parse/expected/single_class/description/meta_model.py +12 -0
  364. dev/test_data/parse/expected/single_class/empty/meta_model.py +6 -0
  365. dev/test_data/parse/expected/single_class/property/description/meta_model.py +14 -0
  366. dev/test_data/parse/expected/single_class/property/mandatory/meta_model.py +6 -0
  367. dev/test_data/parse/expected/single_class/property/optional/meta_model.py +6 -0
  368. dev/test_data/parse/expected/single_class/property/recursion_to_entity/meta_model.py +6 -0
  369. dev/test_data/parse/unexpected/class_decorators/non_name_decorator/meta_model.py +7 -0
  370. dev/test_data/parse/unexpected/class_decorators/unknown_decorator/meta_model.py +7 -0
  371. dev/test_data/parse/unexpected/class_definitions/is_abstract_and_implementation_specific/meta_model.py +8 -0
  372. dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_before_a_method/meta_model.py +11 -0
  373. dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_for_a_pass/meta_model.py +9 -0
  374. dev/test_data/parse/unexpected/class_definitions/unexpected_double_description_for_a_property/meta_model.py +10 -0
  375. dev/test_data/parse/unexpected/class_inheritances/inheriting_from_implementation_specific_parent/meta_model.py +20 -0
  376. dev/test_data/parse/unexpected/class_inheritances/non_name_super_class/meta_model.py +6 -0
  377. dev/test_data/parse/unexpected/enum/expression_as_assignment_value/meta_model.py +6 -0
  378. dev/test_data/parse/unexpected/enum/non_assignment/meta_model.py +8 -0
  379. dev/test_data/parse/unexpected/enum/non_string_literal/meta_model.py +6 -0
  380. dev/test_data/parse/unexpected/enum/unexpected_inheritance/meta_model.py +6 -0
  381. dev/test_data/parse/unexpected/method_contracts/contract/non_lambda_condition/meta_model.py +8 -0
  382. dev/test_data/parse/unexpected/method_contracts/contract/non_string_literal_description/meta_model.py +8 -0
  383. dev/test_data/parse/unexpected/method_contracts/contract/without_any_arguments/meta_model.py +8 -0
  384. dev/test_data/parse/unexpected/method_contracts/contract/without_condition/meta_model.py +8 -0
  385. dev/test_data/parse/unexpected/method_contracts/postcondition/OLD_in_postcondition_without_snapshot/meta_model.py +8 -0
  386. dev/test_data/parse/unexpected/method_contracts/postcondition/argument_missing_in_function/meta_model.py +8 -0
  387. dev/test_data/parse/unexpected/method_contracts/precondition/argument_missing_in_function/meta_model.py +8 -0
  388. dev/test_data/parse/unexpected/method_contracts/snapshot/argument_missing_in_function/meta_model.py +8 -0
  389. dev/test_data/parse/unexpected/method_contracts/snapshot/capture_not_a_lambda/meta_model.py +8 -0
  390. dev/test_data/parse/unexpected/method_contracts/snapshot/invalid_name/meta_model.py +8 -0
  391. dev/test_data/parse/unexpected/method_contracts/snapshot/name_not_a_string_literal/meta_model.py +8 -0
  392. dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_capture/meta_model.py +8 -0
  393. dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_name/meta_model.py +8 -0
  394. dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_constructor/meta_model.py +8 -0
  395. dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_verification_function/meta_model.py +8 -0
  396. dev/test_data/parse/unexpected/method_decorators/non_name_decorator/meta_model.py +8 -0
  397. dev/test_data/parse/unexpected/method_decorators/unknown_call_decorator/meta_model.py +8 -0
  398. dev/test_data/parse/unexpected/method_decorators/unknown_name_decorator/meta_model.py +8 -0
  399. dev/test_data/parse/unexpected/method_definitions/argument_with_final/meta_model.py +7 -0
  400. dev/test_data/parse/unexpected/method_definitions/argument_without_a_type_annotation/meta_model.py +7 -0
  401. dev/test_data/parse/unexpected/method_definitions/default_for_self/meta_model.py +7 -0
  402. dev/test_data/parse/unexpected/method_definitions/dunder/meta_model.py +7 -0
  403. dev/test_data/parse/unexpected/method_definitions/init_with_return_type/meta_model.py +7 -0
  404. dev/test_data/parse/unexpected/method_definitions/with_keyword_only_arguments/meta_model.py +7 -0
  405. dev/test_data/parse/unexpected/method_definitions/with_positional_arguments/meta_model.py +7 -0
  406. dev/test_data/parse/unexpected/method_definitions/with_type_annotation_for_self/meta_model.py +7 -0
  407. dev/test_data/parse/unexpected/method_definitions/with_variable_arguments/meta_model.py +7 -0
  408. dev/test_data/parse/unexpected/method_definitions/with_variable_keyword_arguments/meta_model.py +7 -0
  409. dev/test_data/parse/unexpected/method_definitions/without_arguments/meta_model.py +7 -0
  410. dev/test_data/parse/unexpected/method_definitions/without_self/meta_model.py +7 -0
  411. dev/test_data/parse/unexpected/method_definitions/without_type_annotation_for_result/meta_model.py +7 -0
  412. dev/test_data/parse/unexpected/property_definitions/final_without_subscript/meta_model.py +6 -0
  413. dev/test_data/parse/unexpected/property_definitions/nested_final/meta_model.py +6 -0
  414. dev/test_data/parse/unexpected/property_definitions/non_simple/meta_model.py +6 -0
  415. dev/test_data/parse/unexpected/property_definitions/unexpected_assignment/meta_model.py +6 -0
  416. dev/test_data/parse/unexpected/property_definitions/unexpected_non_name_property/meta_model.py +6 -0
  417. dev/test_data/parse/unexpected/property_definitions/without_type_annotation/meta_model.py +6 -0
  418. dev/test_data/parse/unexpected/symbol_table/constant_set_with_a_non_set_subset/meta_model.py +6 -0
  419. dev/test_data/parse/unexpected/symbol_table/dangling_inheritance/meta_model.py +6 -0
  420. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_a_property/meta_model.py +6 -0
  421. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_an_argument/meta_model.py +7 -0
  422. dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_constant_set/meta_model.py +6 -0
  423. dev/test_data/parse/unexpected/symbol_table/dangling_subset_in_constant_set/meta_model.py +4 -0
  424. dev/test_data/parse/unexpected/symbol_table/inheritance_from_non_class/meta_model.py +10 -0
  425. dev/test_data/parse_retree/expected/character_set/common_escaping/source.py +1 -0
  426. dev/test_data/parse_retree/expected/character_set/complementing/double_caret/source.py +1 -0
  427. dev/test_data/parse_retree/expected/character_set/complementing/multiple_ranges/source.py +1 -0
  428. dev/test_data/parse_retree/expected/character_set/complementing/suffix_dash/source.py +1 -0
  429. dev/test_data/parse_retree/expected/character_set/escape_first_caret/source.py +1 -0
  430. dev/test_data/parse_retree/expected/character_set/literals_which_need_no_escaping_in_characters_set_but_need_escaping_outside/source.py +1 -0
  431. dev/test_data/parse_retree/expected/character_set/multiple_ranges/source.py +1 -0
  432. dev/test_data/parse_retree/expected/character_set/single_literal/source.py +1 -0
  433. dev/test_data/parse_retree/expected/character_set/single_range/source.py +1 -0
  434. dev/test_data/parse_retree/expected/character_set/unescaped_dash/only_dash/source.py +1 -0
  435. dev/test_data/parse_retree/expected/character_set/unescaped_dash/prefix_dash/source.py +1 -0
  436. dev/test_data/parse_retree/expected/character_set/unescaped_dash/suffix_dash/source.py +1 -0
  437. dev/test_data/parse_retree/expected/dot/source.py +1 -0
  438. dev/test_data/parse_retree/expected/empty/group/source.py +1 -0
  439. dev/test_data/parse_retree/expected/empty/group_in_a_group/source.py +1 -0
  440. dev/test_data/parse_retree/expected/empty/group_of_union_of_empty_concatenations/source.py +1 -0
  441. dev/test_data/parse_retree/expected/empty/regex/source.py +1 -0
  442. dev/test_data/parse_retree/expected/empty/union_of_empty_concatenations/source.py +1 -0
  443. dev/test_data/parse_retree/expected/escaped_literals/source.py +1 -0
  444. dev/test_data/parse_retree/expected/formatted_value/at_the_beginning/source.py +1 -0
  445. dev/test_data/parse_retree/expected/formatted_value/at_the_end/source.py +1 -0
  446. dev/test_data/parse_retree/expected/formatted_value/in_the_middle/source.py +1 -0
  447. dev/test_data/parse_retree/expected/formatted_value/single_formatted_value/source.py +1 -0
  448. dev/test_data/parse_retree/expected/literal/source.py +1 -0
  449. dev/test_data/parse_retree/expected/quantifier/greedy/at_least_3/source.py +1 -0
  450. dev/test_data/parse_retree/expected/quantifier/greedy/at_least_one/source.py +1 -0
  451. dev/test_data/parse_retree/expected/quantifier/greedy/at_most_3/source.py +1 -0
  452. dev/test_data/parse_retree/expected/quantifier/greedy/exactly_3/source.py +1 -0
  453. dev/test_data/parse_retree/expected/quantifier/greedy/maybe/source.py +1 -0
  454. dev/test_data/parse_retree/expected/quantifier/greedy/zero_or_more/source.py +1 -0
  455. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_3/source.py +1 -0
  456. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_one/source.py +1 -0
  457. dev/test_data/parse_retree/expected/quantifier/non_greedy/at_most_3/source.py +1 -0
  458. dev/test_data/parse_retree/expected/quantifier/non_greedy/exactly_3/source.py +1 -0
  459. dev/test_data/parse_retree/expected/quantifier/non_greedy/maybe/source.py +1 -0
  460. dev/test_data/parse_retree/expected/quantifier/non_greedy/zero_or_more/source.py +1 -0
  461. dev/test_data/parse_retree/expected/quantifier/on_a_character_set/source.py +1 -0
  462. dev/test_data/parse_retree/expected/quantifier/on_a_formatted_value/source.py +1 -0
  463. dev/test_data/parse_retree/expected/quantifier/on_a_group/source.py +1 -0
  464. dev/test_data/parse_retree/expected/quantifier/on_a_literal/source.py +1 -0
  465. dev/test_data/parse_retree/expected/start_and_stop_symbols/double_end_symbol/source.py +1 -0
  466. dev/test_data/parse_retree/expected/start_and_stop_symbols/double_start_symbol/source.py +1 -0
  467. dev/test_data/parse_retree/expected/start_and_stop_symbols/end_symbol_in_the_middle/source.py +1 -0
  468. dev/test_data/parse_retree/expected/start_and_stop_symbols/only_start_symbol/source.py +1 -0
  469. dev/test_data/parse_retree/expected/start_and_stop_symbols/only_stop_symbol/source.py +1 -0
  470. dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_at_the_beginning/source.py +1 -0
  471. dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_in_the_middle/source.py +1 -0
  472. dev/test_data/parse_retree/expected/start_and_stop_symbols/stop_symbol_at_the_end/source.py +1 -0
  473. dev/test_data/parse_retree/expected/union/of_character_sets/source.py +1 -0
  474. dev/test_data/parse_retree/expected/union/of_groups/source.py +1 -0
  475. dev/test_data/parse_retree/expected/union/of_string_literals/source.py +1 -0
  476. dev/test_data/parse_retree/expected/union/within_group/source.py +1 -0
  477. dev/test_data/parse_retree/expected/whitespace/source.py +1 -0
  478. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/Uxxxxxxxx_out_of_range/source.py +1 -0
  479. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/only_backslash/source.py +1 -0
  480. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_Uxxxxxxxx/source.py +1 -0
  481. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_uxxxx/source.py +1 -0
  482. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_x/source.py +1 -0
  483. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unexpected_escaping/source.py +1 -0
  484. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/digit/source.py +1 -0
  485. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_digit/source.py +1 -0
  486. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_whitespace/source.py +1 -0
  487. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_word/source.py +1 -0
  488. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/whitespace/source.py +1 -0
  489. dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/word/source.py +1 -0
  490. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/Uxxxxxxxx_out_of_range/source.py +1 -0
  491. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/only_backslash/source.py +1 -0
  492. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_Uxxxxxxxx/source.py +1 -0
  493. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_uxxxx/source.py +1 -0
  494. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_x/source.py +1 -0
  495. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unexpected_escaping/source.py +1 -0
  496. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/digit/source.py +1 -0
  497. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_digit/source.py +1 -0
  498. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_whitespace/source.py +1 -0
  499. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_word/source.py +1 -0
  500. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/whitespace/source.py +1 -0
  501. dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/word/source.py +1 -0
  502. dev/test_data/parse_retree/unexpected/invalid_character_range/source.py +1 -0
  503. dev/test_data/parse_retree/unexpected/invalid_quantifier/at_least_x/source.py +1 -0
  504. dev/test_data/parse_retree/unexpected/invalid_quantifier/between_3_and_x/source.py +1 -0
  505. dev/test_data/parse_retree/unexpected/invalid_quantifier/exactly_x/source.py +1 -0
  506. dev/test_data/parse_retree/unexpected/unhandled_group_directives/source.py +1 -0
  507. dev/test_data/parse_retree/unexpected/unterminated/character_set/source.py +1 -0
  508. dev/test_data/parse_retree/unexpected/unterminated/group/source.py +1 -0
  509. dev/test_data/parse_retree/unexpected/unterminated/group_of_union_of_empty_concatenations/source.py +1 -0
  510. dev/test_data/parse_retree/unexpected/unterminated/quantifier/source.py +1 -0
  511. dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_comma/source.py +1 -0
  512. dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_number_and_comma/source.py +1 -0
  513. dev/test_data/proto/test_main/expected/abstract_and_concrete_classes/meta_model.py +37 -0
  514. dev/test_data/proto/test_main/expected/concrete_class_with_descendants/meta_model.py +30 -0
  515. dev/test_data/proto/test_main/expected/concrete_class_with_enum/meta_model.py +21 -0
  516. dev/test_data/proto/test_main/expected/concrete_class_with_list_of_instances/meta_model.py +21 -0
  517. dev/test_data/proto/test_main/expected/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  518. dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/expected_output/pbization.py +532 -0
  519. dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
  520. dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/expected_output/pbization.py +527 -0
  521. dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/meta_model.py +27 -0
  522. dev/test_data/python_protobuf/test_main/concrete_class_with_enum/expected_output/pbization.py +290 -0
  523. dev/test_data/python_protobuf/test_main/concrete_class_with_enum/meta_model.py +21 -0
  524. dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/expected_output/pbization.py +328 -0
  525. dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/meta_model.py +23 -0
  526. dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/expected_output/pbization.py +274 -0
  527. dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
  528. dev/test_data/rdf_shacl/test_main/expected/regression_when_lang_string_class_is_missing/meta_model.py +29 -0
  529. dev/test_data/rdf_shacl/test_main/expected/regression_when_len_constraints_on_inherited_property/meta_model.py +27 -0
  530. dev/test_data/rdf_shacl/test_main/unexpected/regression_len_constraint_on_class_property/meta_model.py +61 -0
  531. dev/test_data/real_meta_models/aas_core_meta.v3.py +5721 -0
  532. dev/test_data/smoke/test_main/unexpected/infer_for_schema_error/meta_model.py +12 -0
  533. dev/test_data/smoke/test_main/unexpected/intermediate_error/meta_model.py +18 -0
  534. dev/test_data/smoke/test_main/unexpected/parse_error/meta_model.py +5 -0
  535. dev/test_data/smoke/test_main/unexpected/pattern_verification_unparsable_regex/direct_match/meta_model.py +8 -0
  536. dev/test_data/smoke/test_main/unexpected/type_error/meta_model.py +18 -0
  537. dev/tests/__init__.py +1 -0
  538. dev/tests/common.py +197 -0
  539. dev/tests/cpp/__init__.py +0 -0
  540. dev/tests/cpp/test_common.py +32 -0
  541. dev/tests/cpp/test_main.py +144 -0
  542. dev/tests/cpp/test_pattern.py +188 -0
  543. dev/tests/cpp/test_verification.py +189 -0
  544. dev/tests/cpp/test_yielding.py +225 -0
  545. dev/tests/csharp/__init__.py +0 -0
  546. dev/tests/csharp/live_test_main.py +109 -0
  547. dev/tests/csharp/test_common.py +28 -0
  548. dev/tests/csharp/test_description.py +684 -0
  549. dev/tests/csharp/test_main.py +129 -0
  550. dev/tests/csharp/test_structure.py +93 -0
  551. dev/tests/csharp/test_verification.py +82 -0
  552. dev/tests/description.py +29 -0
  553. dev/tests/golang/__init__.py +0 -0
  554. dev/tests/golang/test_common.py +78 -0
  555. dev/tests/golang/test_main.py +128 -0
  556. dev/tests/infer_for_schema/__init__.py +0 -0
  557. dev/tests/infer_for_schema/common.py +47 -0
  558. dev/tests/infer_for_schema/test_len_on_properties.py +955 -0
  559. dev/tests/infer_for_schema/test_len_on_self.py +580 -0
  560. dev/tests/infer_for_schema/test_patterns_on_properties.py +686 -0
  561. dev/tests/infer_for_schema/test_patterns_on_self.py +258 -0
  562. dev/tests/infer_for_schema/test_property_in_set_of_enumeration_literals.py +600 -0
  563. dev/tests/infer_for_schema/test_property_in_set_of_primitives.py +549 -0
  564. dev/tests/intermediate/__init__.py +0 -0
  565. dev/tests/intermediate/test_constructor.py +719 -0
  566. dev/tests/intermediate/test_hierarchy.py +221 -0
  567. dev/tests/intermediate/test_revm.py +134 -0
  568. dev/tests/intermediate/test_translate.py +337 -0
  569. dev/tests/intermediate/test_type_inference.py +333 -0
  570. dev/tests/intermediate/test_types.py +169 -0
  571. dev/tests/java/__init__.py +0 -0
  572. dev/tests/java/test_common.py +20 -0
  573. dev/tests/java/test_description.py +128 -0
  574. dev/tests/java/test_main.py +234 -0
  575. dev/tests/jsonld_context/test_main.py +79 -0
  576. dev/tests/opcua/__init__.py +3 -0
  577. dev/tests/opcua/test_main.py +110 -0
  578. dev/tests/our_jsonschema/__init__.py +3 -0
  579. dev/tests/our_jsonschema/test_main.py +232 -0
  580. dev/tests/parse/__init__.py +0 -0
  581. dev/tests/parse/test_parse.py +503 -0
  582. dev/tests/parse/test_retree.py +272 -0
  583. dev/tests/proto/__init__.py +0 -0
  584. dev/tests/proto/test_main.py +112 -0
  585. dev/tests/python/__init__.py +0 -0
  586. dev/tests/python/test_common.py +124 -0
  587. dev/tests/python/test_main.py +126 -0
  588. dev/tests/python/test_xml_playground.py +254 -0
  589. dev/tests/python_protobuf/__init__.py +0 -0
  590. dev/tests/python_protobuf/test_main.py +111 -0
  591. dev/tests/rdf_shacl/__init__.py +0 -0
  592. dev/tests/rdf_shacl/test_common.py +32 -0
  593. dev/tests/rdf_shacl/test_description.py +223 -0
  594. dev/tests/rdf_shacl/test_main.py +194 -0
  595. dev/tests/smoke/__init__.py +0 -0
  596. dev/tests/smoke/test_main.py +83 -0
  597. dev/tests/test_common.py +94 -0
  598. dev/tests/typescript/__init__.py +0 -0
  599. dev/tests/typescript/test_common.py +108 -0
  600. dev/tests/typescript/test_main.py +125 -0
  601. dev/tests/xsd/__init__.py +0 -0
  602. dev/tests/xsd/test_main.py +227 -0
  603. dev/tests/yielding/__init__.py +0 -0
  604. dev/tests/yielding/test_linear.py +558 -0
@@ -0,0 +1,1578 @@
1
+ """Generate the invariant verifiers from the intermediate representation."""
2
+ import io
3
+ import textwrap
4
+ from typing import (
5
+ Tuple,
6
+ Optional,
7
+ List,
8
+ Sequence,
9
+ Mapping,
10
+ Union,
11
+ )
12
+
13
+ from icontract import ensure, require
14
+
15
+ from aas_core_codegen import intermediate, specific_implementations
16
+ from aas_core_codegen.common import (
17
+ Error,
18
+ Stripped,
19
+ assert_never,
20
+ Identifier,
21
+ indent_but_first_line,
22
+ wrap_text_into_lines,
23
+ assert_union_without_excluded,
24
+ )
25
+ from aas_core_codegen.intermediate import type_inference as intermediate_type_inference
26
+ from aas_core_codegen.parse import tree as parse_tree, retree as parse_retree
27
+ from aas_core_codegen.typescript import (
28
+ common as typescript_common,
29
+ naming as typescript_naming,
30
+ description as typescript_description,
31
+ transpilation as typescript_transpilation,
32
+ )
33
+ from aas_core_codegen.typescript.common import (
34
+ INDENT as I,
35
+ INDENT2 as II,
36
+ INDENT3 as III,
37
+ INDENT4 as IIII,
38
+ )
39
+
40
+
41
+ # region Verify
42
+
43
+
44
+ def verify(
45
+ spec_impls: specific_implementations.SpecificImplementations,
46
+ verification_functions: Sequence[intermediate.Verification],
47
+ ) -> Optional[List[str]]:
48
+ """Verify all the implementation snippets related to verification."""
49
+ errors = [] # type: List[str]
50
+
51
+ expected_keys = [] # type: List[specific_implementations.ImplementationKey]
52
+
53
+ for func in verification_functions:
54
+ if isinstance(func, intermediate.ImplementationSpecificVerification):
55
+ expected_keys.append(
56
+ specific_implementations.ImplementationKey(
57
+ f"Verification/{func.name}.ts"
58
+ ),
59
+ )
60
+
61
+ for key in expected_keys:
62
+ if key not in spec_impls:
63
+ errors.append(f"The implementation snippet is missing for: {key}")
64
+
65
+ if len(errors) == 0:
66
+ return None
67
+
68
+ return errors
69
+
70
+
71
+ # endregion
72
+
73
+ # region Generate
74
+
75
+
76
+ class _RegexRendererForJavaScript(parse_retree.Renderer):
77
+ r"""
78
+ Render the regular expressions as expected by JavaScript.
79
+
80
+ For example, unicode characters are rendered as ``\u{...}``.
81
+ """
82
+
83
+ def char_to_str_and_escape_or_encode_if_necessary(
84
+ self, node: parse_retree.Char, escaping: Mapping[str, str]
85
+ ) -> List[Union[str, parse_tree.FormattedValue]]:
86
+ """Convert the ``node`` to a string, and escape and/or encode appropriately."""
87
+ if not node.explicitly_encoded:
88
+ escaped = escaping.get(node.character, None)
89
+ if escaped is not None:
90
+ result: List[Union[str, parse_tree.FormattedValue]] = [escaped]
91
+ else:
92
+ result = [node.character]
93
+
94
+ return result
95
+ else:
96
+ code = ord(node.character)
97
+ # pylint: disable=line-too-long
98
+ # NOTE (mristin, 2022-12-09):
99
+ # See: https://dmitripavlutin.com/what-every-javascript-developer-should-know-about-unicode/#24-surrogate-pairs
100
+ return [f"\\u{{{code:x}}}"]
101
+
102
+
103
+ _REGEX_RENDERER_FOR_JAVASCRIPT = _RegexRendererForJavaScript()
104
+
105
+
106
+ class _PatternVerificationTranspiler(
107
+ parse_tree.RestrictedTransformer[Tuple[Optional[Stripped], Optional[Error]]]
108
+ ):
109
+ """Transpile a statement of a pattern verification into TypeScript."""
110
+
111
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
112
+ def _transform_joined_str_values(
113
+ self, values: Sequence[Union[str, parse_tree.FormattedValue]]
114
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
115
+ """Transform the values of a joined string to a TypeScript string literal."""
116
+ # If we do not need interpolation, simply return the string literals
117
+ # joined together.
118
+ needs_interpolation = any(
119
+ isinstance(value, parse_tree.FormattedValue) for value in values
120
+ )
121
+ if not needs_interpolation:
122
+ return (
123
+ Stripped(
124
+ typescript_common.string_literal(
125
+ "".join(value for value in values) # type: ignore
126
+ )
127
+ ),
128
+ None,
129
+ )
130
+
131
+ parts = [] # type: List[str]
132
+
133
+ for value in values:
134
+ if isinstance(value, str):
135
+ parts.append(
136
+ typescript_common.string_literal(
137
+ value,
138
+ without_enclosing=True,
139
+ in_backticks=True,
140
+ )
141
+ )
142
+
143
+ elif isinstance(value, parse_tree.FormattedValue):
144
+ code, error = self.transform(value.value)
145
+ if error is not None:
146
+ return None, error
147
+
148
+ assert code is not None
149
+
150
+ assert (
151
+ "\n" not in code
152
+ ), f"New-lines are not expected in formatted values, but got: {code}"
153
+
154
+ parts.append(f"${{{code}}}")
155
+ else:
156
+ assert_never(value)
157
+
158
+ parts_joined = "".join(parts)
159
+ return Stripped(f"`{parts_joined}`"), None
160
+
161
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
162
+ def transform_constant(
163
+ self, node: parse_tree.Constant
164
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
165
+ if isinstance(node.value, str):
166
+ # NOTE (mristin, 2022-06-11):
167
+ # We assume that all the string constants are valid regular expressions.
168
+
169
+ regex, parse_error = parse_retree.parse(values=[node.value])
170
+ if parse_error is not None:
171
+ regex_line, pointer_line = parse_retree.render_pointer(
172
+ parse_error.cursor
173
+ )
174
+
175
+ return (
176
+ None,
177
+ Error(
178
+ node.original_node,
179
+ f"The string constant could not be parsed "
180
+ f"as a regular expression: \n"
181
+ f"{parse_error.message}\n"
182
+ f"{regex_line}\n"
183
+ f"{pointer_line}",
184
+ ),
185
+ )
186
+
187
+ assert regex is not None
188
+
189
+ # NOTE (mristin, 2022-11-04):
190
+ # Strictly speaking, this is a joined string with a single value, a string
191
+ # literal. Thus, do not be confused by the name of the function —
192
+ # this function treats both joined formatted values *and* string literals.
193
+ return self._transform_joined_str_values(
194
+ values=parse_retree.render(
195
+ regex=regex, renderer=_REGEX_RENDERER_FOR_JAVASCRIPT
196
+ )
197
+ )
198
+ else:
199
+ raise AssertionError(f"Unexpected {node=}")
200
+
201
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
202
+ def transform_name(
203
+ self, node: parse_tree.Name
204
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
205
+ return Stripped(typescript_naming.variable_name(node.identifier)), None
206
+
207
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
208
+ def transform_joined_str(
209
+ self, node: parse_tree.JoinedStr
210
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
211
+ regex, parse_error = parse_retree.parse(values=node.values)
212
+ if parse_error is not None:
213
+ regex_line, pointer_line = parse_retree.render_pointer(parse_error.cursor)
214
+
215
+ return (
216
+ None,
217
+ Error(
218
+ node.original_node,
219
+ f"The joined string could not be parsed "
220
+ f"as a regular expression: \n"
221
+ f"{parse_error.message}\n"
222
+ f"{regex_line}\n"
223
+ f"{pointer_line}",
224
+ ),
225
+ )
226
+
227
+ assert regex is not None
228
+
229
+ return self._transform_joined_str_values(
230
+ values=parse_retree.render(
231
+ regex=regex, renderer=_REGEX_RENDERER_FOR_JAVASCRIPT
232
+ )
233
+ )
234
+
235
+ def transform_assignment(
236
+ self, node: parse_tree.Assignment
237
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
238
+ assert isinstance(node.target, parse_tree.Name)
239
+ variable = typescript_naming.variable_name(node.target.identifier)
240
+ code, error = self.transform(node.value)
241
+ if error is not None:
242
+ return None, error
243
+ assert code is not None
244
+
245
+ # NOTE (mristin, 2022-11-24):
246
+ # We assume that the variables won't change in the patterns. If this assumption
247
+ # is broken, fix the code here by first inspecting the scope and classifying
248
+ # the variables into constant ones and modifiable ones.
249
+ return Stripped(f"const {variable} = {code};"), None
250
+
251
+
252
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
253
+ def _transpile_pattern_verification(
254
+ verification: intermediate.PatternVerification,
255
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
256
+ """Generate the verification function that checks the regular expressions."""
257
+ # NOTE (mristin, 2022-11-12):
258
+ # We assume that we performed all the checks at the intermediate stage.
259
+
260
+ construct_name = typescript_naming.function_name(
261
+ Identifier(f"construct_{verification.name}")
262
+ )
263
+
264
+ blocks = [] # type: List[Stripped]
265
+
266
+ # region Construct block
267
+
268
+ writer = io.StringIO()
269
+ writer.write(
270
+ f"""\
271
+ function {construct_name}(): RegExp {{
272
+ """
273
+ )
274
+
275
+ transpiler = _PatternVerificationTranspiler()
276
+
277
+ for i, stmt in enumerate(verification.parsed.body):
278
+ if i == len(verification.parsed.body) - 1:
279
+ break
280
+
281
+ code, error = transpiler.transform(stmt)
282
+ if error is not None:
283
+ return None, error
284
+ assert code is not None
285
+
286
+ writer.write(textwrap.indent(code, I))
287
+ writer.write("\n")
288
+
289
+ if len(verification.parsed.body) >= 2:
290
+ writer.write("\n")
291
+
292
+ pattern_expr, error = transpiler.transform(verification.pattern_expr)
293
+ if error is not None:
294
+ return None, error
295
+ assert pattern_expr is not None
296
+
297
+ # A pragmatic heuristics for breaking lines
298
+ if len(pattern_expr) < 50:
299
+ writer.write(textwrap.indent(f'return new RegExp({pattern_expr}, "u");', I))
300
+ else:
301
+ writer.write(
302
+ textwrap.indent(
303
+ f"""\
304
+ return new RegExp(
305
+ {I}{indent_but_first_line(pattern_expr, I)},
306
+ {I}"u"
307
+ );""",
308
+ I,
309
+ )
310
+ )
311
+
312
+ writer.write("\n}")
313
+
314
+ blocks.append(Stripped(writer.getvalue()))
315
+
316
+ # endregion
317
+
318
+ # region Initialize the regex
319
+
320
+ regex_name = typescript_naming.constant_name(
321
+ Identifier(f"regexp_{verification.name}")
322
+ )
323
+
324
+ blocks.append(Stripped(f"const {regex_name} = {construct_name}();"))
325
+
326
+ # endregion
327
+
328
+ # region Define the verification function
329
+
330
+ assert len(verification.arguments) == 1
331
+ assert isinstance(
332
+ verification.arguments[0].type_annotation, intermediate.PrimitiveTypeAnnotation
333
+ )
334
+ # noinspection PyUnresolvedReferences
335
+ assert (
336
+ verification.arguments[0].type_annotation.a_type
337
+ == intermediate.PrimitiveType.STR
338
+ )
339
+
340
+ arg_name = typescript_naming.argument_name(verification.arguments[0].name)
341
+
342
+ function_name = typescript_naming.function_name(verification.name)
343
+
344
+ writer = io.StringIO()
345
+
346
+ if verification.description is not None:
347
+ (
348
+ comment,
349
+ comment_errors,
350
+ ) = typescript_description.generate_documentation_comment_for_signature(
351
+ description=verification.description,
352
+ context=typescript_description.Context(
353
+ module=typescript_common.VERIFICATION_MODULE, cls_or_enum=None
354
+ ),
355
+ )
356
+ if comment_errors is not None:
357
+ return None, Error(
358
+ verification.description.parsed.node,
359
+ f"Failed to generate the documentation comment for {verification.name!r}",
360
+ comment_errors,
361
+ )
362
+
363
+ assert comment is not None
364
+
365
+ writer.write(comment)
366
+ writer.write("\n")
367
+
368
+ writer.write(
369
+ f"""\
370
+ export function {function_name}({arg_name}: string): boolean {{
371
+ {I}return {regex_name}.test({arg_name});
372
+ }}"""
373
+ )
374
+
375
+ blocks.append(Stripped(writer.getvalue()))
376
+
377
+ # endregion
378
+
379
+ writer = io.StringIO()
380
+ for i, block in enumerate(blocks):
381
+ if i > 0:
382
+ writer.write("\n\n")
383
+
384
+ writer.write(block)
385
+
386
+ return Stripped(writer.getvalue()), None
387
+
388
+
389
+ class _TranspilableVerificationTranspiler(typescript_transpilation.Transpiler):
390
+ """Transpile the body of a :py:class:`TranspilableVerification`."""
391
+
392
+ # fmt: off
393
+ @require(
394
+ lambda environment, verification:
395
+ all(
396
+ environment.find(arg.name) is not None
397
+ for arg in verification.arguments
398
+ ),
399
+ "All arguments defined in the environment"
400
+ )
401
+ # fmt: on
402
+ def __init__(
403
+ self,
404
+ type_map: Mapping[
405
+ parse_tree.Node, intermediate_type_inference.TypeAnnotationUnion
406
+ ],
407
+ environment: intermediate_type_inference.Environment,
408
+ symbol_table: intermediate.SymbolTable,
409
+ verification: intermediate.TranspilableVerification,
410
+ ) -> None:
411
+ """Initialize with the given values."""
412
+ typescript_transpilation.Transpiler.__init__(
413
+ self, type_map=type_map, environment=environment
414
+ )
415
+
416
+ self._symbol_table = symbol_table
417
+
418
+ self._argument_name_set = frozenset(arg.name for arg in verification.arguments)
419
+
420
+ def transform_name(
421
+ self, node: parse_tree.Name
422
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
423
+ if node.identifier in self._variable_name_set:
424
+ return Stripped(typescript_naming.variable_name(node.identifier)), None
425
+
426
+ if node.identifier in self._argument_name_set:
427
+ return Stripped(typescript_naming.argument_name(node.identifier)), None
428
+
429
+ if node.identifier in self._symbol_table.constants_by_name:
430
+ constant_name = typescript_naming.constant_name(node.identifier)
431
+ return Stripped(f"AasConstants.{constant_name}"), None
432
+
433
+ if node.identifier in self._symbol_table.verification_functions_by_name:
434
+ return Stripped(typescript_naming.function_name(node.identifier)), None
435
+
436
+ our_type = self._symbol_table.find_our_type(name=node.identifier)
437
+ if isinstance(our_type, intermediate.Enumeration):
438
+ return (
439
+ Stripped(f"AasTypes.{typescript_naming.enum_name(node.identifier)}"),
440
+ None,
441
+ )
442
+
443
+ return None, Error(
444
+ node.original_node,
445
+ f"We can not determine how to transpile the name {node.identifier!r} "
446
+ f"to TypeScript. We could not find it neither in the constants, nor in "
447
+ f"verification functions, nor as an enumeration. "
448
+ f"If you expect this name to be transpilable, please contact "
449
+ f"the developers.",
450
+ )
451
+
452
+
453
+ def _transpile_transpilable_verification(
454
+ verification: intermediate.TranspilableVerification,
455
+ symbol_table: intermediate.SymbolTable,
456
+ environment: intermediate_type_inference.Environment,
457
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
458
+ """Transpile a verification function."""
459
+ # fmt: off
460
+ type_inference, error = (
461
+ intermediate_type_inference.infer_for_verification(
462
+ verification=verification,
463
+ base_environment=environment
464
+ )
465
+ )
466
+ # fmt: on
467
+
468
+ if error is not None:
469
+ return None, error
470
+
471
+ assert type_inference is not None
472
+
473
+ transpiler = _TranspilableVerificationTranspiler(
474
+ type_map=type_inference.type_map,
475
+ environment=type_inference.environment_with_args,
476
+ symbol_table=symbol_table,
477
+ verification=verification,
478
+ )
479
+
480
+ body = [] # type: List[Stripped]
481
+ for node in verification.parsed.body:
482
+ stmt, error = transpiler.transform(node)
483
+ if error is not None:
484
+ return None, Error(
485
+ verification.parsed.node,
486
+ f"Failed to transpile the verification function {verification.name!r}",
487
+ [error],
488
+ )
489
+
490
+ assert stmt is not None
491
+ body.append(stmt)
492
+
493
+ writer = io.StringIO()
494
+
495
+ if verification.description is not None:
496
+ (
497
+ comment,
498
+ comment_errors,
499
+ ) = typescript_description.generate_documentation_comment_for_signature(
500
+ description=verification.description,
501
+ context=typescript_description.Context(
502
+ module=typescript_common.VERIFICATION_MODULE,
503
+ cls_or_enum=None,
504
+ ),
505
+ )
506
+ if comment_errors is not None:
507
+ return None, Error(
508
+ verification.description.parsed.node,
509
+ f"Failed to generate the comment for verification function {verification.name!r}",
510
+ comment_errors,
511
+ )
512
+
513
+ assert comment is not None
514
+
515
+ writer.write(comment)
516
+ writer.write("\n")
517
+
518
+ function_name = typescript_naming.function_name(verification.name)
519
+
520
+ if verification.returns is None:
521
+ return_type = "void"
522
+ else:
523
+ return_type = typescript_common.generate_type(
524
+ type_annotation=verification.returns, types_module=Identifier("aas_types")
525
+ )
526
+
527
+ arg_defs = [] # type: List[Stripped]
528
+ for arg in verification.arguments:
529
+ arg_type = typescript_common.generate_type(
530
+ arg.type_annotation, types_module=Identifier("AasTypes")
531
+ )
532
+ arg_name = typescript_naming.argument_name(arg.name)
533
+ arg_defs.append(Stripped(f"{arg_name}: {arg_type}"))
534
+
535
+ if len(arg_defs) == 0:
536
+ writer.write(
537
+ f"""\
538
+ export function {function_name}(): {return_type}:"""
539
+ )
540
+ else:
541
+ writer.write(
542
+ f"""\
543
+ export function {function_name}(
544
+ """
545
+ )
546
+
547
+ for i, arg_def in enumerate(arg_defs):
548
+ if i > 0:
549
+ writer.write(",\n")
550
+ writer.write(textwrap.indent(arg_def, I))
551
+
552
+ writer.write("\n")
553
+ writer.write(
554
+ f"""\
555
+ ): {return_type} {{"""
556
+ )
557
+
558
+ if len(body) == 0:
559
+ writer.write("// Intentionally empty.")
560
+ else:
561
+ for stmt in body:
562
+ writer.write("\n")
563
+ writer.write(textwrap.indent(stmt, I))
564
+
565
+ writer.write("\n}")
566
+
567
+ return Stripped(writer.getvalue()), None
568
+
569
+
570
+ class _InvariantTranspiler(typescript_transpilation.Transpiler):
571
+ def __init__(
572
+ self,
573
+ type_map: Mapping[
574
+ parse_tree.Node, intermediate_type_inference.TypeAnnotationUnion
575
+ ],
576
+ environment: intermediate_type_inference.Environment,
577
+ symbol_table: intermediate.SymbolTable,
578
+ ) -> None:
579
+ """Initialize with the given values."""
580
+ typescript_transpilation.Transpiler.__init__(
581
+ self, type_map=type_map, environment=environment
582
+ )
583
+
584
+ self._symbol_table = symbol_table
585
+
586
+ def transform_name(
587
+ self, node: parse_tree.Name
588
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
589
+ if node.identifier in self._variable_name_set:
590
+ return Stripped(typescript_naming.variable_name(node.identifier)), None
591
+
592
+ if node.identifier == "self":
593
+ # The ``that`` refers to the argument of the verification function.
594
+ return Stripped("that"), None
595
+
596
+ if node.identifier in self._symbol_table.constants_by_name:
597
+ constant_name = typescript_naming.constant_name(node.identifier)
598
+ return Stripped(f"AasConstants.{constant_name}"), None
599
+
600
+ if node.identifier in self._symbol_table.verification_functions_by_name:
601
+ return Stripped(typescript_naming.function_name(node.identifier)), None
602
+
603
+ our_type = self._symbol_table.find_our_type(name=node.identifier)
604
+ if isinstance(our_type, intermediate.Enumeration):
605
+ return (
606
+ Stripped(f"AasTypes.{typescript_naming.enum_name(node.identifier)}"),
607
+ None,
608
+ )
609
+
610
+ return None, Error(
611
+ node.original_node,
612
+ f"We can not determine how to transpile the name {node.identifier!r} "
613
+ f"to TypeScript. We could not find it neither in the local variables, "
614
+ f"nor in the global constants, nor in verification functions, "
615
+ f"nor as an enumeration. If you expect this name to be transpilable, "
616
+ f"please contact the developers.",
617
+ )
618
+
619
+
620
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
621
+ def _transpile_invariant(
622
+ invariant: intermediate.Invariant,
623
+ symbol_table: intermediate.SymbolTable,
624
+ environment: intermediate_type_inference.Environment,
625
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
626
+ """Translate the invariant from the meta-model into TypeScript code."""
627
+ # fmt: off
628
+ type_map, inference_error = (
629
+ intermediate_type_inference.infer_for_invariant(
630
+ invariant=invariant,
631
+ environment=environment
632
+ )
633
+ )
634
+ # fmt: on
635
+
636
+ if inference_error is not None:
637
+ return None, inference_error
638
+
639
+ assert type_map is not None
640
+
641
+ transpiler = _InvariantTranspiler(
642
+ type_map=type_map,
643
+ environment=environment,
644
+ symbol_table=symbol_table,
645
+ )
646
+
647
+ expr, error = transpiler.transform(invariant.parsed.body)
648
+ if error is not None:
649
+ return None, error
650
+
651
+ assert expr is not None
652
+
653
+ writer = io.StringIO()
654
+ if len(expr) > 50 or "\n" in expr:
655
+ writer.write("if (!(\n")
656
+ writer.write(textwrap.indent(expr, I))
657
+ writer.write("\n)) {\n")
658
+ else:
659
+ no_parenthesis_type_in_this_context = (
660
+ parse_tree.Index,
661
+ parse_tree.Name,
662
+ parse_tree.Member,
663
+ parse_tree.MethodCall,
664
+ parse_tree.FunctionCall,
665
+ )
666
+
667
+ if isinstance(invariant.parsed.body, no_parenthesis_type_in_this_context):
668
+ not_expr = f"!{expr}"
669
+ else:
670
+ not_expr = f"!({expr})"
671
+
672
+ writer.write(f"if ({not_expr}) {{\n")
673
+
674
+ writer.write(f"{I}yield new VerificationError(\n")
675
+
676
+ # NOTE (mristin, 2022-11-12):
677
+ # We need to wrap the description in multiple literals as a single long
678
+ # string literal is often too much for the readability.
679
+ invariant_description_lines = wrap_text_into_lines(invariant.description)
680
+
681
+ for i, literal in enumerate(invariant_description_lines):
682
+ if i < len(invariant_description_lines) - 1:
683
+ writer.write(f"{II}{typescript_common.string_literal(literal)} +\n")
684
+ else:
685
+ writer.write(f"{II}{typescript_common.string_literal(literal)}\n")
686
+ writer.write(f"{I})")
687
+
688
+ writer.write("\n}")
689
+
690
+ return Stripped(writer.getvalue()), None
691
+
692
+
693
+ OurTypeExceptEnumeration = Union[
694
+ intermediate.ConstrainedPrimitive,
695
+ intermediate.AbstractClass,
696
+ intermediate.ConcreteClass,
697
+ ]
698
+ assert_union_without_excluded(
699
+ original_union=intermediate.OurType,
700
+ subset_union=OurTypeExceptEnumeration,
701
+ excluded=[intermediate.Enumeration],
702
+ )
703
+
704
+
705
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
706
+ def _generate_verify_property_snippet(
707
+ prop: intermediate.Property,
708
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
709
+ """
710
+ Generate the snippet to transform a property to verification errors.
711
+
712
+ Return an empty string if there is nothing to be verified for the given property.
713
+ """
714
+ # NOTE (mristin, 2022-11-12):
715
+ # Instead of writing here a complex but general solution with unrolling we choose
716
+ # to provide a simple, but limited, solution. First, the meta-model is quite
717
+ # limited itself at the moment, so the complexity of the general solution is not
718
+ # warranted. Second, we hope that there will be fewer bugs in the simple solution
719
+ # which is particularly important at this early adoption stage.
720
+ #
721
+ # We anticipate that in the future we will indeed need a general and complex
722
+ # solution. Here are just some thoughts on how to approach it:
723
+ # * Leave the pattern matching to produce more readable code for simple cases,
724
+ # * Unroll only in case of composite types and optional composite types.
725
+
726
+ type_anno = (
727
+ prop.type_annotation
728
+ if not isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation)
729
+ else prop.type_annotation.value
730
+ )
731
+
732
+ if isinstance(type_anno, intermediate.OptionalTypeAnnotation):
733
+ return None, Error(
734
+ prop.parsed.node,
735
+ "We currently implemented verification based on a very limited "
736
+ "pattern matching due to code simplicity. We did not handle "
737
+ "the case of nested optional values. Please contact "
738
+ "the developers if you need this functionality.",
739
+ )
740
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
741
+ if isinstance(type_anno.items, intermediate.OptionalTypeAnnotation):
742
+ return None, Error(
743
+ prop.parsed.node,
744
+ "We currently implemented verification based on a very limited "
745
+ "pattern matching due to code simplicity. We did not handle "
746
+ "the case of lists of optional values. Please contact "
747
+ "the developers if you need this functionality.",
748
+ )
749
+ elif isinstance(type_anno.items, intermediate.ListTypeAnnotation):
750
+ return None, Error(
751
+ prop.parsed.node,
752
+ "We currently implemented verification based on a very limited "
753
+ "pattern matching due to code simplicity. We did not handle "
754
+ "the case of lists of lists. Please contact "
755
+ "the developers if you need this functionality.",
756
+ )
757
+ else:
758
+ pass
759
+ else:
760
+ pass
761
+
762
+ stmts = [] # type: List[Stripped]
763
+
764
+ prop_name = typescript_naming.property_name(prop.name)
765
+ prop_name_literal = typescript_common.string_literal(prop_name)
766
+
767
+ primitive_type = intermediate.try_primitive_type(type_anno)
768
+ if primitive_type is not None and primitive_type is intermediate.PrimitiveType.INT:
769
+ stmts.append(
770
+ Stripped(
771
+ f"""\
772
+ if (!Number.isInteger(that.{prop_name})) {{
773
+ {I}const error = new VerificationError(
774
+ {II}"Expected an integer, but got a floating-point number"
775
+ {I});
776
+ {I}error.path.prepend(
777
+ {II}new PropertySegment(
778
+ {III}that,
779
+ {III}{prop_name_literal}
780
+ {II})
781
+ {I});
782
+ {I}yield error;
783
+ }}"""
784
+ )
785
+ )
786
+
787
+ if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation):
788
+ # There is nothing more that we check for primitive types explicitly. The values
789
+ # of the primitive properties are checked at the level of class invariants.
790
+ return Stripped(""), None
791
+ elif isinstance(type_anno, intermediate.OurTypeAnnotation):
792
+ if isinstance(type_anno.our_type, intermediate.Enumeration):
793
+ # We rely on TypeScript compiler to check for valid enumerations, so we do not check
794
+ # the enumerations on our side.
795
+ return Stripped(""), None
796
+
797
+ elif isinstance(type_anno.our_type, intermediate.ConstrainedPrimitive):
798
+ function_name = typescript_naming.function_name(
799
+ Identifier(f"verify_{type_anno.our_type.name}")
800
+ )
801
+
802
+ # fmt: off
803
+ for_error_of_verify = (
804
+ f"for (const error of {function_name}(that.{prop_name}))"
805
+ )
806
+ # fmt: on
807
+
808
+ # Heuristic to break the lines, very rudimentary
809
+ if len(for_error_of_verify) > 70:
810
+ for_error_of_verify = f"""\
811
+ for (const error of {function_name}(
812
+ {II}that.{prop_name})
813
+ )"""
814
+
815
+ stmts.append(
816
+ Stripped(
817
+ f"""\
818
+ {for_error_of_verify} {{
819
+ {I}error.path.prepend(
820
+ {II}new PropertySegment(
821
+ {III}that,
822
+ {III}{prop_name_literal}
823
+ {II})
824
+ {I});
825
+ {I}yield error;
826
+ }}"""
827
+ )
828
+ )
829
+
830
+ elif isinstance(
831
+ type_anno.our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
832
+ ):
833
+ for_error_of_this_transform = f"for (const error of this.transformWithContext(that.{prop_name}, context))"
834
+ # Heuristic to break the lines, very rudimentary
835
+ if len(for_error_of_this_transform) > 70:
836
+ for_error_of_this_transform = f"""\
837
+ for (const error of this.transformWithContext(
838
+ {II}that.{prop_name}, context)
839
+ )"""
840
+
841
+ stmts.append(
842
+ Stripped(
843
+ f"""\
844
+ {for_error_of_this_transform} {{
845
+ {I}error.path.prepend(
846
+ {II}new PropertySegment(
847
+ {III}that,
848
+ {III}{prop_name_literal}
849
+ {II})
850
+ {I});
851
+ {I}yield error;
852
+ }}"""
853
+ )
854
+ )
855
+ else:
856
+ assert_never(type_anno.our_type)
857
+
858
+ elif isinstance(type_anno, intermediate.ListTypeAnnotation):
859
+ assert isinstance(type_anno.items, intermediate.OurTypeAnnotation), (
860
+ "We chose to implement only a very limited pattern matching; "
861
+ "see the note above in the code."
862
+ )
863
+
864
+ index_var = typescript_naming.variable_name(Identifier(f"{prop.name}_index"))
865
+
866
+ stmts.append(
867
+ Stripped(
868
+ f"""\
869
+ let {index_var} = 0;
870
+ for (const item of that.{prop_name}) {{
871
+ {I}for (const error of this.transformWithContext(item, context)) {{
872
+ {II}error.path.prepend(
873
+ {III}new IndexSegment(
874
+ {IIII}that.{prop_name},
875
+ {IIII}{index_var}
876
+ {III})
877
+ {II});
878
+ {II}error.path.prepend(
879
+ {III}new PropertySegment(
880
+ {IIII}that,
881
+ {IIII}{prop_name_literal}
882
+ {III})
883
+ {II});
884
+ {II}yield error;
885
+ {I}}}
886
+ {I}{index_var}++;
887
+ }}"""
888
+ )
889
+ )
890
+
891
+ else:
892
+ assert_never(type_anno)
893
+
894
+ verify_block = Stripped("\n".join(stmts))
895
+
896
+ if isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation):
897
+ return (
898
+ Stripped(
899
+ f"""\
900
+ if (that.{prop_name} !== null) {{
901
+ {I}{indent_but_first_line(verify_block, I)}
902
+ }}"""
903
+ ),
904
+ None,
905
+ )
906
+
907
+ return verify_block, None
908
+
909
+
910
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
911
+ def _generate_transform_for_class(
912
+ cls: intermediate.ConcreteClass,
913
+ symbol_table: intermediate.SymbolTable,
914
+ base_environment: intermediate_type_inference.Environment,
915
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
916
+ """Generate the transform method to errors for the given concrete class."""
917
+ errors = [] # type: List[Error]
918
+ blocks = [] # type: List[Stripped]
919
+
920
+ environment = intermediate_type_inference.MutableEnvironment(
921
+ parent=base_environment
922
+ )
923
+
924
+ assert environment.find(Identifier("self")) is None
925
+ environment.set(
926
+ identifier=Identifier("self"),
927
+ type_annotation=intermediate_type_inference.OurTypeAnnotation(our_type=cls),
928
+ )
929
+
930
+ # region Generate the non-recursive part verifying the invariants
931
+
932
+ for invariant in cls.invariants:
933
+ invariant_code, error = _transpile_invariant(
934
+ invariant=invariant, symbol_table=symbol_table, environment=environment
935
+ )
936
+ if error is not None:
937
+ errors.append(
938
+ Error(
939
+ cls.parsed.node,
940
+ f"Failed to transpile the invariant of the class {cls.name!r}",
941
+ [error],
942
+ )
943
+ )
944
+ continue
945
+
946
+ assert invariant_code is not None
947
+
948
+ blocks.append(invariant_code)
949
+
950
+ # endregion
951
+
952
+ # region Split properties in two, constrained primitives and others
953
+
954
+ # We split the properties in two, those of constrained primitives and others.
955
+ # We do this in a separate step instead of duplicating the code to avoid bugs
956
+ # related to DRY on the splitting logic.
957
+
958
+ properties_constrained_primitives = [] # type: List[intermediate.Property]
959
+ properties_non_constrained_primitives = [] # type: List[intermediate.Property]
960
+ for prop in cls.properties:
961
+ prop_type = intermediate.beneath_optional(prop.type_annotation)
962
+ if isinstance(prop_type, intermediate.OurTypeAnnotation) and isinstance(
963
+ prop_type.our_type, intermediate.ConstrainedPrimitive
964
+ ):
965
+ properties_constrained_primitives.append(prop)
966
+ else:
967
+ properties_non_constrained_primitives.append(prop)
968
+
969
+ # endregion
970
+
971
+ # region Include constrained primitive verification in non-recusrive part
972
+
973
+ # Since constrained primitives are not included in the recursion, we verify
974
+ # properties of constrained primitives at the non-recurse block as well.
975
+ for prop in properties_constrained_primitives:
976
+ prop_type = intermediate.beneath_optional(prop.type_annotation)
977
+ if isinstance(prop_type, intermediate.OurTypeAnnotation) and isinstance(
978
+ prop_type.our_type, intermediate.ConstrainedPrimitive
979
+ ):
980
+ constrained_primitive_block, error = _generate_verify_property_snippet(
981
+ prop=prop
982
+ )
983
+ if error is not None:
984
+ errors.append(error)
985
+ else:
986
+ assert constrained_primitive_block is not None
987
+ if constrained_primitive_block != "":
988
+ blocks.append(constrained_primitive_block)
989
+
990
+ if len(errors) > 0:
991
+ return None, errors
992
+
993
+ # endregion
994
+
995
+ # region Generate the recursive part
996
+
997
+ recurse_prop_blocks = [] # type: List[Stripped]
998
+
999
+ for prop in properties_non_constrained_primitives:
1000
+ prop_block, error = _generate_verify_property_snippet(prop=prop)
1001
+ if error is not None:
1002
+ errors.append(error)
1003
+ else:
1004
+ assert prop_block is not None
1005
+ if prop_block != "":
1006
+ recurse_prop_blocks.append(prop_block)
1007
+
1008
+ if len(errors) > 0:
1009
+ return None, errors
1010
+
1011
+ if len(recurse_prop_blocks) > 0:
1012
+ joined_prop_blocks = "\n\n".join(recurse_prop_blocks)
1013
+ blocks.append(
1014
+ Stripped(
1015
+ f"""\
1016
+ if (context === true) {{
1017
+ {I}{indent_but_first_line(joined_prop_blocks, I)}
1018
+ }}"""
1019
+ )
1020
+ )
1021
+
1022
+ # endregion
1023
+
1024
+ cls_name = typescript_naming.class_name(cls.name)
1025
+
1026
+ no_verification = len(blocks) == 0
1027
+ if len(blocks) == 0:
1028
+ blocks.append(
1029
+ Stripped(
1030
+ f"""\
1031
+ // No verification has been defined for {cls_name}."""
1032
+ )
1033
+ )
1034
+
1035
+ transform_name = typescript_naming.method_name(
1036
+ Identifier(f"transform_{cls.name}_with_context")
1037
+ )
1038
+
1039
+ maybe_disable_that_unused = (
1040
+ ""
1041
+ if not no_verification
1042
+ else f"{I}// eslint-disable-next-line @typescript-eslint/no-unused-vars\n"
1043
+ )
1044
+
1045
+ maybe_disable_context_unused = (
1046
+ ""
1047
+ if len(recurse_prop_blocks) > 0
1048
+ else f"{I}// eslint-disable-next-line @typescript-eslint/no-unused-vars\n"
1049
+ )
1050
+
1051
+ writer = io.StringIO()
1052
+ writer.write(
1053
+ f"""\
1054
+ *{transform_name}(
1055
+ {maybe_disable_that_unused}{I}that: AasTypes.{cls_name},
1056
+ {maybe_disable_context_unused}{I}context: boolean
1057
+ ): IterableIterator<VerificationError> {{
1058
+ """
1059
+ )
1060
+
1061
+ for i, stmt in enumerate(blocks):
1062
+ if i > 0:
1063
+ writer.write("\n\n")
1064
+ writer.write(textwrap.indent(stmt, I))
1065
+
1066
+ writer.write("\n}")
1067
+
1068
+ return Stripped(writer.getvalue()), None
1069
+
1070
+
1071
+ def _generate_transformer(
1072
+ symbol_table: intermediate.SymbolTable,
1073
+ base_environment: intermediate_type_inference.Environment,
1074
+ spec_impls: specific_implementations.SpecificImplementations,
1075
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
1076
+ """Generate a transformer to double-dispatch an instance to errors."""
1077
+ errors = [] # type: List[Error]
1078
+
1079
+ blocks = [] # type: List[Stripped]
1080
+
1081
+ # The abstract classes are directly dispatched by the transformer,
1082
+ # so we do not need to handle them separately.
1083
+ for cls in symbol_table.concrete_classes:
1084
+ if cls.is_implementation_specific:
1085
+ transform_key = specific_implementations.ImplementationKey(
1086
+ f"Verification/transform_{cls.name}.ts"
1087
+ )
1088
+
1089
+ implementation = spec_impls.get(transform_key, None)
1090
+ if implementation is None:
1091
+ errors.append(
1092
+ Error(
1093
+ cls.parsed.node,
1094
+ f"The transformation snippet is missing "
1095
+ f"for the implementation-specific "
1096
+ f"class {cls.name}: {transform_key}",
1097
+ )
1098
+ )
1099
+ continue
1100
+
1101
+ blocks.append(spec_impls[transform_key])
1102
+ else:
1103
+ block, cls_errors = _generate_transform_for_class(
1104
+ cls=cls,
1105
+ symbol_table=symbol_table,
1106
+ base_environment=base_environment,
1107
+ )
1108
+ if cls_errors is not None:
1109
+ errors.extend(cls_errors)
1110
+ else:
1111
+ assert block is not None
1112
+ blocks.append(block)
1113
+
1114
+ if len(errors) > 0:
1115
+ return None, errors
1116
+
1117
+ writer = io.StringIO()
1118
+ writer.write(
1119
+ f"""\
1120
+ /**
1121
+ * Verify an instance of the model recursively or non-recursively (depending on the context).
1122
+ */
1123
+ class Verifier
1124
+ {I}extends AasTypes.AbstractTransformerWithContext<
1125
+ {II}boolean, IterableIterator<VerificationError>
1126
+ {I}> {{
1127
+ """
1128
+ )
1129
+
1130
+ for i, block in enumerate(blocks):
1131
+ if i > 0:
1132
+ writer.write("\n\n")
1133
+ writer.write(textwrap.indent(block, I))
1134
+
1135
+ writer.write("\n}")
1136
+
1137
+ return Stripped(writer.getvalue()), None
1138
+
1139
+
1140
+ def _generate_verify_constrained_primitive(
1141
+ constrained_primitive: intermediate.ConstrainedPrimitive,
1142
+ symbol_table: intermediate.SymbolTable,
1143
+ base_environment: intermediate_type_inference.Environment,
1144
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
1145
+ """Generate the verify function for the constrained primitives."""
1146
+ errors = [] # type: List[Error]
1147
+ blocks = [] # type: List[Stripped]
1148
+
1149
+ environment = intermediate_type_inference.MutableEnvironment(
1150
+ parent=base_environment
1151
+ )
1152
+
1153
+ assert environment.find(Identifier("self")) is None
1154
+ environment.set(
1155
+ identifier=Identifier("self"),
1156
+ type_annotation=intermediate_type_inference.OurTypeAnnotation(
1157
+ our_type=constrained_primitive
1158
+ ),
1159
+ )
1160
+
1161
+ for invariant in constrained_primitive.invariants:
1162
+ invariant_code, error = _transpile_invariant(
1163
+ invariant=invariant, symbol_table=symbol_table, environment=environment
1164
+ )
1165
+ if error is not None:
1166
+ errors.append(
1167
+ Error(
1168
+ constrained_primitive.parsed.node,
1169
+ f"Failed to transpile the invariant of "
1170
+ f"the constrained primitive {constrained_primitive.name!r}",
1171
+ [error],
1172
+ )
1173
+ )
1174
+ continue
1175
+
1176
+ assert invariant_code is not None
1177
+
1178
+ blocks.append(invariant_code)
1179
+
1180
+ if len(errors) > 0:
1181
+ return None, errors
1182
+
1183
+ no_verification = False
1184
+ if len(blocks) == 0:
1185
+ blocks.append(Stripped("// There is no verification specified."))
1186
+ no_verification = True
1187
+
1188
+ function_name = typescript_naming.function_name(
1189
+ Identifier(f"verify_{constrained_primitive.name}")
1190
+ )
1191
+
1192
+ that_type = typescript_common.PRIMITIVE_TYPE_MAP[constrained_primitive.constrainee]
1193
+
1194
+ writer = io.StringIO()
1195
+
1196
+ writer.write(
1197
+ """\
1198
+ /**
1199
+ * Verify the constraints of `that` value.
1200
+ *
1201
+ * @param that - to be verified
1202
+ * @returns errors, if any
1203
+ */
1204
+ """
1205
+ )
1206
+
1207
+ if no_verification:
1208
+ writer.write(
1209
+ f"""\
1210
+ export function *{function_name}(
1211
+ {I}// eslint-disable-next-line @typescript-eslint/no-unused-vars
1212
+ {I}that: {that_type}
1213
+ ): IterableIterator<VerificationError> {{
1214
+ """
1215
+ )
1216
+ else:
1217
+ writer.write(
1218
+ f"""\
1219
+ export function *{function_name}(
1220
+ {I}that: {that_type}
1221
+ ): IterableIterator<VerificationError> {{
1222
+ """
1223
+ )
1224
+
1225
+ for i, block in enumerate(blocks):
1226
+ if i > 0:
1227
+ writer.write("\n\n")
1228
+ writer.write(textwrap.indent(block, I))
1229
+
1230
+ writer.write("\n}")
1231
+
1232
+ assert len(errors) == 0
1233
+ return Stripped(writer.getvalue()), None
1234
+
1235
+
1236
+ def _generate_module_comment(
1237
+ symbol_table: intermediate.SymbolTable,
1238
+ spec_impls: specific_implementations.SpecificImplementations,
1239
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
1240
+ """Generate the documentation comment for the module."""
1241
+ package_identifier_key = specific_implementations.ImplementationKey(
1242
+ "package_identifier.txt"
1243
+ )
1244
+
1245
+ package_identifier = spec_impls.get(package_identifier_key, None)
1246
+ if package_identifier is None:
1247
+ return None, Error(
1248
+ None,
1249
+ f"The package identifier snippet is missing "
1250
+ f"in the specific implementations: {package_identifier_key}",
1251
+ )
1252
+
1253
+ assert package_identifier is not None
1254
+
1255
+ blocks = [
1256
+ Stripped("Verify that the instances of the meta-model satisfy the invariants.")
1257
+ ] # type: List[Stripped]
1258
+
1259
+ first_cls = (
1260
+ symbol_table.concrete_classes[0]
1261
+ if len(symbol_table.concrete_classes) > 0
1262
+ else None
1263
+ ) # type: Optional[intermediate.ConcreteClass]
1264
+
1265
+ if first_cls is not None:
1266
+ cls_name = typescript_naming.class_name(first_cls.name)
1267
+ an_instance_variable = typescript_naming.variable_name(
1268
+ Identifier("an_instance")
1269
+ )
1270
+
1271
+ blocks.append(
1272
+ Stripped(
1273
+ f"""\
1274
+ Here is an example how to verify an instance of {{@link types.{cls_name}}}:
1275
+
1276
+ ```ts
1277
+ import * as AasTypes from "{package_identifier}/types";
1278
+ import * as AasVerification from "{package_identifier}/verification";
1279
+
1280
+ const {an_instance_variable} = new AasTypes.{cls_name}(
1281
+ {I}// ... some constructor arguments ...
1282
+ );
1283
+
1284
+ for (const error of AasVerification.verify({an_instance_variable})) {{
1285
+ {I}console.log(`${{error.message}} at: ${{error.path}}`);
1286
+ }}
1287
+ ```"""
1288
+ )
1289
+ )
1290
+
1291
+ # endregion
1292
+
1293
+ text = "\n\n".join(blocks)
1294
+
1295
+ return Stripped(typescript_description.documentation_comment(Stripped(text))), None
1296
+
1297
+
1298
+ # fmt: off
1299
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1300
+ @ensure(
1301
+ lambda result:
1302
+ not (result[0] is not None) or result[0].endswith('\n'),
1303
+ "Trailing newline mandatory for valid end-of-files"
1304
+ )
1305
+ # fmt: on
1306
+ def generate(
1307
+ symbol_table: intermediate.SymbolTable,
1308
+ spec_impls: specific_implementations.SpecificImplementations,
1309
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
1310
+ """Generate the TypeScript code for verification based on the symbol table."""
1311
+ errors = [] # type: List[Error]
1312
+
1313
+ module_docstring, module_docstring_error = _generate_module_comment(
1314
+ symbol_table=symbol_table, spec_impls=spec_impls
1315
+ )
1316
+ if module_docstring_error is not None:
1317
+ errors.append(module_docstring_error)
1318
+ # NOTE (mristin, 2023-03-18):
1319
+ # Allow the execution to continue to catch other errors as well
1320
+ module_docstring = Stripped("")
1321
+
1322
+ assert module_docstring is not None
1323
+
1324
+ blocks = [
1325
+ module_docstring,
1326
+ typescript_common.WARNING,
1327
+ Stripped(
1328
+ """\
1329
+ import * as AasCommon from "./common";
1330
+ import * as AasConstants from "./constants";
1331
+ import * as AasTypes from "./types";"""
1332
+ ),
1333
+ Stripped(
1334
+ """\
1335
+ // The generated code might contain deliberately double negations. For example,
1336
+ // when the constraint is formulated as a NAND and we check that the constraint
1337
+ // is not fulfilled. Therefore, we disable this linting rule.
1338
+ /* eslint no-extra-boolean-cast: 0 */"""
1339
+ ),
1340
+ Stripped(
1341
+ f"""\
1342
+ /**
1343
+ * Represent a property access on a path to an erroneous value.
1344
+ */
1345
+ export class PropertySegment {{
1346
+ {I}/**
1347
+ {I} * Instance containing the property
1348
+ {I} */
1349
+ {I}readonly instance: AasTypes.Class;
1350
+
1351
+ {I}/**
1352
+ {I} * Name of the property
1353
+ {I} */
1354
+ {I}readonly name: string;
1355
+
1356
+ {I}constructor(instance: AasTypes.Class, name: string) {{
1357
+ {II}this.instance = instance;
1358
+ {II}this.name = name;
1359
+ {I}}}
1360
+
1361
+ {I}toString(): string {{
1362
+ {II}return `.${{this.name}}`;
1363
+ {I}}}
1364
+ }}"""
1365
+ ),
1366
+ Stripped(
1367
+ f"""\
1368
+ /**
1369
+ * Represent an index access on a path to an erroneous value.
1370
+ */
1371
+ export class IndexSegment {{
1372
+ {I}/**
1373
+ {I} * Sequence containing the item at {{@link index}}
1374
+ {I} */
1375
+ {I}readonly sequence: Array<AasTypes.Class>;
1376
+
1377
+ {I}/**
1378
+ {I} * Index of the item in the {{@link sequence}}
1379
+ {I} */
1380
+ {I}readonly index: number;
1381
+
1382
+ {I}constructor(sequence: Array<AasTypes.Class>, index: number) {{
1383
+ {II}this.sequence = sequence;
1384
+ {II}this.index = index;
1385
+ {I}}}
1386
+
1387
+ {I}toString(): string {{
1388
+ {II}return `[${{this.index}}]`;
1389
+ {I}}}
1390
+ }}"""
1391
+ ),
1392
+ Stripped("export type Segment = PropertySegment | IndexSegment;"),
1393
+ Stripped(
1394
+ f"""\
1395
+ /**
1396
+ * Represent the relative path to the erroneous value.
1397
+ */
1398
+ export class Path {{
1399
+ {I}readonly segments: Array<Segment> = [];
1400
+
1401
+ {I}prepend(segment: Segment): void {{
1402
+ {II}this.segments.unshift(segment);
1403
+ {I}}}
1404
+
1405
+ {I}toString(): string {{
1406
+ {II}return this.segments.join("");
1407
+ {I}}}
1408
+ }}"""
1409
+ ),
1410
+ Stripped(
1411
+ f"""\
1412
+ /**
1413
+ * Represent a verification error in the data.
1414
+ */
1415
+ export class VerificationError {{
1416
+ {I}// NOTE (mristin, 2022-11-12):
1417
+ {I}// The name `VerificationError` is redundant since it lives in `verification` module,
1418
+ {I}// and it would have made more sense to call it simply `Error`. Unfortunately in this case,
1419
+ {I}// `Error` is a reserved name by JavaScript.
1420
+
1421
+ {I}/**
1422
+ {I} * Human-readable description of the error
1423
+ {I} */
1424
+ {I}readonly message: string;
1425
+
1426
+ {I}/**
1427
+ {I} * Path to the erroneous value
1428
+ {I} */
1429
+ {I}readonly path: Path = new Path();
1430
+
1431
+ {I}/**
1432
+ {I} * Initialize with the given `message` and `path`.
1433
+ {I} *
1434
+ {I} * @remarks
1435
+ {I} * If no `path` is specified, initialize with an empty path.
1436
+ {I} */
1437
+ {I}constructor(message: string, path: Path | null = null) {{
1438
+ {II}this.message = message;
1439
+ {II}this.path = (path !== null)
1440
+ {III}? path
1441
+ {III}: new Path();
1442
+ {I}}}
1443
+ }}"""
1444
+ ),
1445
+ ] # type: List[Stripped]
1446
+
1447
+ base_environment = intermediate_type_inference.populate_base_environment(
1448
+ symbol_table=symbol_table
1449
+ )
1450
+
1451
+ for verification in symbol_table.verification_functions:
1452
+ if isinstance(verification, intermediate.ImplementationSpecificVerification):
1453
+ implementation_key = specific_implementations.ImplementationKey(
1454
+ f"Verification/{verification.name}.ts"
1455
+ )
1456
+
1457
+ implementation = spec_impls.get(implementation_key, None)
1458
+ if implementation is None:
1459
+ errors.append(
1460
+ Error(
1461
+ None,
1462
+ f"The snippet for the verification function "
1463
+ f"{verification.name!r} is missing: {implementation_key}",
1464
+ )
1465
+ )
1466
+ else:
1467
+ blocks.append(implementation)
1468
+
1469
+ elif isinstance(verification, intermediate.PatternVerification):
1470
+ implementation, error = _transpile_pattern_verification(
1471
+ verification=verification
1472
+ )
1473
+
1474
+ if error is not None:
1475
+ errors.append(error)
1476
+ else:
1477
+ assert implementation is not None
1478
+ blocks.append(implementation)
1479
+
1480
+ elif isinstance(verification, intermediate.TranspilableVerification):
1481
+ implementation, error = _transpile_transpilable_verification(
1482
+ verification=verification,
1483
+ symbol_table=symbol_table,
1484
+ environment=base_environment,
1485
+ )
1486
+
1487
+ if error is not None:
1488
+ errors.append(error)
1489
+ else:
1490
+ assert implementation is not None
1491
+ blocks.append(implementation)
1492
+
1493
+ else:
1494
+ assert_never(verification)
1495
+
1496
+ transformer_block, transformer_errors = _generate_transformer(
1497
+ symbol_table=symbol_table,
1498
+ base_environment=base_environment,
1499
+ spec_impls=spec_impls,
1500
+ )
1501
+ if transformer_errors is not None:
1502
+ errors.extend(transformer_errors)
1503
+ else:
1504
+ assert transformer_block is not None
1505
+ blocks.append(transformer_block)
1506
+
1507
+ blocks.append(Stripped("const VERIFIER = new Verifier();"))
1508
+
1509
+ blocks.append(
1510
+ Stripped(
1511
+ f"""\
1512
+ /**
1513
+ * Verify the constraints of `that`.
1514
+ *
1515
+ * @param that - instance to be verified
1516
+ * @param recurse - if set, continue the verification recursively
1517
+ * @returns a stream of verification errors
1518
+ */
1519
+ export function *verify(
1520
+ that: AasTypes.Class,
1521
+ recurse = true
1522
+ ): IterableIterator<VerificationError> {{
1523
+ {I}yield * VERIFIER.transformWithContext(that, recurse);
1524
+ }}"""
1525
+ )
1526
+ )
1527
+
1528
+ for our_type in symbol_table.our_types:
1529
+ if isinstance(our_type, intermediate.Enumeration):
1530
+ # NOTE (mristin, 2022-11-12):
1531
+ # We do not verify the enumerations explicitly in TypeScript and
1532
+ # leave those checks to TypeScript compiler.
1533
+ pass
1534
+
1535
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
1536
+ (
1537
+ constrained_primitive_block,
1538
+ constrained_primitive_errors,
1539
+ ) = _generate_verify_constrained_primitive(
1540
+ constrained_primitive=our_type,
1541
+ symbol_table=symbol_table,
1542
+ base_environment=base_environment,
1543
+ )
1544
+
1545
+ if constrained_primitive_errors is not None:
1546
+ errors.extend(constrained_primitive_errors)
1547
+ else:
1548
+ assert constrained_primitive_block is not None
1549
+ blocks.append(constrained_primitive_block)
1550
+
1551
+ elif isinstance(
1552
+ our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
1553
+ ):
1554
+ # NOTE (mristin, 2022-11-12):
1555
+ # We provide a general dispatch function for the most abstract
1556
+ # class ``Class``.
1557
+ pass
1558
+ else:
1559
+ assert_never(our_type)
1560
+
1561
+ blocks.append(typescript_common.WARNING)
1562
+
1563
+ if len(errors) > 0:
1564
+ return None, errors
1565
+
1566
+ writer = io.StringIO()
1567
+ for i, block in enumerate(blocks):
1568
+ if i > 0:
1569
+ writer.write("\n\n")
1570
+
1571
+ writer.write(block)
1572
+
1573
+ writer.write("\n")
1574
+
1575
+ return writer.getvalue(), None
1576
+
1577
+
1578
+ # endregion