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,1503 @@
1
+ """Generate the C++ data structures from the intermediate representation."""
2
+ import io
3
+ import itertools
4
+ import textwrap
5
+ from typing import (
6
+ Optional,
7
+ Dict,
8
+ List,
9
+ Tuple,
10
+ cast,
11
+ Union,
12
+ )
13
+
14
+ from icontract import ensure, require
15
+
16
+ from aas_core_codegen import intermediate
17
+ from aas_core_codegen import specific_implementations
18
+ from aas_core_codegen.common import (
19
+ Error,
20
+ Identifier,
21
+ assert_never,
22
+ Stripped,
23
+ indent_but_first_line,
24
+ )
25
+ from aas_core_codegen.cpp import (
26
+ common as cpp_common,
27
+ naming as cpp_naming,
28
+ description as cpp_description,
29
+ )
30
+ from aas_core_codegen.cpp.common import (
31
+ INDENT as I,
32
+ INDENT2 as II,
33
+ INDENT3 as III,
34
+ INDENT4 as IIII,
35
+ )
36
+ from aas_core_codegen.intermediate import construction as intermediate_construction
37
+
38
+
39
+ # region Checks
40
+
41
+
42
+ def _human_readable_identifier(
43
+ something: Union[
44
+ intermediate.Enumeration,
45
+ intermediate.AbstractClass,
46
+ intermediate.ConcreteClass,
47
+ intermediate.EnumerationLiteral,
48
+ ]
49
+ ) -> str:
50
+ """
51
+ Represent ``something`` in a human-readable text.
52
+
53
+ The reader should be able to trace ``something`` back to the meta-model.
54
+ """
55
+ # NOTE (mristin, 2023-03-29):
56
+ # This function has been copy-pasted from
57
+ # :py:mod:`aas_core_codegen.python.structure._generate`. We tried to refactor it to
58
+ # :py:mod:`aas_core_codegen.intermediate`, but it turned out that the refactored
59
+ # code was nigh unreadable. So we preferred a little bit of copying to a little
60
+ # bit of complexity.
61
+
62
+ result: str
63
+
64
+ if isinstance(something, intermediate.Enumeration):
65
+ result = f"meta-model enumeration {something.name!r}"
66
+ elif isinstance(something, intermediate.EnumerationLiteral):
67
+ result = f"meta-model enumeration literal {something.name!r}"
68
+ elif isinstance(something, intermediate.AbstractClass):
69
+ result = f"meta-model abstract class {something.name!r}"
70
+ elif isinstance(something, intermediate.ConcreteClass):
71
+ result = f"meta-model concrete class {something.name!r}"
72
+ else:
73
+ assert_never(something)
74
+
75
+ return result
76
+
77
+
78
+ def _verify_intra_structure_collisions(
79
+ our_type: intermediate.OurType,
80
+ ) -> Optional[Error]:
81
+ """Verify that no member names collide in the Golang structure of our type."""
82
+ errors = [] # type: List[Error]
83
+
84
+ if isinstance(our_type, intermediate.Enumeration):
85
+ observed_literal_names = {} # type: Dict[Identifier, str]
86
+ for literal in our_type.literals:
87
+ name = cpp_naming.enum_literal_name(literal.name)
88
+
89
+ if name in observed_literal_names:
90
+ errors.append(
91
+ Error(
92
+ literal.parsed.node,
93
+ f"C++ name {name!r} corresponding "
94
+ f"to the meta-model enumeration literal {literal.name!r} "
95
+ f"collides with the literal {observed_literal_names[name]}",
96
+ )
97
+ )
98
+ else:
99
+ observed_literal_names[name] = literal.name
100
+
101
+ elif isinstance(our_type, intermediate.ConstrainedPrimitive):
102
+ pass
103
+
104
+ elif isinstance(our_type, intermediate.Class):
105
+ observed_member_names = {} # type: Dict[Identifier, str]
106
+
107
+ for prop in our_type.properties:
108
+ name = cpp_naming.getter_name(prop.name)
109
+ if name in observed_member_names:
110
+ errors.append(
111
+ Error(
112
+ prop.parsed.node,
113
+ f"C++ getter {name!r} corresponding "
114
+ f"to the meta-model property {prop.name!r} collides with "
115
+ f"the {observed_member_names[name]}",
116
+ )
117
+ )
118
+ else:
119
+ observed_member_names[name] = (
120
+ f"C++ getter {name!r} corresponding to "
121
+ f"the meta-model property {prop.name!r}"
122
+ )
123
+
124
+ name = cpp_naming.mutable_getter_name(prop.name)
125
+ if name in observed_member_names:
126
+ errors.append(
127
+ Error(
128
+ prop.parsed.node,
129
+ f"C++ mutable getter {name!r} corresponding "
130
+ f"to the meta-model property {prop.name!r} collides with "
131
+ f"the {observed_member_names[name]}",
132
+ )
133
+ )
134
+ else:
135
+ observed_member_names[name] = (
136
+ f"C++ mutable getter {name!r} corresponding to "
137
+ f"the meta-model property {prop.name!r}"
138
+ )
139
+
140
+ name = cpp_naming.setter_name(prop.name)
141
+ if name in observed_member_names:
142
+ errors.append(
143
+ Error(
144
+ prop.parsed.node,
145
+ f"C++ setter {name!r} corresponding "
146
+ f"to the meta-model property {prop.name!r} collides with "
147
+ f"the {observed_member_names[name]}",
148
+ )
149
+ )
150
+ else:
151
+ observed_member_names[name] = (
152
+ f"C++ setter {name!r} corresponding to "
153
+ f"the meta-model property {prop.name!r}"
154
+ )
155
+
156
+ name = cpp_naming.private_property_name(prop.name)
157
+ if name in observed_member_names:
158
+ errors.append(
159
+ Error(
160
+ prop.parsed.node,
161
+ f"C++ private property {name!r} corresponding "
162
+ f"to the meta-model property {prop.name!r} collides with "
163
+ f"the {observed_member_names[name]}",
164
+ )
165
+ )
166
+ else:
167
+ observed_member_names[name] = (
168
+ f"C++ private property {name!r} corresponding to "
169
+ f"the meta-model property {prop.name!r}"
170
+ )
171
+
172
+ for method in our_type.methods:
173
+ method_name = cpp_naming.method_name(method.name)
174
+
175
+ if method_name in observed_member_names:
176
+ errors.append(
177
+ Error(
178
+ method.parsed.node,
179
+ f"C++ method {method_name!r} corresponding "
180
+ f"to the meta-model method {method.name!r} collides with "
181
+ f"the {observed_member_names[method_name]}",
182
+ )
183
+ )
184
+ else:
185
+ observed_member_names[method_name] = (
186
+ f"C++ method {method_name!r} corresponding to "
187
+ f"the meta-model method {method.name!r}"
188
+ )
189
+
190
+ else:
191
+ assert_never(our_type)
192
+
193
+ if len(errors) > 0:
194
+ errors.append(
195
+ Error(
196
+ our_type.parsed.node,
197
+ f"Naming collision(s) in C++ code for our type {our_type.name!r}",
198
+ underlying=errors,
199
+ )
200
+ )
201
+
202
+ return None
203
+
204
+
205
+ def _verify_structure_name_collisions(
206
+ symbol_table: intermediate.SymbolTable,
207
+ ) -> List[Error]:
208
+ """Verify that the C++ names of the structures do not collide."""
209
+ observed_type_names: Dict[
210
+ Identifier,
211
+ Union[
212
+ intermediate.Enumeration,
213
+ intermediate.AbstractClass,
214
+ intermediate.ConcreteClass,
215
+ ],
216
+ ] = dict()
217
+
218
+ errors = [] # type: List[Error]
219
+
220
+ # region Inter-structure collisions
221
+
222
+ for enum_or_cls in itertools.chain(symbol_table.enumerations, symbol_table.classes):
223
+ names: List[Identifier]
224
+
225
+ if isinstance(enum_or_cls, intermediate.Enumeration):
226
+ names = [cpp_naming.enum_name(enum_or_cls.name)]
227
+ elif isinstance(enum_or_cls, intermediate.AbstractClass):
228
+ names = [cpp_naming.interface_name(enum_or_cls.name)]
229
+ elif isinstance(enum_or_cls, intermediate.ConcreteClass):
230
+ names = [
231
+ cpp_naming.interface_name(enum_or_cls.name),
232
+ cpp_naming.class_name(enum_or_cls.name),
233
+ ]
234
+ else:
235
+ assert_never(enum_or_cls)
236
+
237
+ for name in names:
238
+ other = observed_type_names.get(name, None)
239
+
240
+ if other is not None:
241
+ errors.append(
242
+ Error(
243
+ enum_or_cls.parsed.node,
244
+ f"The C++ name {name!r} "
245
+ f"of the {_human_readable_identifier(enum_or_cls)} "
246
+ f"collides with the C++ name "
247
+ f"of the {_human_readable_identifier(other)}",
248
+ )
249
+ )
250
+ else:
251
+ observed_type_names[name] = enum_or_cls
252
+
253
+ # endregion
254
+
255
+ # region Intra-structure collisions
256
+
257
+ for our_type in symbol_table.our_types:
258
+ collision_error = _verify_intra_structure_collisions(our_type=our_type)
259
+
260
+ if collision_error is not None:
261
+ errors.append(collision_error)
262
+
263
+ # endregion
264
+
265
+ return errors
266
+
267
+
268
+ class VerifiedIntermediateSymbolTable(intermediate.SymbolTable):
269
+ """Represent a verified symbol table which can be used for code generation."""
270
+
271
+ # noinspection PyInitNewSignature
272
+ def __new__(
273
+ cls, symbol_table: intermediate.SymbolTable
274
+ ) -> "VerifiedIntermediateSymbolTable":
275
+ raise AssertionError("Only for type annotation")
276
+
277
+
278
+ @ensure(lambda result: (result[0] is None) ^ (result[1] is None))
279
+ def verify(
280
+ symbol_table: intermediate.SymbolTable,
281
+ ) -> Tuple[Optional[VerifiedIntermediateSymbolTable], Optional[List[Error]]]:
282
+ """Verify that Golang code can be generated from the ``symbol_table``."""
283
+ errors = [] # type: List[Error]
284
+
285
+ structure_name_collisions = _verify_structure_name_collisions(
286
+ symbol_table=symbol_table
287
+ )
288
+
289
+ errors.extend(structure_name_collisions)
290
+
291
+ if len(errors) > 0:
292
+ return None, errors
293
+
294
+ return cast(VerifiedIntermediateSymbolTable, symbol_table), None
295
+
296
+
297
+ # endregion
298
+
299
+ # region Generation
300
+
301
+
302
+ @require(lambda enumeration, literal: id(literal) in enumeration.literal_id_set)
303
+ @require(lambda literal: literal.description is not None)
304
+ def _generate_comment_for_enumeration_literal(
305
+ enumeration: intermediate.Enumeration,
306
+ literal: intermediate.EnumerationLiteral,
307
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
308
+ """Generate the documentation comment for the given enumeration literal."""
309
+ # NOTE (mristin, 2023-07-14):
310
+ # We need to state the pre-condition for the second time for mypy.
311
+ assert literal.description is not None
312
+
313
+ # fmt: off
314
+ comment, errors = (
315
+ cpp_description.generate_comment_for_summary_remarks(
316
+ description=literal.description,
317
+ context=cpp_description.Context(
318
+ namespace=cpp_common.TYPES_NAMESPACE,
319
+ cls_or_enum=enumeration
320
+ )
321
+ )
322
+ )
323
+ # fmt: on
324
+
325
+ if errors is not None:
326
+ return None, errors
327
+
328
+ assert comment is not None
329
+
330
+ return comment, None
331
+
332
+
333
+ @require(lambda cls_or_enum: cls_or_enum.description is not None)
334
+ def _generate_comment_for_cls_or_enum(
335
+ cls_or_enum: Union[intermediate.Enumeration, intermediate.ClassUnion],
336
+ ) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
337
+ """Generate the documentation comment for our type."""
338
+ # NOTE (mristin, 2023-07-14):
339
+ # We need to state the pre-condition for the second time for mypy.
340
+ assert cls_or_enum.description is not None
341
+
342
+ # fmt: off
343
+ comment, errors = (
344
+ cpp_description
345
+ .generate_comment_for_summary_remarks_constraints(
346
+ description=cls_or_enum.description,
347
+ context=cpp_description.Context(
348
+ namespace=cpp_common.TYPES_NAMESPACE,
349
+ cls_or_enum=None
350
+ )
351
+ )
352
+ )
353
+ # fmt: on
354
+
355
+ if errors is not None:
356
+ return None, errors
357
+
358
+ assert comment is not None
359
+
360
+ return comment, None
361
+
362
+
363
+ @ensure(lambda result: (result[0] is None) ^ (result[1] is None))
364
+ def _generate_enum(
365
+ enum: intermediate.Enumeration,
366
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
367
+ """Generate the C++ code for the enum."""
368
+ writer = io.StringIO()
369
+
370
+ errors = [] # type: List[Error]
371
+
372
+ comment = None # type: Optional[Stripped]
373
+ if enum.description is not None:
374
+ comment, comment_errors = _generate_comment_for_cls_or_enum(cls_or_enum=enum)
375
+
376
+ if comment_errors:
377
+ errors.append(
378
+ Error(
379
+ enum.description.parsed.node,
380
+ f"Failed to generate the comment "
381
+ f"for the enumeration {enum.name!r}",
382
+ comment_errors,
383
+ )
384
+ )
385
+ else:
386
+ assert comment is not None
387
+
388
+ if comment is not None:
389
+ writer.write(comment)
390
+ writer.write("\n")
391
+
392
+ name = cpp_naming.enum_name(enum.name)
393
+
394
+ writer.write(f"enum class {name} : std::uint32_t {{\n")
395
+ if len(enum.literals) == 0:
396
+ writer.write("// Intentionally empty.")
397
+ else:
398
+ for i, literal in enumerate(enum.literals):
399
+ if literal.description is not None:
400
+ comment, comment_errors = _generate_comment_for_enumeration_literal(
401
+ enumeration=enum, literal=literal
402
+ )
403
+ if comment_errors is not None:
404
+ errors.append(
405
+ Error(
406
+ literal.description.parsed.node,
407
+ f"Failed to generate the documentation comment "
408
+ f"for enumeration literal {literal.name!r}",
409
+ comment_errors,
410
+ )
411
+ )
412
+ else:
413
+ assert comment is not None
414
+ writer.write(textwrap.indent(comment, I))
415
+ writer.write("\n")
416
+
417
+ literal_name = cpp_naming.enum_literal_name(literal.name)
418
+
419
+ writer.write(textwrap.indent(f"{literal_name} = {i}", I))
420
+ if i < len(enum.literals):
421
+ writer.write(",\n")
422
+ else:
423
+ writer.write("\n")
424
+
425
+ writer.write(f"}}; // enum class {name}")
426
+
427
+ if len(errors) > 0:
428
+ return None, Error(
429
+ enum.parsed.node,
430
+ f"Failed to generate the Golang code for the enumeration {enum.name!r}",
431
+ errors,
432
+ )
433
+
434
+ return Stripped(writer.getvalue()), None
435
+
436
+
437
+ def _generate_literals_of_enum_definition(enum: intermediate.Enumeration) -> Stripped:
438
+ """Generate the definition for the constant vector listing the literals."""
439
+ enum_name = cpp_naming.enum_name(enum.name)
440
+ constant_name = cpp_naming.constant_name(Identifier(f"literals_of_{enum.name}"))
441
+ return Stripped(
442
+ f"""\
443
+ extern const std::vector<
444
+ {I}{enum_name}
445
+ > {constant_name};"""
446
+ )
447
+
448
+
449
+ def _generate_literals_of_enum_implementation(
450
+ enum: intermediate.Enumeration,
451
+ ) -> Stripped:
452
+ """Generate the implementation for the constant vector listing the literals."""
453
+ enum_name = cpp_naming.enum_name(enum.name)
454
+ constant_name = cpp_naming.constant_name(Identifier(f"literals_of_{enum.name}"))
455
+
456
+ literals = []
457
+ for literal in enum.literals:
458
+ literal_name = cpp_naming.enum_literal_name(literal.name)
459
+ literals.append(f"{enum_name}::{literal_name}")
460
+
461
+ literals_joined = ",\n".join(literals)
462
+
463
+ return Stripped(
464
+ f"""\
465
+ /**
466
+ * List the literals of {enum_name}.
467
+ *
468
+ * C++ does not provide an elegant way to iterate over the literals, so
469
+ * this array helps you avoid common errors and pitfalls.
470
+ */
471
+ const std::vector<
472
+ {I}{enum_name}
473
+ > {constant_name} = {{
474
+ {I}{indent_but_first_line(literals_joined, I)}
475
+ }};"""
476
+ )
477
+
478
+
479
+ def _generate_model_type_definition(
480
+ symbol_table: intermediate.SymbolTable,
481
+ ) -> Stripped:
482
+ """
483
+ Generate the enumeration corresponding to the model types.
484
+
485
+ This is necessary so that we can have fast switches on instance types.
486
+ """
487
+ enum_name = cpp_naming.enum_name(Identifier("Model_type"))
488
+
489
+ literal_specs = [] # type: List[Stripped]
490
+ for i, cls in enumerate(symbol_table.concrete_classes):
491
+ literal_name = cpp_naming.enum_literal_name(cls.name)
492
+
493
+ literal_specs.append(Stripped(f"{literal_name} = {i}"))
494
+
495
+ literal_specs_joined = ",\n".join(literal_specs)
496
+
497
+ if len(literal_specs) == 0:
498
+ return Stripped(
499
+ f"""\
500
+ enum class {enum_name} : std::uint32_t {{
501
+ {I}// Intentionally empty.
502
+ }};"""
503
+ )
504
+
505
+ return Stripped(
506
+ f"""\
507
+ /**
508
+ * Enumerate the model types for faster type switches.
509
+ *
510
+ * For example, switch statements can be implemented as jump tables.
511
+ */
512
+ enum class {enum_name} : std::uint32_t {{
513
+ {I}{indent_but_first_line(literal_specs_joined, I)}
514
+ }};"""
515
+ )
516
+
517
+
518
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
519
+ def _generate_class_interface(
520
+ cls: intermediate.ClassUnion,
521
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
522
+ """Generate the definition of an interface representing a class."""
523
+ errors = [] # type: List[Error]
524
+
525
+ members = [] # type: List[Stripped]
526
+
527
+ for prop in cls.properties:
528
+ if prop.specified_for is not cls:
529
+ continue
530
+
531
+ description_comment = None # type: Optional[Stripped]
532
+ if prop.description is not None:
533
+ (
534
+ description_comment,
535
+ description_errors,
536
+ ) = cpp_description.generate_comment_for_summary_remarks(
537
+ prop.description,
538
+ context=cpp_description.Context(
539
+ namespace=cpp_common.TYPES_NAMESPACE, cls_or_enum=cls
540
+ ),
541
+ )
542
+ if description_errors is not None:
543
+ errors.append(
544
+ Error(
545
+ prop.parsed.node,
546
+ f"Failed to generate the description comment "
547
+ f"for the property {prop.name!r}",
548
+ description_errors,
549
+ )
550
+ )
551
+ else:
552
+ assert description_comment is not None
553
+ members.append(
554
+ Stripped(
555
+ f"""\
556
+ ///@{{
557
+ {description_comment}"""
558
+ )
559
+ )
560
+
561
+ getter_name = cpp_naming.getter_name(prop.name)
562
+ getter_type = cpp_common.generate_type_with_const_ref_if_applicable(
563
+ prop.type_annotation
564
+ )
565
+
566
+ members.append(Stripped(f"virtual {getter_type} {getter_name}() const = 0;"))
567
+
568
+ mutable_getter_name = cpp_naming.mutable_getter_name(prop.name)
569
+ mutable_getter_type = cpp_common.generate_type_with_ref(prop.type_annotation)
570
+ members.append(
571
+ Stripped(f"virtual {mutable_getter_type} {mutable_getter_name}() = 0;")
572
+ )
573
+
574
+ setter_name = cpp_naming.setter_name(prop.name)
575
+ # NOTE (mristin, 2023-09-13):
576
+ # For a discussion on ``std::shared_ptr`` and referencing,
577
+ # see: https://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
578
+
579
+ # NOTE (mristin, 2023-09-13):
580
+ # We provide setters which only set-by-value logic since this seems to be
581
+ # the best approach for general cases,
582
+ # see: https://stackoverflow.com/questions/10692345/is-it-worth-adding-a-move-enabled-setter.
583
+ #
584
+ # Whenever you know that you do not need the value after calling the setter,
585
+ # make sure to call it with ``std::move(.)``.
586
+
587
+ value_type = cpp_common.generate_type(type_annotation=prop.type_annotation)
588
+ members.append(
589
+ Stripped(
590
+ f"""\
591
+ virtual void {setter_name}(
592
+ {I}{indent_but_first_line(value_type, I)} value
593
+ ) = 0;"""
594
+ )
595
+ )
596
+
597
+ if description_comment is not None:
598
+ members.append(Stripped("///@}"))
599
+
600
+ for method in cls.methods:
601
+ if method.specified_for is not cls:
602
+ continue
603
+
604
+ returns = (
605
+ cpp_common.generate_type(method.returns)
606
+ if method.returns is not None
607
+ else None
608
+ )
609
+
610
+ return_type = "void" if returns is None else returns
611
+
612
+ arg_types_names = [
613
+ (
614
+ cpp_common.generate_type_with_const_ref_if_applicable(
615
+ arg.type_annotation
616
+ ),
617
+ cpp_naming.argument_name(arg.name),
618
+ )
619
+ for arg in method.arguments
620
+ ]
621
+
622
+ method_name = cpp_naming.method_name(method.name)
623
+
624
+ const_suffix = " const" if method.non_mutating else ""
625
+
626
+ description_comment_prefix = ""
627
+ if method.description is not None:
628
+ (
629
+ description_comment,
630
+ description_errors,
631
+ ) = cpp_description.generate_comment_for_summary_remarks(
632
+ method.description,
633
+ context=cpp_description.Context(
634
+ namespace=cpp_common.TYPES_NAMESPACE, cls_or_enum=cls
635
+ ),
636
+ )
637
+ if description_errors is not None:
638
+ errors.append(
639
+ Error(
640
+ method.parsed.node,
641
+ f"Failed to generate the description comment "
642
+ f"for the method {method.name!r}",
643
+ description_errors,
644
+ )
645
+ )
646
+ else:
647
+ assert description_comment is not None
648
+ description_comment_prefix = description_comment + "\n"
649
+
650
+ if len(method.arguments) == 0:
651
+ members.append(
652
+ Stripped(
653
+ f"{description_comment_prefix}"
654
+ f"virtual {return_type} {method_name}(){const_suffix} = 0;"
655
+ )
656
+ )
657
+ else:
658
+ arguments_definition = ",\n".join(
659
+ f"{arg_type} {arg_name}" for arg_type, arg_name in arg_types_names
660
+ )
661
+
662
+ members.append(
663
+ Stripped(
664
+ f"""\
665
+ {description_comment_prefix}virtual {return_type} {method_name}(
666
+ {I}{indent_but_first_line(arguments_definition, I)}
667
+ ){const_suffix} = 0;"""
668
+ )
669
+ )
670
+
671
+ interface_name = cpp_naming.interface_name(cls.name)
672
+
673
+ members.append(Stripped(f"virtual ~{interface_name}() = default;"))
674
+
675
+ members_joined = "\n\n".join(members)
676
+
677
+ inheritances = [
678
+ f"virtual public {cpp_naming.interface_name(inheritance.name)}"
679
+ for inheritance in cls.inheritances
680
+ ]
681
+
682
+ if len(inheritances) == 0:
683
+ inheritances = ["virtual public IClass"]
684
+
685
+ inheritances_joined = ",\n".join(inheritances)
686
+
687
+ description_comment = None
688
+ if cls.description is not None:
689
+ (
690
+ description_comment,
691
+ description_errors,
692
+ ) = cpp_description.generate_comment_for_summary_remarks_constraints(
693
+ description=cls.description,
694
+ context=cpp_description.Context(
695
+ namespace=cpp_common.TYPES_NAMESPACE, cls_or_enum=cls
696
+ ),
697
+ )
698
+ if description_errors is not None:
699
+ errors.append(
700
+ Error(
701
+ cls.description.parsed.node,
702
+ "Failed to translate the class description to a comment",
703
+ description_errors,
704
+ )
705
+ )
706
+ else:
707
+ assert description_comment is not None
708
+
709
+ if len(errors) > 0:
710
+ return None, Error(
711
+ cls.parsed.node,
712
+ f"Failed to generate the class definition for {cls.name!r}",
713
+ errors,
714
+ )
715
+
716
+ maybe_description_comment_nl = (
717
+ "" if description_comment is None else description_comment + "\n"
718
+ )
719
+
720
+ return (
721
+ Stripped(
722
+ f"""\
723
+ {maybe_description_comment_nl}class {interface_name}
724
+ {II}: {indent_but_first_line(inheritances_joined, II)} {{
725
+ public:
726
+ {I}{indent_but_first_line(members_joined, I)}
727
+ }};"""
728
+ ),
729
+ None,
730
+ )
731
+
732
+
733
+ def _generate_class_definition(cls: intermediate.ConcreteClass) -> Stripped:
734
+ """Generate the definition of a concrete class."""
735
+ public_members = [] # type: List[Stripped]
736
+
737
+ cls_name = cpp_naming.class_name(cls.name)
738
+
739
+ if len(cls.constructor.arguments) == 0:
740
+ public_members.append(Stripped(f"{cls_name}() {{}}"))
741
+ else:
742
+ constructor_argument_specs = [] # type: List[str]
743
+ for arg in cls.constructor.arguments:
744
+ arg_type = cpp_common.generate_type(arg.type_annotation)
745
+ arg_name = cpp_naming.argument_name(arg.name)
746
+
747
+ assign_default_suffix = (
748
+ " = common::nullopt"
749
+ if isinstance(arg.type_annotation, intermediate.OptionalTypeAnnotation)
750
+ else ""
751
+ )
752
+
753
+ constructor_argument_specs.append(
754
+ f"{arg_type} {arg_name}{assign_default_suffix}"
755
+ )
756
+
757
+ constructor_arguments_specs_joined = ",\n".join(constructor_argument_specs)
758
+
759
+ # NOTE (mristin, 2023-09-22):
760
+ # See: https://stackoverflow.com/questions/12437241/c-always-use-explicit-constructor
761
+ non_default_argument_count = sum(
762
+ 1 for arg in cls.constructor.arguments if arg.default is None
763
+ )
764
+
765
+ explicit_prefix = "explicit " if non_default_argument_count == 1 else ""
766
+
767
+ public_members.append(
768
+ Stripped(
769
+ f"""\
770
+ {explicit_prefix}{cls_name}(
771
+ {I}{indent_but_first_line(constructor_arguments_specs_joined, I)}
772
+ );"""
773
+ )
774
+ )
775
+
776
+ model_type_getter = cpp_naming.getter_name(Identifier("model_type"))
777
+ model_type_enum = cpp_naming.enum_name(Identifier("Model_type"))
778
+
779
+ public_members.append(
780
+ Stripped(f"{model_type_enum} {model_type_getter}() const override;")
781
+ )
782
+
783
+ for prop in cls.properties:
784
+ getter_name = cpp_naming.getter_name(prop.name)
785
+ getter_type = cpp_common.generate_type_with_const_ref_if_applicable(
786
+ prop.type_annotation
787
+ )
788
+
789
+ public_members.append(
790
+ Stripped(
791
+ f"// region Get and set {cpp_naming.private_property_name(prop.name)}"
792
+ )
793
+ )
794
+
795
+ public_members.append(
796
+ Stripped(f"{getter_type} {getter_name}() const override;")
797
+ )
798
+
799
+ mutable_getter_name = cpp_naming.mutable_getter_name(prop.name)
800
+ mutable_getter_type = cpp_common.generate_type_with_ref(prop.type_annotation)
801
+ public_members.append(
802
+ Stripped(f"{mutable_getter_type} {mutable_getter_name}() override;")
803
+ )
804
+
805
+ setter_name = cpp_naming.setter_name(prop.name)
806
+
807
+ value_type = cpp_common.generate_type(type_annotation=prop.type_annotation)
808
+ public_members.append(
809
+ Stripped(
810
+ f"""\
811
+ void {setter_name}(
812
+ {I}{indent_but_first_line(value_type, I)} value
813
+ ) override;"""
814
+ )
815
+ )
816
+
817
+ public_members.append(Stripped("// endregion"))
818
+
819
+ for method in cls.methods:
820
+ returns = (
821
+ cpp_common.generate_type(method.returns)
822
+ if method.returns is not None
823
+ else None
824
+ )
825
+
826
+ return_type = "void" if returns is None else returns
827
+
828
+ arg_types_names = [
829
+ (
830
+ cpp_common.generate_type_with_const_ref_if_applicable(
831
+ arg.type_annotation
832
+ ),
833
+ cpp_naming.argument_name(arg.name),
834
+ )
835
+ for arg in method.arguments
836
+ ]
837
+
838
+ method_name = cpp_naming.method_name(method.name)
839
+
840
+ const_suffix = " const" if method.non_mutating else ""
841
+
842
+ if len(method.arguments) == 0:
843
+ public_members.append(
844
+ Stripped(f"{return_type} {method_name}(){const_suffix} override;")
845
+ )
846
+ else:
847
+ arguments_definition = ",\n".join(
848
+ f"{arg_type} {arg_name}" for arg_type, arg_name in arg_types_names
849
+ )
850
+
851
+ public_members.append(
852
+ Stripped(
853
+ f"""\
854
+ {return_type} {method_name}(
855
+ {I}{indent_but_first_line(arguments_definition, I)}
856
+ ){const_suffix} override;"""
857
+ )
858
+ )
859
+
860
+ public_members.append(Stripped(f"~{cls_name}() override = default;"))
861
+
862
+ public_members_joined = "\n\n".join(public_members)
863
+
864
+ interface_name = cpp_naming.interface_name(cls.name)
865
+
866
+ private_members = [] # type: List[Stripped]
867
+ for prop in cls.properties:
868
+ value_type = cpp_common.generate_type(type_annotation=prop.type_annotation)
869
+
870
+ member_name = cpp_naming.private_property_name(prop.name)
871
+ private_members.append(Stripped(f"{value_type} {member_name};"))
872
+
873
+ blocks = [
874
+ f"""\
875
+ public:
876
+ {I}{indent_but_first_line(public_members_joined, I)}"""
877
+ ]
878
+
879
+ if len(private_members) > 0:
880
+ private_members_joined = "\n\n".join(private_members)
881
+ blocks.append(
882
+ f"""\
883
+ private:
884
+ {I}{indent_but_first_line(private_members_joined, I)}"""
885
+ )
886
+
887
+ blocks_joined = "\n\n".join(blocks)
888
+
889
+ return Stripped(
890
+ f"""\
891
+ class {cls_name}
892
+ {II}: public {interface_name} {{
893
+ {blocks_joined}
894
+ }};"""
895
+ )
896
+
897
+
898
+ def _generate_is_cls_definition(cls: intermediate.ClassUnion) -> Stripped:
899
+ """Generate the definition of the function to check is-a based on model type."""
900
+ function_name = cpp_naming.function_name(Identifier(f"is_{cls.name}"))
901
+
902
+ interface_name = cpp_naming.interface_name(cls.name)
903
+
904
+ return Stripped(
905
+ f"""\
906
+ /**
907
+ * \\brief Check whether \\p that instance is of runtime type
908
+ * \\ref {interface_name}.
909
+ *
910
+ * We use `IClass::model_type` to determine the runtime type, which is
911
+ * a bit faster than native C++'s RTTI.
912
+ *
913
+ * \\param that instance to check for runtime type
914
+ * \\return `true` if \\p that instance is indeed
915
+ * an instance of \\ref {interface_name}
916
+ */
917
+ bool {function_name}(
918
+ {I}const IClass& that
919
+ );"""
920
+ )
921
+
922
+
923
+ # fmt: off
924
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
925
+ @ensure(
926
+ lambda result:
927
+ not (result[0] is not None) or result[0].endswith('\n'),
928
+ "Trailing newline mandatory for valid end-of-files"
929
+ )
930
+ # fmt: on
931
+ def generate_header(
932
+ symbol_table: VerifiedIntermediateSymbolTable,
933
+ spec_impls: specific_implementations.SpecificImplementations,
934
+ library_namespace: Stripped,
935
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
936
+ """Generate the C++ header code of the structures based on the symbol table."""
937
+ namespace = Stripped(f"{library_namespace}::{cpp_common.TYPES_NAMESPACE}")
938
+
939
+ include_guard_var = cpp_common.include_guard_var(namespace)
940
+
941
+ include_prefix_path = cpp_common.generate_include_prefix_path(library_namespace)
942
+
943
+ blocks = [
944
+ Stripped(
945
+ f"""\
946
+ #ifndef {include_guard_var}
947
+ #define {include_guard_var}"""
948
+ ),
949
+ cpp_common.WARNING,
950
+ Stripped(
951
+ f"""\
952
+ #include "{include_prefix_path}/common.hpp"
953
+
954
+ #pragma warning(push, 0)
955
+ #include <cstddef>
956
+ #include <cstdint>
957
+ #include <memory>
958
+ #include <string>
959
+ #include <vector>
960
+ #pragma warning(pop)"""
961
+ ),
962
+ cpp_common.generate_namespace_opening(library_namespace),
963
+ Stripped(
964
+ f"""\
965
+ /**
966
+ * \\defgroup types Define data structures corresponding to the meta-model.
967
+ * @{{
968
+ */
969
+ namespace {cpp_common.TYPES_NAMESPACE} {{"""
970
+ ),
971
+ ] # type: List[Stripped]
972
+
973
+ errors = [] # type: List[Error]
974
+
975
+ blocks.append(Stripped("// region Enumerations"))
976
+
977
+ blocks.append(_generate_model_type_definition(symbol_table=symbol_table))
978
+
979
+ for enum in symbol_table.enumerations:
980
+ block, error = _generate_enum(enum=enum)
981
+ if error is not None:
982
+ errors.append(error)
983
+ else:
984
+ assert block is not None
985
+ blocks.append(block)
986
+
987
+ blocks.append(Stripped("// endregion Enumerations"))
988
+
989
+ blocks.append(Stripped("// region Forward declaration of interfaces"))
990
+
991
+ blocks.append(Stripped("// endregion Forward declaration of interfaces"))
992
+
993
+ for cls in symbol_table.classes:
994
+ interface_name = cpp_naming.interface_name(cls.name)
995
+ blocks.append(Stripped(f"class {interface_name};"))
996
+
997
+ blocks.append(Stripped("// region Class interfaces"))
998
+
999
+ model_type_getter = cpp_naming.getter_name(Identifier("model_type"))
1000
+ model_type_enum = cpp_naming.enum_name(Identifier("Model_type"))
1001
+
1002
+ blocks.append(
1003
+ Stripped(
1004
+ f"""\
1005
+ /**
1006
+ * Model the most general instance of the model.
1007
+ */
1008
+ class IClass {{
1009
+ public:
1010
+ {I}/**
1011
+ {I} * Indicate the runtime model type.
1012
+ {I} */
1013
+ {I}virtual {model_type_enum} {model_type_getter}() const = 0;
1014
+ {I}virtual ~IClass() = default;
1015
+ }};"""
1016
+ )
1017
+ )
1018
+
1019
+ for cls in symbol_table.classes:
1020
+ block, error = _generate_class_interface(cls=cls)
1021
+ if error is not None:
1022
+ errors.append(error)
1023
+ else:
1024
+ assert block is not None
1025
+ blocks.append(block)
1026
+
1027
+ blocks.append(Stripped("// endregion"))
1028
+
1029
+ blocks.append(Stripped("// region Definitions of concrete classes"))
1030
+
1031
+ for cls in symbol_table.concrete_classes:
1032
+ blocks.append(_generate_class_definition(cls=cls))
1033
+
1034
+ blocks.append(Stripped("// endregion"))
1035
+
1036
+ if len(errors) > 0:
1037
+ return None, errors
1038
+
1039
+ blocks.append(Stripped("// region Is-a functions"))
1040
+
1041
+ for cls in symbol_table.classes:
1042
+ blocks.append(_generate_is_cls_definition(cls=cls))
1043
+
1044
+ blocks.append(Stripped("// endregion Is-a functions"))
1045
+
1046
+ blocks.extend(
1047
+ [
1048
+ Stripped(
1049
+ f"""\
1050
+ }} // namespace {cpp_common.TYPES_NAMESPACE}
1051
+ /**@}}*/"""
1052
+ ),
1053
+ cpp_common.generate_namespace_closing(library_namespace),
1054
+ cpp_common.WARNING,
1055
+ Stripped(f"#endif // {include_guard_var}"),
1056
+ ]
1057
+ )
1058
+
1059
+ out = io.StringIO()
1060
+ for i, block in enumerate(blocks):
1061
+ if i > 0:
1062
+ out.write("\n\n")
1063
+
1064
+ out.write(block)
1065
+
1066
+ out.write("\n")
1067
+
1068
+ return out.getvalue(), None
1069
+
1070
+
1071
+ def _generate_constructor_implementation(cls: intermediate.ConcreteClass) -> Stripped:
1072
+ """Transpile the constructor implementation for the given ``cls``."""
1073
+ assert all(
1074
+ isinstance(stmt, intermediate_construction.AssignArgument)
1075
+ for stmt in cls.constructor.inlined_statements
1076
+ ), (
1077
+ f"We expect only assigns in the inlined constructors, "
1078
+ f"but got for class {cls.name!r}: {cls.constructor.inlined_statements}"
1079
+ )
1080
+
1081
+ body_statements = [] # type: List[Stripped]
1082
+
1083
+ for stmt in cls.constructor.inlined_statements:
1084
+ assert isinstance(stmt, intermediate_construction.AssignArgument), (
1085
+ f"Only assigns expected in inlined constructors, but got the following "
1086
+ f"statement for the class {cls.name!r}: {stmt}"
1087
+ )
1088
+
1089
+ prop_member = cpp_naming.private_property_name(stmt.name)
1090
+ arg_name = cpp_naming.argument_name(stmt.argument)
1091
+
1092
+ if stmt.default is not None:
1093
+ if isinstance(stmt.default, intermediate_construction.EmptyList):
1094
+ body_statements.append(
1095
+ Stripped(
1096
+ f"""\
1097
+ if ({arg_name}.has_value()) {{
1098
+ {I}{prop_member} = *{arg_name};
1099
+ }} else {{
1100
+ {I}{prop_member}.emplace();
1101
+ }}"""
1102
+ )
1103
+ )
1104
+ elif isinstance(stmt.default, intermediate_construction.DefaultEnumLiteral):
1105
+ enum_name = cpp_naming.enum_name(stmt.default.enum.name)
1106
+ literal_name = cpp_naming.enum_literal_name(stmt.default.literal.name)
1107
+
1108
+ body_statements.append(
1109
+ Stripped(
1110
+ f"""\
1111
+ {prop_member} = ({arg_name}.has_value())
1112
+ {I}? *{arg_name}
1113
+ {I}: {enum_name}::{literal_name};"""
1114
+ )
1115
+ )
1116
+ else:
1117
+ assert_never(stmt.default)
1118
+
1119
+ else:
1120
+ prop = cls.properties_by_name[stmt.name]
1121
+ if cpp_common.is_referencable(prop.type_annotation):
1122
+ body_statements.append(
1123
+ Stripped(f"{prop_member} = std::move({arg_name});")
1124
+ )
1125
+ else:
1126
+ body_statements.append(Stripped(f"{prop_member} = {arg_name};"))
1127
+
1128
+ body = (
1129
+ "\n\n".join(body_statements)
1130
+ if len(body_statements) > 0
1131
+ else "// Intentionally empty."
1132
+ )
1133
+
1134
+ cls_name = cpp_naming.class_name(cls.name)
1135
+
1136
+ if len(cls.constructor.arguments) == 0:
1137
+ return Stripped(
1138
+ f"""\
1139
+ {cls_name}::{cls_name}() {{
1140
+ {I}{indent_but_first_line(body, I)}
1141
+ }}"""
1142
+ )
1143
+
1144
+ constructor_argument_specs = [] # type: List[str]
1145
+ for arg in cls.constructor.arguments:
1146
+ arg_type = cpp_common.generate_type(arg.type_annotation)
1147
+ arg_name = cpp_naming.argument_name(arg.name)
1148
+
1149
+ constructor_argument_specs.append(f"{arg_type} {arg_name}")
1150
+
1151
+ constructor_arguments_specs_joined = ",\n".join(constructor_argument_specs)
1152
+
1153
+ return Stripped(
1154
+ f"""\
1155
+ {cls_name}::{cls_name}(
1156
+ {I}{indent_but_first_line(constructor_arguments_specs_joined, I)}
1157
+ ) {{
1158
+ {I}{indent_but_first_line(body, I)}
1159
+ }}"""
1160
+ )
1161
+
1162
+
1163
+ def _generate_model_type_getter_implementation(
1164
+ cls: intermediate.ConcreteClass,
1165
+ ) -> Stripped:
1166
+ """Implement the getter for the runtime model type."""
1167
+ enum_name = cpp_naming.enum_name(Identifier("Model_type"))
1168
+ literal_name = cpp_naming.enum_literal_name(cls.name)
1169
+
1170
+ cls_name = cpp_naming.class_name(cls.name)
1171
+ getter_name = cpp_naming.getter_name(Identifier("model_type"))
1172
+
1173
+ return Stripped(
1174
+ f"""\
1175
+ {enum_name} {cls_name}::{getter_name}() const {{
1176
+ {I}return {enum_name}::{literal_name};
1177
+ }}"""
1178
+ )
1179
+
1180
+
1181
+ @require(lambda prop, cls: id(prop) in cls.property_id_set)
1182
+ def _generate_getters_and_setter(
1183
+ prop: intermediate.Property, cls: intermediate.ConcreteClass
1184
+ ) -> List[Stripped]:
1185
+ """Generate the immutable and mutable getter and the setter."""
1186
+ cls_name = cpp_naming.class_name(cls.name)
1187
+ member_name = cpp_naming.private_property_name(prop.name)
1188
+
1189
+ blocks = [] # type: List[Stripped]
1190
+
1191
+ # region Getter
1192
+ getter_name = cpp_naming.getter_name(prop.name)
1193
+ getter_type = cpp_common.generate_type_with_const_ref_if_applicable(
1194
+ prop.type_annotation
1195
+ )
1196
+
1197
+ blocks.append(
1198
+ Stripped(
1199
+ f"""\
1200
+ {getter_type} {cls_name}::{getter_name}() const {{
1201
+ {I}return {member_name};
1202
+ }}"""
1203
+ )
1204
+ )
1205
+ # endregion
1206
+
1207
+ # region Mutable getter
1208
+ mutable_getter_name = cpp_naming.mutable_getter_name(prop.name)
1209
+ mutable_getter_type = cpp_common.generate_type_with_ref(prop.type_annotation)
1210
+
1211
+ blocks.append(
1212
+ Stripped(
1213
+ f"""\
1214
+ {mutable_getter_type} {cls_name}::{mutable_getter_name}() {{
1215
+ {I}return {member_name};
1216
+ }}"""
1217
+ )
1218
+ )
1219
+ # endregion
1220
+
1221
+ # region Setter
1222
+ setter_name = cpp_naming.setter_name(prop.name)
1223
+ value_type = cpp_common.generate_type(type_annotation=prop.type_annotation)
1224
+
1225
+ blocks.append(
1226
+ Stripped(
1227
+ f"""\
1228
+ void {cls_name}::{setter_name}(
1229
+ {I}{indent_but_first_line(value_type, I)} value
1230
+ ) {{
1231
+ {I}{member_name} = value;
1232
+ }}"""
1233
+ )
1234
+ )
1235
+ # endregion
1236
+
1237
+ return blocks
1238
+
1239
+
1240
+ @require(lambda method, cls: id(method) in cls.method_id_set)
1241
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1242
+ def _generate_method_implementation(
1243
+ method: intermediate.MethodUnion,
1244
+ cls: intermediate.ConcreteClass,
1245
+ spec_impls: specific_implementations.SpecificImplementations,
1246
+ ) -> Tuple[Optional[Stripped], Optional[Error]]:
1247
+ """Generate the implementation of the method."""
1248
+ body: Optional[Stripped]
1249
+
1250
+ if isinstance(method, intermediate.ImplementationSpecificMethod):
1251
+ implementation_key = specific_implementations.ImplementationKey(
1252
+ f"types/{method.specified_for.name}/{method.name}.body.cpp"
1253
+ )
1254
+
1255
+ body = spec_impls.get(implementation_key, None)
1256
+
1257
+ if body is None:
1258
+ return None, Error(
1259
+ method.parsed.node,
1260
+ f"The implementation is missing for "
1261
+ f"the implementation-specific method: {implementation_key}",
1262
+ )
1263
+
1264
+ elif isinstance(method, intermediate.UnderstoodMethod):
1265
+ return None, Error(
1266
+ cls.parsed.node,
1267
+ "At the moment (2023-09-22), we do not transpile the method body and "
1268
+ "its contracts, as it is quite a difficult task. Please contact "
1269
+ "the developers if you need this feature.",
1270
+ )
1271
+ else:
1272
+ assert_never(method)
1273
+
1274
+ assert body is not None
1275
+
1276
+ returns = (
1277
+ cpp_common.generate_type(method.returns) if method.returns is not None else None
1278
+ )
1279
+
1280
+ return_type = "void" if returns is None else returns
1281
+
1282
+ arg_types_names = [
1283
+ (
1284
+ cpp_common.generate_type_with_const_ref_if_applicable(arg.type_annotation),
1285
+ cpp_naming.argument_name(arg.name),
1286
+ )
1287
+ for arg in method.arguments
1288
+ ]
1289
+
1290
+ method_name = cpp_naming.method_name(method.name)
1291
+
1292
+ const_suffix = " const" if method.non_mutating else ""
1293
+
1294
+ cls_name = cpp_naming.class_name(cls.name)
1295
+
1296
+ if len(method.arguments) == 0:
1297
+ return (
1298
+ Stripped(
1299
+ f"""\
1300
+ {return_type} {cls_name}::{method_name}(){const_suffix} {{
1301
+ {I}{indent_but_first_line(body, I)}
1302
+ }}"""
1303
+ ),
1304
+ None,
1305
+ )
1306
+ else:
1307
+ arguments_definition = ",\n".join(
1308
+ f"{arg_type} {arg_name}" for arg_type, arg_name in arg_types_names
1309
+ )
1310
+
1311
+ return (
1312
+ Stripped(
1313
+ f"""\
1314
+ {return_type} {cls_name}::{method_name}(
1315
+ {I}{indent_but_first_line(arguments_definition, I)}
1316
+ ){const_suffix} {{
1317
+ {I}{indent_but_first_line(body, I)}
1318
+ }}"""
1319
+ ),
1320
+ None,
1321
+ )
1322
+
1323
+
1324
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1325
+ def _generate_class_implementation(
1326
+ cls: intermediate.ConcreteClass,
1327
+ spec_impls: specific_implementations.SpecificImplementations,
1328
+ ) -> Tuple[Optional[List[Stripped]], Optional[Error]]:
1329
+ """Generate the implementation blocks for the given class."""
1330
+ blocks = [
1331
+ _generate_constructor_implementation(cls=cls),
1332
+ _generate_model_type_getter_implementation(cls=cls),
1333
+ ] # type: List[Stripped]
1334
+
1335
+ for prop in cls.properties:
1336
+ blocks.extend(_generate_getters_and_setter(prop=prop, cls=cls))
1337
+
1338
+ errors = [] # type: List[Error]
1339
+
1340
+ for method in cls.methods:
1341
+ code, error = _generate_method_implementation(
1342
+ method=method, cls=cls, spec_impls=spec_impls
1343
+ )
1344
+ if error is not None:
1345
+ errors.append(
1346
+ Error(
1347
+ method.parsed.node,
1348
+ f"Failed to generate the implementation "
1349
+ f"for the method {method.name!r}",
1350
+ [error],
1351
+ )
1352
+ )
1353
+ else:
1354
+ assert code is not None
1355
+ blocks.append(code)
1356
+
1357
+ if len(errors) > 0:
1358
+ return None, Error(
1359
+ cls.parsed.node,
1360
+ f"Failed to generate the implementation for the class {cls.name!r}",
1361
+ errors,
1362
+ )
1363
+
1364
+ return blocks, None
1365
+
1366
+
1367
+ def _generate_is_cls_implementation(
1368
+ cls: intermediate.ClassUnion, symbol_table: intermediate.SymbolTable
1369
+ ) -> Stripped:
1370
+ """Generate the impl. of the function to check is-a based on model type."""
1371
+ function_name = cpp_naming.function_name(Identifier(f"is_{cls.name}"))
1372
+
1373
+ case_blocks = [] # type: List[Stripped]
1374
+ for concrete_cls in symbol_table.concrete_classes:
1375
+ case_body = (
1376
+ "return true;" if concrete_cls.is_subclass_of(cls) else "return false;"
1377
+ )
1378
+
1379
+ model_type_literal = cpp_naming.enum_literal_name(concrete_cls.name)
1380
+
1381
+ case_blocks.append(
1382
+ Stripped(
1383
+ f"""\
1384
+ case ModelType::{model_type_literal}:
1385
+ {I}{indent_but_first_line(case_body, I)}"""
1386
+ )
1387
+ )
1388
+
1389
+ case_blocks.append(
1390
+ Stripped(
1391
+ f"""\
1392
+ default:
1393
+ {I}throw std::invalid_argument(
1394
+ {II}common::Concat(
1395
+ {III}"Unexpected model type: ",
1396
+ {III}std::to_string(
1397
+ {IIII}static_cast<std::uint32_t>(that.model_type())
1398
+ {III})
1399
+ {II})
1400
+ {I});"""
1401
+ )
1402
+ )
1403
+
1404
+ case_blocks_joined = "\n".join(case_blocks)
1405
+
1406
+ return Stripped(
1407
+ f"""\
1408
+ bool {function_name}(
1409
+ {I}const IClass& that
1410
+ ) {{
1411
+ {I}switch (that.model_type()) {{
1412
+ {II}{indent_but_first_line(case_blocks_joined, II)}
1413
+ {I}}}
1414
+ }}"""
1415
+ )
1416
+
1417
+
1418
+ # fmt: off
1419
+ @ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
1420
+ @ensure(
1421
+ lambda result:
1422
+ not (result[0] is not None) or result[0].endswith('\n'),
1423
+ "Trailing newline mandatory for valid end-of-files"
1424
+ )
1425
+ # fmt: on
1426
+ def generate_implementation(
1427
+ symbol_table: intermediate.SymbolTable,
1428
+ spec_impls: specific_implementations.SpecificImplementations,
1429
+ library_namespace: Stripped,
1430
+ ) -> Tuple[Optional[str], Optional[List[Error]]]:
1431
+ """Generate the C++ implementation code for data structure."""
1432
+ namespace = Stripped(f"{library_namespace}::types")
1433
+
1434
+ include_prefix_path = cpp_common.generate_include_prefix_path(library_namespace)
1435
+
1436
+ blocks = [
1437
+ cpp_common.WARNING,
1438
+ Stripped(
1439
+ f'''\
1440
+ #include "{include_prefix_path}/types.hpp"'''
1441
+ ),
1442
+ cpp_common.generate_namespace_opening(namespace),
1443
+ ] # type: List[Stripped]
1444
+
1445
+ errors = [] # type: List[Error]
1446
+
1447
+ for concrete_cls in symbol_table.concrete_classes:
1448
+ if concrete_cls.is_implementation_specific:
1449
+ errors.append(
1450
+ Error(
1451
+ concrete_cls.parsed.node,
1452
+ f"We currently do not support implementation-specific classes "
1453
+ f"in the C++ generator, but the class {concrete_cls.name!r} has "
1454
+ f"been marked as implementation-specific. If you need "
1455
+ f"this feature, please contact the developers.",
1456
+ )
1457
+ )
1458
+ continue
1459
+
1460
+ cls_blocks, error = _generate_class_implementation(
1461
+ cls=concrete_cls, spec_impls=spec_impls
1462
+ )
1463
+ if error is not None:
1464
+ errors.append(error)
1465
+ else:
1466
+ assert cls_blocks is not None
1467
+ cls_name = cpp_naming.class_name(concrete_cls.name)
1468
+ blocks.append(Stripped(f"// region {cls_name}"))
1469
+ blocks.extend(cls_blocks)
1470
+ blocks.append(Stripped(f"// endregion {cls_name}"))
1471
+
1472
+ if len(errors) > 0:
1473
+ return None, errors
1474
+
1475
+ blocks.append(Stripped("// region Is-a functions"))
1476
+
1477
+ for cls in symbol_table.classes:
1478
+ blocks.append(
1479
+ _generate_is_cls_implementation(cls=cls, symbol_table=symbol_table)
1480
+ )
1481
+
1482
+ blocks.append(Stripped("// endregion Is-a functions"))
1483
+
1484
+ blocks.extend(
1485
+ [
1486
+ cpp_common.generate_namespace_closing(namespace),
1487
+ cpp_common.WARNING,
1488
+ ]
1489
+ )
1490
+
1491
+ writer = io.StringIO()
1492
+ for i, block in enumerate(blocks):
1493
+ if i > 0:
1494
+ writer.write("\n\n")
1495
+
1496
+ writer.write(block)
1497
+
1498
+ writer.write("\n")
1499
+
1500
+ return writer.getvalue(), None
1501
+
1502
+
1503
+ # endregion