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.
- aas_core_codegen/__init__.py +6 -0
- aas_core_codegen/__main__.py +8 -0
- aas_core_codegen/common.py +500 -0
- aas_core_codegen/cpp/__init__.py +1 -0
- aas_core_codegen/cpp/aas_common/__init__.py +6 -0
- aas_core_codegen/cpp/aas_common/_generate.py +713 -0
- aas_core_codegen/cpp/common.py +681 -0
- aas_core_codegen/cpp/constants/__init__.py +6 -0
- aas_core_codegen/cpp/constants/_generate.py +568 -0
- aas_core_codegen/cpp/description.py +654 -0
- aas_core_codegen/cpp/enhancing/__init__.py +4 -0
- aas_core_codegen/cpp/enhancing/_generate.py +993 -0
- aas_core_codegen/cpp/iteration/__init__.py +6 -0
- aas_core_codegen/cpp/iteration/_generate.py +2332 -0
- aas_core_codegen/cpp/jsonization/__init__.py +6 -0
- aas_core_codegen/cpp/jsonization/_generate.py +2619 -0
- aas_core_codegen/cpp/main.py +694 -0
- aas_core_codegen/cpp/naming.py +170 -0
- aas_core_codegen/cpp/optionaling.py +557 -0
- aas_core_codegen/cpp/pattern/__init__.py +6 -0
- aas_core_codegen/cpp/pattern/_generate.py +508 -0
- aas_core_codegen/cpp/revm/__init__.py +6 -0
- aas_core_codegen/cpp/revm/_generate.py +1149 -0
- aas_core_codegen/cpp/stringification/__init__.py +5 -0
- aas_core_codegen/cpp/stringification/_generate.py +955 -0
- aas_core_codegen/cpp/structure/__init__.py +7 -0
- aas_core_codegen/cpp/structure/_generate.py +1503 -0
- aas_core_codegen/cpp/transpilation.py +1383 -0
- aas_core_codegen/cpp/unrolling.py +159 -0
- aas_core_codegen/cpp/verification/__init__.py +6 -0
- aas_core_codegen/cpp/verification/_generate.py +3073 -0
- aas_core_codegen/cpp/visitation/__init__.py +6 -0
- aas_core_codegen/cpp/visitation/_generate.py +521 -0
- aas_core_codegen/cpp/wstringification/__init__.py +5 -0
- aas_core_codegen/cpp/wstringification/_generate.py +586 -0
- aas_core_codegen/cpp/xmlization/__init__.py +6 -0
- aas_core_codegen/cpp/xmlization/_generate.py +5373 -0
- aas_core_codegen/cpp/yielding.py +201 -0
- aas_core_codegen/csharp/__init__.py +1 -0
- aas_core_codegen/csharp/common.py +224 -0
- aas_core_codegen/csharp/constants/__init__.py +5 -0
- aas_core_codegen/csharp/constants/_generate.py +409 -0
- aas_core_codegen/csharp/copying/__init__.py +4 -0
- aas_core_codegen/csharp/copying/_generate.py +498 -0
- aas_core_codegen/csharp/description.py +1103 -0
- aas_core_codegen/csharp/enhancing/__init__.py +4 -0
- aas_core_codegen/csharp/enhancing/_generate.py +667 -0
- aas_core_codegen/csharp/jsonization/__init__.py +4 -0
- aas_core_codegen/csharp/jsonization/_generate.py +1630 -0
- aas_core_codegen/csharp/main.py +421 -0
- aas_core_codegen/csharp/naming.py +157 -0
- aas_core_codegen/csharp/reporting/__init__.py +4 -0
- aas_core_codegen/csharp/reporting/_generate.py +266 -0
- aas_core_codegen/csharp/stringification/__init__.py +4 -0
- aas_core_codegen/csharp/stringification/_generate.py +243 -0
- aas_core_codegen/csharp/structure/__init__.py +6 -0
- aas_core_codegen/csharp/structure/_generate.py +1341 -0
- aas_core_codegen/csharp/transpilation.py +990 -0
- aas_core_codegen/csharp/unrolling.py +211 -0
- aas_core_codegen/csharp/verification/__init__.py +6 -0
- aas_core_codegen/csharp/verification/_generate.py +1457 -0
- aas_core_codegen/csharp/visitation/__init__.py +5 -0
- aas_core_codegen/csharp/visitation/_generate.py +579 -0
- aas_core_codegen/csharp/xmlization/__init__.py +4 -0
- aas_core_codegen/csharp/xmlization/_generate.py +1980 -0
- aas_core_codegen/golang/__init__.py +1 -0
- aas_core_codegen/golang/aas_common/__init__.py +4 -0
- aas_core_codegen/golang/aas_common/_generate.py +152 -0
- aas_core_codegen/golang/common.py +303 -0
- aas_core_codegen/golang/constants/__init__.py +5 -0
- aas_core_codegen/golang/constants/_generate.py +339 -0
- aas_core_codegen/golang/description.py +501 -0
- aas_core_codegen/golang/enhancing/__init__.py +4 -0
- aas_core_codegen/golang/enhancing/_generate.py +527 -0
- aas_core_codegen/golang/jsonization/__init__.py +4 -0
- aas_core_codegen/golang/jsonization/_generate.py +1740 -0
- aas_core_codegen/golang/main.py +368 -0
- aas_core_codegen/golang/naming.py +412 -0
- aas_core_codegen/golang/pointering.py +631 -0
- aas_core_codegen/golang/reporting/__init__.py +4 -0
- aas_core_codegen/golang/reporting/_generate.py +218 -0
- aas_core_codegen/golang/stringification/__init__.py +4 -0
- aas_core_codegen/golang/stringification/_generate.py +394 -0
- aas_core_codegen/golang/structure/__init__.py +6 -0
- aas_core_codegen/golang/structure/_generate.py +1493 -0
- aas_core_codegen/golang/transpilation.py +1191 -0
- aas_core_codegen/golang/unrolling.py +159 -0
- aas_core_codegen/golang/verification/__init__.py +6 -0
- aas_core_codegen/golang/verification/_generate.py +1513 -0
- aas_core_codegen/golang/xmlization/__init__.py +4 -0
- aas_core_codegen/golang/xmlization/_generate.py +2507 -0
- aas_core_codegen/infer_for_schema/__init__.py +21 -0
- aas_core_codegen/infer_for_schema/_inline.py +693 -0
- aas_core_codegen/infer_for_schema/_len.py +527 -0
- aas_core_codegen/infer_for_schema/_pattern.py +311 -0
- aas_core_codegen/infer_for_schema/_set.py +394 -0
- aas_core_codegen/infer_for_schema/_stringify.py +201 -0
- aas_core_codegen/infer_for_schema/_types.py +135 -0
- aas_core_codegen/infer_for_schema/match.py +122 -0
- aas_core_codegen/intermediate/__init__.py +78 -0
- aas_core_codegen/intermediate/_hierarchy.py +397 -0
- aas_core_codegen/intermediate/_stringify.py +989 -0
- aas_core_codegen/intermediate/_translate.py +5128 -0
- aas_core_codegen/intermediate/_types.py +2901 -0
- aas_core_codegen/intermediate/construction.py +750 -0
- aas_core_codegen/intermediate/doc.py +344 -0
- aas_core_codegen/intermediate/pattern_verification.py +428 -0
- aas_core_codegen/intermediate/revm.py +985 -0
- aas_core_codegen/intermediate/type_inference.py +2266 -0
- aas_core_codegen/java/__init__.py +1 -0
- aas_core_codegen/java/common.py +197 -0
- aas_core_codegen/java/constants/__init__.py +5 -0
- aas_core_codegen/java/constants/_generate.py +334 -0
- aas_core_codegen/java/copying/__init__.py +4 -0
- aas_core_codegen/java/copying/_generate.py +502 -0
- aas_core_codegen/java/description.py +774 -0
- aas_core_codegen/java/enhancing/__init__.py +4 -0
- aas_core_codegen/java/enhancing/_generate.py +820 -0
- aas_core_codegen/java/generation/__init__.py +5 -0
- aas_core_codegen/java/generation/_generate.py +285 -0
- aas_core_codegen/java/jsonization/__init__.py +4 -0
- aas_core_codegen/java/jsonization/_generate.py +1472 -0
- aas_core_codegen/java/main.py +438 -0
- aas_core_codegen/java/naming.py +187 -0
- aas_core_codegen/java/optional.py +514 -0
- aas_core_codegen/java/reporting/__init__.py +4 -0
- aas_core_codegen/java/reporting/_generate.py +248 -0
- aas_core_codegen/java/stringification/__init__.py +4 -0
- aas_core_codegen/java/stringification/_generate.py +212 -0
- aas_core_codegen/java/structure/__init__.py +6 -0
- aas_core_codegen/java/structure/_generate.py +1767 -0
- aas_core_codegen/java/transpilation.py +1111 -0
- aas_core_codegen/java/verification/__init__.py +6 -0
- aas_core_codegen/java/verification/_generate.py +1536 -0
- aas_core_codegen/java/visitation/__init__.py +5 -0
- aas_core_codegen/java/visitation/_generate.py +689 -0
- aas_core_codegen/java/xmlization/__init__.py +4 -0
- aas_core_codegen/java/xmlization/_generate.py +2274 -0
- aas_core_codegen/jsonld/__init__.py +1 -0
- aas_core_codegen/jsonld/main.py +455 -0
- aas_core_codegen/jsonschema/__init__.py +1 -0
- aas_core_codegen/jsonschema/main.py +982 -0
- aas_core_codegen/main.py +245 -0
- aas_core_codegen/naming.py +133 -0
- aas_core_codegen/opcua/__init__.py +1 -0
- aas_core_codegen/opcua/main.py +1525 -0
- aas_core_codegen/opcua/naming.py +126 -0
- aas_core_codegen/parse/__init__.py +46 -0
- aas_core_codegen/parse/_rules.py +796 -0
- aas_core_codegen/parse/_stringify.py +532 -0
- aas_core_codegen/parse/_translate.py +3940 -0
- aas_core_codegen/parse/_types.py +973 -0
- aas_core_codegen/parse/retree/__init__.py +46 -0
- aas_core_codegen/parse/retree/_fix.py +434 -0
- aas_core_codegen/parse/retree/_parse.py +1143 -0
- aas_core_codegen/parse/retree/_render.py +298 -0
- aas_core_codegen/parse/retree/_stringify.py +199 -0
- aas_core_codegen/parse/retree/_types.py +362 -0
- aas_core_codegen/parse/retree/_visitor.py +70 -0
- aas_core_codegen/parse/tree.py +1303 -0
- aas_core_codegen/protobuf/__init__.py +1 -0
- aas_core_codegen/protobuf/common.py +225 -0
- aas_core_codegen/protobuf/description.py +1102 -0
- aas_core_codegen/protobuf/main.py +115 -0
- aas_core_codegen/protobuf/naming.py +143 -0
- aas_core_codegen/protobuf/structure/__init__.py +6 -0
- aas_core_codegen/protobuf/structure/_generate.py +502 -0
- aas_core_codegen/py.typed +1 -0
- aas_core_codegen/python/__init__.py +1 -0
- aas_core_codegen/python/aas_common/__init__.py +4 -0
- aas_core_codegen/python/aas_common/_generate.py +63 -0
- aas_core_codegen/python/common.py +406 -0
- aas_core_codegen/python/constants/__init__.py +5 -0
- aas_core_codegen/python/constants/_generate.py +377 -0
- aas_core_codegen/python/description.py +508 -0
- aas_core_codegen/python/jsonization/__init__.py +4 -0
- aas_core_codegen/python/jsonization/_generate.py +1391 -0
- aas_core_codegen/python/main.py +323 -0
- aas_core_codegen/python/naming.py +255 -0
- aas_core_codegen/python/stringification/__init__.py +4 -0
- aas_core_codegen/python/stringification/_generate.py +129 -0
- aas_core_codegen/python/structure/__init__.py +6 -0
- aas_core_codegen/python/structure/_generate.py +1801 -0
- aas_core_codegen/python/transpilation.py +958 -0
- aas_core_codegen/python/unrolling.py +156 -0
- aas_core_codegen/python/verification/__init__.py +6 -0
- aas_core_codegen/python/verification/_generate.py +1471 -0
- aas_core_codegen/python/xmlization/__init__.py +4 -0
- aas_core_codegen/python/xmlization/_generate.py +3003 -0
- aas_core_codegen/python_protobuf/__init__.py +1 -0
- aas_core_codegen/python_protobuf/main.py +1424 -0
- aas_core_codegen/python_protobuf/naming.py +85 -0
- aas_core_codegen/rdf_shacl/__init__.py +1 -0
- aas_core_codegen/rdf_shacl/_description.py +351 -0
- aas_core_codegen/rdf_shacl/common.py +206 -0
- aas_core_codegen/rdf_shacl/main.py +114 -0
- aas_core_codegen/rdf_shacl/naming.py +145 -0
- aas_core_codegen/rdf_shacl/rdf.py +435 -0
- aas_core_codegen/rdf_shacl/shacl.py +453 -0
- aas_core_codegen/run.py +124 -0
- aas_core_codegen/smoke/__init__.py +1 -0
- aas_core_codegen/smoke/main.py +219 -0
- aas_core_codegen/specific_implementations.py +72 -0
- aas_core_codegen/stringify.py +333 -0
- aas_core_codegen/typescript/__init__.py +1 -0
- aas_core_codegen/typescript/aas_common/__init__.py +4 -0
- aas_core_codegen/typescript/aas_common/_generate.py +472 -0
- aas_core_codegen/typescript/common.py +340 -0
- aas_core_codegen/typescript/constants/__init__.py +5 -0
- aas_core_codegen/typescript/constants/_generate.py +347 -0
- aas_core_codegen/typescript/description.py +530 -0
- aas_core_codegen/typescript/jsonization/__init__.py +4 -0
- aas_core_codegen/typescript/jsonization/_generate.py +1510 -0
- aas_core_codegen/typescript/main.py +258 -0
- aas_core_codegen/typescript/naming.py +189 -0
- aas_core_codegen/typescript/stringification/__init__.py +4 -0
- aas_core_codegen/typescript/stringification/_generate.py +367 -0
- aas_core_codegen/typescript/structure/__init__.py +6 -0
- aas_core_codegen/typescript/structure/_generate.py +2500 -0
- aas_core_codegen/typescript/transpilation.py +1051 -0
- aas_core_codegen/typescript/unrolling.py +159 -0
- aas_core_codegen/typescript/verification/__init__.py +6 -0
- aas_core_codegen/typescript/verification/_generate.py +1578 -0
- aas_core_codegen/xsd/__init__.py +1 -0
- aas_core_codegen/xsd/main.py +1187 -0
- aas_core_codegen/xsd/naming.py +83 -0
- aas_core_codegen/yielding/__init__.py +1 -0
- aas_core_codegen/yielding/flow.py +139 -0
- aas_core_codegen/yielding/linear.py +754 -0
- aas_core_codegen-0.0.16.dist-info/METADATA +211 -0
- aas_core_codegen-0.0.16.dist-info/RECORD +604 -0
- aas_core_codegen-0.0.16.dist-info/WHEEL +5 -0
- aas_core_codegen-0.0.16.dist-info/entry_points.txt +3 -0
- aas_core_codegen-0.0.16.dist-info/licenses/AUTHORS +9 -0
- aas_core_codegen-0.0.16.dist-info/licenses/LICENSE +23 -0
- aas_core_codegen-0.0.16.dist-info/top_level.txt +2 -0
- dev/continuous_integration/__init__.py +1 -0
- dev/continuous_integration/check_help_in_readme.py +208 -0
- dev/continuous_integration/check_init_and_pyproject_consistent.py +154 -0
- dev/continuous_integration/precommit.py +400 -0
- dev/dev_scripts/__init__.py +1 -0
- dev/dev_scripts/compare_rendered_regexes_against_source_py.py +42 -0
- dev/dev_scripts/copy_to_aas_core3_cpp.py +100 -0
- dev/dev_scripts/copy_to_aas_core3_java.py +90 -0
- dev/dev_scripts/download_latest_aas_core_meta_v3.py +114 -0
- dev/dev_scripts/draw_bipartite_graph_based_on_lines.py +37 -0
- dev/dev_scripts/run_tests_with_rerecord.py +69 -0
- dev/dev_scripts/update_to_aas_core_meta.py +174 -0
- dev/integration_tests/input/jsonschema/boilerplate/main.py +55 -0
- dev/integration_tests/input/meta_model.py +38 -0
- dev/integration_tests/input/python/boilerplate/main.py +153 -0
- dev/integration_tests/main.py +258 -0
- dev/test_data/csharp/test_structure/concrete_class_with_descendants/meta_model.py +15 -0
- dev/test_data/csharp/test_structure/constructor_without_arguments/all_properties_optional/meta_model.py +9 -0
- dev/test_data/csharp/test_structure/constructor_without_arguments/no_properties/meta_model.py +6 -0
- dev/test_data/csharp/test_verification/builtin_functions/len/on_list/meta_model.py +20 -0
- dev/test_data/csharp/test_verification/builtin_functions/len/on_str/meta_model.py +16 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_prefix/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/as_suffix/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_group_with_quantifier/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_the_middle/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/in_union/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/single_utf32_literal/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_within_group/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_as_literal/with_quantifier_without_group/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_beginning/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/at_the_end/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/in_the_middle/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/multiple/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/literal/single_with_quantifier/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/mixed_with_non_utf32/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/more_than_two_high_surrogates/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/multiple_utf32_ranges/meta_model.py +8 -0
- 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
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/same_high_surrogate_with_quantifier/meta_model.py +8 -0
- dev/test_data/csharp/test_verification/pattern_verification/utf32_in_character_set/range/two_high_surrogates/meta_model.py +8 -0
- dev/test_data/intermediate/expected/class/empty/meta_model.py +6 -0
- dev/test_data/intermediate/expected/class/implementation_specific_method/meta_model.py +8 -0
- dev/test_data/intermediate/expected/class/inheritance/meta_model.py +41 -0
- dev/test_data/intermediate/expected/class/methods_with_contracts/meta_model.py +15 -0
- dev/test_data/intermediate/expected/class/only_method_no_property/meta_model.py +7 -0
- dev/test_data/intermediate/expected/class/only_property_no_method/meta_model.py +9 -0
- dev/test_data/intermediate/expected/constant/constant_set/of_enum/meta_model.py +12 -0
- dev/test_data/intermediate/expected/constant/constant_set/of_str/meta_model.py +4 -0
- dev/test_data/intermediate/expected/constant/constant_set/with_description/meta_model.py +6 -0
- dev/test_data/intermediate/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
- dev/test_data/intermediate/expected/constant/constant_str/only_value/meta_model.py +7 -0
- dev/test_data/intermediate/expected/constant/constant_str/with_description/meta_model.py +5 -0
- dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_in_literal/meta_model.py +20 -0
- dev/test_data/intermediate/expected/documentation/docstring_with_special_characters_outside_literal/meta_model.py +20 -0
- dev/test_data/intermediate/expected/empty/meta_model.py +2 -0
- dev/test_data/intermediate/expected/enumeration/meta_model.py +9 -0
- dev/test_data/intermediate/expected/interface/basic/meta_model.py +14 -0
- dev/test_data/intermediate/expected/interface/empty/meta_model.py +7 -0
- dev/test_data/intermediate/expected/interface/inheritance/meta_model.py +27 -0
- dev/test_data/intermediate/expected/interface/method_signature/meta_model.py +10 -0
- dev/test_data/intermediate/expected/interface/only_constructor/meta_model.py +11 -0
- dev/test_data/intermediate/expected/method/non_mutating/implementation_specific/meta_model.py +12 -0
- dev/test_data/intermediate/expected/method/non_mutating/understood/meta_model.py +11 -0
- dev/test_data/intermediate/expected/type_annotation/atomic/meta_model.py +9 -0
- dev/test_data/intermediate/expected/type_annotation/subscripted/class/meta_model.py +13 -0
- dev/test_data/intermediate/expected/type_annotation/subscripted/primitive/meta_model.py +9 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/enumeration_literals_in_subset_outside_of_superset/meta_model.py +20 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/invalid_literal/meta_model.py +11 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_between_enumeration_and_literal/meta_model.py +30 -0
- dev/test_data/intermediate/unexpected/constant_set/of_enum/mismatch_in_enumerations_between_subset_and_superset/meta_model.py +21 -0
- dev/test_data/intermediate/unexpected/constant_set/of_str/literals_in_subset_outside_of_superset/meta_model.py +18 -0
- dev/test_data/intermediate/unexpected/constant_set/of_str/mismatch_between_type_annotation_and_literals/meta_model.py +10 -0
- dev/test_data/intermediate/unexpected/constant_set/of_str/superset_and_subset_mismatch_in_type/meta_model.py +12 -0
- dev/test_data/intermediate/unexpected/constraints/dangling_constraintref/meta_model.py +18 -0
- dev/test_data/intermediate/unexpected/constraints/duplicate_constraints/meta_model.py +20 -0
- dev/test_data/intermediate/unexpected/documentation/unexpected_documentation_elements/meta_model.py +34 -0
- dev/test_data/intermediate/unexpected/invariant/class_invariant_uses_re/meta_model.py +10 -0
- dev/test_data/intermediate/unexpected/invariant/invariant_of_constrained_primitive_uses_re/meta_model.py +7 -0
- dev/test_data/intermediate/unexpected/invariant/unexpected_argument_count_to_len/meta_model.py +20 -0
- dev/test_data/intermediate/unexpected/invariant/unhandled_built_in_function/meta_model.py +16 -0
- dev/test_data/intermediate/unexpected/method_definitions/non_constant_default/meta_model.py +7 -0
- dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/default_non_none/meta_model.py +16 -0
- dev/test_data/intermediate/unexpected/optional_constructor_arguments_wo_default/no_default/meta_model.py +16 -0
- dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/after_inheritance/meta_model.py +58 -0
- dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/type_missmatch/meta_model.py +9 -0
- dev/test_data/intermediate/unexpected/properties_and_constructor_arguments_do_not_match/within_class/meta_model.py +22 -0
- dev/test_data/jsonschema/test_main/regression_when_len_constraints_on_inherited_property/meta_model.py +28 -0
- dev/test_data/opcua/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
- dev/test_data/opcua/test_main/classes_with_invariants/meta_model.py +21 -0
- dev/test_data/opcua/test_main/concrete_class_with_descendant/meta_model.py +27 -0
- dev/test_data/opcua/test_main/concrete_class_with_enum/meta_model.py +21 -0
- dev/test_data/opcua/test_main/concrete_class_with_list_of_instances/meta_model.py +21 -0
- dev/test_data/opcua/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
- dev/test_data/opcua/test_main/concrete_class_with_string/meta_model.py +13 -0
- dev/test_data/opcua/test_main/constrained_primitive/meta_model.py +20 -0
- dev/test_data/opcua/test_main/multiple_inheritance/meta_model.py +25 -0
- dev/test_data/parse/expected/constant/constant_set/of_enum/meta_model.py +12 -0
- dev/test_data/parse/expected/constant/constant_set/of_str/meta_model.py +4 -0
- dev/test_data/parse/expected/constant/constant_set/with_description/meta_model.py +6 -0
- dev/test_data/parse/expected/constant/constant_set/with_superset_of/meta_model.py +14 -0
- dev/test_data/parse/expected/constant/constant_str/only_value/meta_model.py +7 -0
- dev/test_data/parse/expected/constant/constant_str/with_description/meta_model.py +5 -0
- dev/test_data/parse/expected/enum/ok/meta_model.py +15 -0
- dev/test_data/parse/expected/implementation_specific_class/properties_and_methods_in_implementation_specific_class/meta_model.py +17 -0
- dev/test_data/parse/expected/inheritance/basic/meta_model.py +11 -0
- dev/test_data/parse/expected/inheritance/diamond/meta_model.py +26 -0
- dev/test_data/parse/expected/inheritance/inheritance_from_concrete_class/meta_model.py +10 -0
- dev/test_data/parse/expected/invariants/in_relation/meta_model.py +16 -0
- dev/test_data/parse/expected/method/arguments/meta_model.py +7 -0
- dev/test_data/parse/expected/method/basic/meta_model.py +7 -0
- dev/test_data/parse/expected/method/contracts/condition_as_keyword_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/condition_as_positional_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/description_as_keyword_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/description_as_positional_argument/meta_model.py +8 -0
- dev/test_data/parse/expected/method/contracts/multiple_contracts_in_order/meta_model.py +17 -0
- dev/test_data/parse/expected/method/contracts/postcondition/basic/meta_model.py +10 -0
- dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_keyword_arguments/meta_model.py +9 -0
- dev/test_data/parse/expected/method/contracts/postcondition/snapshot/with_positional_arguments/meta_model.py +9 -0
- dev/test_data/parse/expected/method/default/meta_model.py +9 -0
- dev/test_data/parse/expected/method/description/meta_model.py +8 -0
- dev/test_data/parse/expected/method/is_implementation_specific/meta_model.py +8 -0
- dev/test_data/parse/expected/method/non_mutating/meta_model.py +11 -0
- dev/test_data/parse/expected/method/returns_none/meta_model.py +7 -0
- dev/test_data/parse/expected/method/returns_something/meta_model.py +7 -0
- dev/test_data/parse/expected/single_class/description/meta_model.py +12 -0
- dev/test_data/parse/expected/single_class/empty/meta_model.py +6 -0
- dev/test_data/parse/expected/single_class/property/description/meta_model.py +14 -0
- dev/test_data/parse/expected/single_class/property/mandatory/meta_model.py +6 -0
- dev/test_data/parse/expected/single_class/property/optional/meta_model.py +6 -0
- dev/test_data/parse/expected/single_class/property/recursion_to_entity/meta_model.py +6 -0
- dev/test_data/parse/unexpected/class_decorators/non_name_decorator/meta_model.py +7 -0
- dev/test_data/parse/unexpected/class_decorators/unknown_decorator/meta_model.py +7 -0
- dev/test_data/parse/unexpected/class_definitions/is_abstract_and_implementation_specific/meta_model.py +8 -0
- dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_before_a_method/meta_model.py +11 -0
- dev/test_data/parse/unexpected/class_definitions/unexpected_docstring_for_a_pass/meta_model.py +9 -0
- dev/test_data/parse/unexpected/class_definitions/unexpected_double_description_for_a_property/meta_model.py +10 -0
- dev/test_data/parse/unexpected/class_inheritances/inheriting_from_implementation_specific_parent/meta_model.py +20 -0
- dev/test_data/parse/unexpected/class_inheritances/non_name_super_class/meta_model.py +6 -0
- dev/test_data/parse/unexpected/enum/expression_as_assignment_value/meta_model.py +6 -0
- dev/test_data/parse/unexpected/enum/non_assignment/meta_model.py +8 -0
- dev/test_data/parse/unexpected/enum/non_string_literal/meta_model.py +6 -0
- dev/test_data/parse/unexpected/enum/unexpected_inheritance/meta_model.py +6 -0
- dev/test_data/parse/unexpected/method_contracts/contract/non_lambda_condition/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/contract/non_string_literal_description/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/contract/without_any_arguments/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/contract/without_condition/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/postcondition/OLD_in_postcondition_without_snapshot/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/postcondition/argument_missing_in_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/precondition/argument_missing_in_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/argument_missing_in_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/capture_not_a_lambda/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/invalid_name/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/name_not_a_string_literal/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_capture/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_contracts/snapshot/without_a_name/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_constructor/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/non_mutating/non_mutating_verification_function/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/non_name_decorator/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/unknown_call_decorator/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_decorators/unknown_name_decorator/meta_model.py +8 -0
- dev/test_data/parse/unexpected/method_definitions/argument_with_final/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/argument_without_a_type_annotation/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/default_for_self/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/dunder/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/init_with_return_type/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_keyword_only_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_positional_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_type_annotation_for_self/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_variable_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/with_variable_keyword_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/without_arguments/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/without_self/meta_model.py +7 -0
- dev/test_data/parse/unexpected/method_definitions/without_type_annotation_for_result/meta_model.py +7 -0
- dev/test_data/parse/unexpected/property_definitions/final_without_subscript/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/nested_final/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/non_simple/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/unexpected_assignment/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/unexpected_non_name_property/meta_model.py +6 -0
- dev/test_data/parse/unexpected/property_definitions/without_type_annotation/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/constant_set_with_a_non_set_subset/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_inheritance/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_a_property/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_an_argument/meta_model.py +7 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_reference_in_type_annotation_of_constant_set/meta_model.py +6 -0
- dev/test_data/parse/unexpected/symbol_table/dangling_subset_in_constant_set/meta_model.py +4 -0
- dev/test_data/parse/unexpected/symbol_table/inheritance_from_non_class/meta_model.py +10 -0
- dev/test_data/parse_retree/expected/character_set/common_escaping/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/complementing/double_caret/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/complementing/multiple_ranges/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/complementing/suffix_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/escape_first_caret/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/literals_which_need_no_escaping_in_characters_set_but_need_escaping_outside/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/multiple_ranges/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/single_literal/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/single_range/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/unescaped_dash/only_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/unescaped_dash/prefix_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/character_set/unescaped_dash/suffix_dash/source.py +1 -0
- dev/test_data/parse_retree/expected/dot/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/group/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/group_in_a_group/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/group_of_union_of_empty_concatenations/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/regex/source.py +1 -0
- dev/test_data/parse_retree/expected/empty/union_of_empty_concatenations/source.py +1 -0
- dev/test_data/parse_retree/expected/escaped_literals/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/at_the_beginning/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/at_the_end/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/in_the_middle/source.py +1 -0
- dev/test_data/parse_retree/expected/formatted_value/single_formatted_value/source.py +1 -0
- dev/test_data/parse_retree/expected/literal/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/at_least_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/at_least_one/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/at_most_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/exactly_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/maybe/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/greedy/zero_or_more/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/at_least_one/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/at_most_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/exactly_3/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/maybe/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/non_greedy/zero_or_more/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_character_set/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_formatted_value/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_group/source.py +1 -0
- dev/test_data/parse_retree/expected/quantifier/on_a_literal/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/double_end_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/double_start_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/end_symbol_in_the_middle/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/only_start_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/only_stop_symbol/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_at_the_beginning/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/start_symbol_in_the_middle/source.py +1 -0
- dev/test_data/parse_retree/expected/start_and_stop_symbols/stop_symbol_at_the_end/source.py +1 -0
- dev/test_data/parse_retree/expected/union/of_character_sets/source.py +1 -0
- dev/test_data/parse_retree/expected/union/of_groups/source.py +1 -0
- dev/test_data/parse_retree/expected/union/of_string_literals/source.py +1 -0
- dev/test_data/parse_retree/expected/union/within_group/source.py +1 -0
- dev/test_data/parse_retree/expected/whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/Uxxxxxxxx_out_of_range/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/only_backslash/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_Uxxxxxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_uxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/short_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unexpected_escaping/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/not_word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/character_literal/unhandled/word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/Uxxxxxxxx_out_of_range/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/only_backslash/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_Uxxxxxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_uxxxx/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/short_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unexpected_escaping/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_digit/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/not_word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/whitespace/source.py +1 -0
- dev/test_data/parse_retree/unexpected/improper_escaping/range_character/unhandled/word/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_character_range/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_quantifier/at_least_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_quantifier/between_3_and_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/invalid_quantifier/exactly_x/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unhandled_group_directives/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/character_set/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/group/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/group_of_union_of_empty_concatenations/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/quantifier/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_comma/source.py +1 -0
- dev/test_data/parse_retree/unexpected/unterminated/quantifier_with_number_and_comma/source.py +1 -0
- dev/test_data/proto/test_main/expected/abstract_and_concrete_classes/meta_model.py +37 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_descendants/meta_model.py +30 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_enum/meta_model.py +21 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_list_of_instances/meta_model.py +21 -0
- dev/test_data/proto/test_main/expected/concrete_class_with_primitive_attributes/meta_model.py +41 -0
- dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/expected_output/pbization.py +532 -0
- dev/test_data/python_protobuf/test_main/abstract_and_concrete_classes/meta_model.py +37 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/expected_output/pbization.py +527 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_descendant/meta_model.py +27 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_enum/expected_output/pbization.py +290 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_enum/meta_model.py +21 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/expected_output/pbization.py +328 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_list_of_instances/meta_model.py +23 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/expected_output/pbization.py +274 -0
- dev/test_data/python_protobuf/test_main/concrete_class_with_primitive_attributes/meta_model.py +41 -0
- dev/test_data/rdf_shacl/test_main/expected/regression_when_lang_string_class_is_missing/meta_model.py +29 -0
- dev/test_data/rdf_shacl/test_main/expected/regression_when_len_constraints_on_inherited_property/meta_model.py +27 -0
- dev/test_data/rdf_shacl/test_main/unexpected/regression_len_constraint_on_class_property/meta_model.py +61 -0
- dev/test_data/real_meta_models/aas_core_meta.v3.py +5721 -0
- dev/test_data/smoke/test_main/unexpected/infer_for_schema_error/meta_model.py +12 -0
- dev/test_data/smoke/test_main/unexpected/intermediate_error/meta_model.py +18 -0
- dev/test_data/smoke/test_main/unexpected/parse_error/meta_model.py +5 -0
- dev/test_data/smoke/test_main/unexpected/pattern_verification_unparsable_regex/direct_match/meta_model.py +8 -0
- dev/test_data/smoke/test_main/unexpected/type_error/meta_model.py +18 -0
- dev/tests/__init__.py +1 -0
- dev/tests/common.py +197 -0
- dev/tests/cpp/__init__.py +0 -0
- dev/tests/cpp/test_common.py +32 -0
- dev/tests/cpp/test_main.py +144 -0
- dev/tests/cpp/test_pattern.py +188 -0
- dev/tests/cpp/test_verification.py +189 -0
- dev/tests/cpp/test_yielding.py +225 -0
- dev/tests/csharp/__init__.py +0 -0
- dev/tests/csharp/live_test_main.py +109 -0
- dev/tests/csharp/test_common.py +28 -0
- dev/tests/csharp/test_description.py +684 -0
- dev/tests/csharp/test_main.py +129 -0
- dev/tests/csharp/test_structure.py +93 -0
- dev/tests/csharp/test_verification.py +82 -0
- dev/tests/description.py +29 -0
- dev/tests/golang/__init__.py +0 -0
- dev/tests/golang/test_common.py +78 -0
- dev/tests/golang/test_main.py +128 -0
- dev/tests/infer_for_schema/__init__.py +0 -0
- dev/tests/infer_for_schema/common.py +47 -0
- dev/tests/infer_for_schema/test_len_on_properties.py +955 -0
- dev/tests/infer_for_schema/test_len_on_self.py +580 -0
- dev/tests/infer_for_schema/test_patterns_on_properties.py +686 -0
- dev/tests/infer_for_schema/test_patterns_on_self.py +258 -0
- dev/tests/infer_for_schema/test_property_in_set_of_enumeration_literals.py +600 -0
- dev/tests/infer_for_schema/test_property_in_set_of_primitives.py +549 -0
- dev/tests/intermediate/__init__.py +0 -0
- dev/tests/intermediate/test_constructor.py +719 -0
- dev/tests/intermediate/test_hierarchy.py +221 -0
- dev/tests/intermediate/test_revm.py +134 -0
- dev/tests/intermediate/test_translate.py +337 -0
- dev/tests/intermediate/test_type_inference.py +333 -0
- dev/tests/intermediate/test_types.py +169 -0
- dev/tests/java/__init__.py +0 -0
- dev/tests/java/test_common.py +20 -0
- dev/tests/java/test_description.py +128 -0
- dev/tests/java/test_main.py +234 -0
- dev/tests/jsonld_context/test_main.py +79 -0
- dev/tests/opcua/__init__.py +3 -0
- dev/tests/opcua/test_main.py +110 -0
- dev/tests/our_jsonschema/__init__.py +3 -0
- dev/tests/our_jsonschema/test_main.py +232 -0
- dev/tests/parse/__init__.py +0 -0
- dev/tests/parse/test_parse.py +503 -0
- dev/tests/parse/test_retree.py +272 -0
- dev/tests/proto/__init__.py +0 -0
- dev/tests/proto/test_main.py +112 -0
- dev/tests/python/__init__.py +0 -0
- dev/tests/python/test_common.py +124 -0
- dev/tests/python/test_main.py +126 -0
- dev/tests/python/test_xml_playground.py +254 -0
- dev/tests/python_protobuf/__init__.py +0 -0
- dev/tests/python_protobuf/test_main.py +111 -0
- dev/tests/rdf_shacl/__init__.py +0 -0
- dev/tests/rdf_shacl/test_common.py +32 -0
- dev/tests/rdf_shacl/test_description.py +223 -0
- dev/tests/rdf_shacl/test_main.py +194 -0
- dev/tests/smoke/__init__.py +0 -0
- dev/tests/smoke/test_main.py +83 -0
- dev/tests/test_common.py +94 -0
- dev/tests/typescript/__init__.py +0 -0
- dev/tests/typescript/test_common.py +108 -0
- dev/tests/typescript/test_main.py +125 -0
- dev/tests/xsd/__init__.py +0 -0
- dev/tests/xsd/test_main.py +227 -0
- dev/tests/yielding/__init__.py +0 -0
- dev/tests/yielding/test_linear.py +558 -0
|
@@ -0,0 +1,1383 @@
|
|
|
1
|
+
"""Transpile meta-model Python code to C++ code."""
|
|
2
|
+
import abc
|
|
3
|
+
import io
|
|
4
|
+
from typing import (
|
|
5
|
+
Tuple,
|
|
6
|
+
Optional,
|
|
7
|
+
List,
|
|
8
|
+
Mapping,
|
|
9
|
+
Union,
|
|
10
|
+
Set,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from icontract import ensure, require
|
|
14
|
+
|
|
15
|
+
from aas_core_codegen import intermediate
|
|
16
|
+
from aas_core_codegen.common import (
|
|
17
|
+
Error,
|
|
18
|
+
Stripped,
|
|
19
|
+
assert_never,
|
|
20
|
+
indent_but_first_line,
|
|
21
|
+
Identifier,
|
|
22
|
+
)
|
|
23
|
+
from aas_core_codegen.cpp.common import (
|
|
24
|
+
INDENT as I,
|
|
25
|
+
INDENT2 as II,
|
|
26
|
+
)
|
|
27
|
+
from aas_core_codegen.intermediate import type_inference as intermediate_type_inference
|
|
28
|
+
from aas_core_codegen.parse import tree as parse_tree
|
|
29
|
+
from aas_core_codegen.cpp import (
|
|
30
|
+
common as cpp_common,
|
|
31
|
+
naming as cpp_naming,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# fmt: off
|
|
36
|
+
@require(
|
|
37
|
+
lambda type_annotation:
|
|
38
|
+
not isinstance(type_annotation, intermediate_type_inference.OurTypeAnnotation)
|
|
39
|
+
or isinstance(type_annotation.our_type, intermediate.ConstrainedPrimitive)
|
|
40
|
+
)
|
|
41
|
+
# fmt: on
|
|
42
|
+
def _determine_which_to_wstring(
|
|
43
|
+
type_annotation: Union[
|
|
44
|
+
intermediate_type_inference.PrimitiveTypeAnnotation,
|
|
45
|
+
intermediate_type_inference.OurTypeAnnotation,
|
|
46
|
+
]
|
|
47
|
+
) -> Optional[str]:
|
|
48
|
+
"""
|
|
49
|
+
Determine which to-wstring function should be used.
|
|
50
|
+
|
|
51
|
+
None indicates that the value needs not be converted (*i.e.*, it is already
|
|
52
|
+
a wstring).
|
|
53
|
+
"""
|
|
54
|
+
if isinstance(type_annotation, intermediate_type_inference.PrimitiveTypeAnnotation):
|
|
55
|
+
if type_annotation.a_type is intermediate_type_inference.PrimitiveType.STR:
|
|
56
|
+
return None
|
|
57
|
+
elif type_annotation.a_type is intermediate_type_inference.PrimitiveType.INT:
|
|
58
|
+
return "std::to_wstring"
|
|
59
|
+
elif type_annotation.a_type is intermediate_type_inference.PrimitiveType.FLOAT:
|
|
60
|
+
return "std::to_wstring"
|
|
61
|
+
elif (
|
|
62
|
+
type_annotation.a_type
|
|
63
|
+
is intermediate_type_inference.PrimitiveType.BYTEARRAY
|
|
64
|
+
):
|
|
65
|
+
base64_encode = cpp_naming.function_name(Identifier("base64_encode"))
|
|
66
|
+
return f"wstringification::{base64_encode}"
|
|
67
|
+
else:
|
|
68
|
+
return "wstringification::to_wstring"
|
|
69
|
+
|
|
70
|
+
elif isinstance(
|
|
71
|
+
type_annotation, intermediate_type_inference.OurTypeAnnotation
|
|
72
|
+
) and isinstance(type_annotation.our_type, intermediate.ConstrainedPrimitive):
|
|
73
|
+
constrainee = type_annotation.our_type.constrainee
|
|
74
|
+
|
|
75
|
+
if constrainee is intermediate.PrimitiveType.BOOL:
|
|
76
|
+
return "wstringification::to_wstring"
|
|
77
|
+
elif constrainee is intermediate.PrimitiveType.INT:
|
|
78
|
+
return "std::to_wstring"
|
|
79
|
+
elif constrainee is intermediate.PrimitiveType.FLOAT:
|
|
80
|
+
return "std::to_wstring"
|
|
81
|
+
elif constrainee is intermediate.PrimitiveType.STR:
|
|
82
|
+
return None
|
|
83
|
+
elif constrainee is intermediate.PrimitiveType.BYTEARRAY:
|
|
84
|
+
base64_encode = cpp_naming.function_name(Identifier("base64_encode"))
|
|
85
|
+
return f"wstringification::{base64_encode}"
|
|
86
|
+
else:
|
|
87
|
+
assert_never(constrainee)
|
|
88
|
+
|
|
89
|
+
else:
|
|
90
|
+
raise ValueError(
|
|
91
|
+
f"Unexpected type annotation for which we can not determine "
|
|
92
|
+
f"the to-wstring function: {type_annotation!r}"
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# NOTE (mristin, 2023-07-01):
|
|
97
|
+
# We have to implement a very similar function for generating type annotations to
|
|
98
|
+
# ``aas_core_codegen.cpp.common.generate_type`` since we can not simply pass
|
|
99
|
+
# ``intermediate_type_inference.TypeAnnotationUnion`` to
|
|
100
|
+
# ``aas_core_codegen.cpp.common.generate_type``.
|
|
101
|
+
|
|
102
|
+
PRIMITIVE_TYPE_MAP = {
|
|
103
|
+
intermediate_type_inference.PrimitiveType.BOOL: Stripped("bool"),
|
|
104
|
+
intermediate_type_inference.PrimitiveType.INT: Stripped("int64_t"),
|
|
105
|
+
intermediate_type_inference.PrimitiveType.FLOAT: Stripped("double"),
|
|
106
|
+
intermediate_type_inference.PrimitiveType.STR: Stripped("std::wstring"),
|
|
107
|
+
intermediate_type_inference.PrimitiveType.BYTEARRAY: Stripped(
|
|
108
|
+
"std::vector<std::uint8_t>"
|
|
109
|
+
),
|
|
110
|
+
intermediate_type_inference.PrimitiveType.NONE: Stripped("void*"),
|
|
111
|
+
intermediate_type_inference.PrimitiveType.LENGTH: Stripped("size_t"),
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
116
|
+
def generate_type(
|
|
117
|
+
type_annotation: intermediate_type_inference.TypeAnnotationUnion,
|
|
118
|
+
types_namespace: Optional[Identifier] = None,
|
|
119
|
+
) -> Tuple[Optional[Stripped], Optional[str]]:
|
|
120
|
+
"""
|
|
121
|
+
Generate the C++ type for the given type annotation.
|
|
122
|
+
|
|
123
|
+
If ``types_namespace`` is specified, it is prepended to all our types.
|
|
124
|
+
|
|
125
|
+
(mristin, 2023-07-01): We do not handle all the type annotations from
|
|
126
|
+
:py:mod:`aas_core_codegen.intermediate.type_inference` as that would be
|
|
127
|
+
YAGNI (*e.g.*, verification functions, built-in functions *etc.*).
|
|
128
|
+
If we do not know how to generate the type in C++, we return an error message.
|
|
129
|
+
"""
|
|
130
|
+
if isinstance(type_annotation, intermediate_type_inference.PrimitiveTypeAnnotation):
|
|
131
|
+
return PRIMITIVE_TYPE_MAP[type_annotation.a_type], None
|
|
132
|
+
|
|
133
|
+
elif isinstance(type_annotation, intermediate_type_inference.OurTypeAnnotation):
|
|
134
|
+
our_type = type_annotation.our_type
|
|
135
|
+
|
|
136
|
+
if isinstance(our_type, intermediate.Enumeration):
|
|
137
|
+
enum_name = cpp_naming.enum_name(type_annotation.our_type.name)
|
|
138
|
+
if types_namespace is None:
|
|
139
|
+
return enum_name, None
|
|
140
|
+
|
|
141
|
+
return Stripped(f"{types_namespace}::{enum_name}"), None
|
|
142
|
+
|
|
143
|
+
elif isinstance(our_type, intermediate.ConstrainedPrimitive):
|
|
144
|
+
return cpp_common.PRIMITIVE_TYPE_MAP[our_type.constrainee], None
|
|
145
|
+
|
|
146
|
+
elif isinstance(
|
|
147
|
+
our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
|
|
148
|
+
):
|
|
149
|
+
# NOTE (mristin, 2023-07-01):
|
|
150
|
+
# We always refer to interfaces even in cases of concrete classes without
|
|
151
|
+
# concrete descendants since we want to allow enhancing.
|
|
152
|
+
interface_name = cpp_naming.interface_name(our_type.name)
|
|
153
|
+
|
|
154
|
+
if types_namespace is None:
|
|
155
|
+
return interface_name, None
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
Stripped(f"std::shared_ptr<{types_namespace}::{interface_name}>"),
|
|
159
|
+
None,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
elif isinstance(type_annotation, intermediate_type_inference.ListTypeAnnotation):
|
|
163
|
+
item_type, error_msg = generate_type(
|
|
164
|
+
type_annotation=type_annotation.items, types_namespace=types_namespace
|
|
165
|
+
)
|
|
166
|
+
if error_msg is not None:
|
|
167
|
+
return None, error_msg
|
|
168
|
+
|
|
169
|
+
assert item_type is not None
|
|
170
|
+
if item_type.endswith(">"):
|
|
171
|
+
return Stripped(f"std::vector<{item_type} >"), None
|
|
172
|
+
|
|
173
|
+
return Stripped(f"std::vector<{item_type}>"), None
|
|
174
|
+
|
|
175
|
+
elif isinstance(
|
|
176
|
+
type_annotation, intermediate_type_inference.OptionalTypeAnnotation
|
|
177
|
+
):
|
|
178
|
+
value_type, error_msg = generate_type(
|
|
179
|
+
type_annotation=type_annotation.value, types_namespace=types_namespace
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
if error_msg is not None:
|
|
183
|
+
return None, error_msg
|
|
184
|
+
|
|
185
|
+
assert value_type is not None
|
|
186
|
+
|
|
187
|
+
if value_type.endswith(">"):
|
|
188
|
+
return Stripped(f"common::optional<{value_type} >"), None
|
|
189
|
+
|
|
190
|
+
return Stripped(f"common::optional<{value_type}>"), None
|
|
191
|
+
|
|
192
|
+
else:
|
|
193
|
+
return None, (
|
|
194
|
+
f"(mristin, 2023-06-01): We do not handle "
|
|
195
|
+
f"the type annotation {type_annotation} from "
|
|
196
|
+
"aas_core_codegen.intermediate.type_inference as that was, "
|
|
197
|
+
"at this time point, YAGNI (*e.g.*, verification functions, "
|
|
198
|
+
"built-in functions *etc.*). If you need this feature, please "
|
|
199
|
+
"contact the developers."
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
raise AssertionError("Should not have gotten here")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def determine_whether_referencable(
|
|
206
|
+
type_annotation: intermediate_type_inference.TypeAnnotationUnion,
|
|
207
|
+
) -> Tuple[Optional[bool], Optional[str]]:
|
|
208
|
+
"""
|
|
209
|
+
Return ``True`` if the type annotation denotes a referencable value.
|
|
210
|
+
|
|
211
|
+
(mristin, 2023-10-19): We do not handle all the type annotations from
|
|
212
|
+
:py:mod:`aas_core_codegen.intermediate.type_inference` as that would be
|
|
213
|
+
YAGNI (*e.g.*, verification functions, built-in functions *etc.*).
|
|
214
|
+
If we do not know how to generate the type in C++, we return an error message.
|
|
215
|
+
"""
|
|
216
|
+
if isinstance(type_annotation, intermediate_type_inference.PrimitiveTypeAnnotation):
|
|
217
|
+
return False, None
|
|
218
|
+
|
|
219
|
+
elif isinstance(type_annotation, intermediate_type_inference.OurTypeAnnotation):
|
|
220
|
+
our_type = type_annotation.our_type
|
|
221
|
+
|
|
222
|
+
if isinstance(our_type, intermediate.Enumeration):
|
|
223
|
+
return False, None
|
|
224
|
+
|
|
225
|
+
elif isinstance(our_type, intermediate.ConstrainedPrimitive):
|
|
226
|
+
return False, None
|
|
227
|
+
|
|
228
|
+
elif isinstance(
|
|
229
|
+
our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
|
|
230
|
+
):
|
|
231
|
+
return True, None
|
|
232
|
+
|
|
233
|
+
elif isinstance(type_annotation, intermediate_type_inference.ListTypeAnnotation):
|
|
234
|
+
return True, None
|
|
235
|
+
|
|
236
|
+
elif isinstance(
|
|
237
|
+
type_annotation, intermediate_type_inference.OptionalTypeAnnotation
|
|
238
|
+
):
|
|
239
|
+
return True, None
|
|
240
|
+
|
|
241
|
+
else:
|
|
242
|
+
return None, (
|
|
243
|
+
f"(mristin, 2023-06-01): We do not handle "
|
|
244
|
+
f"the type annotation {type_annotation} from "
|
|
245
|
+
"aas_core_codegen.intermediate.type_inference as that was, "
|
|
246
|
+
"at this time point, YAGNI (*e.g.*, verification functions, "
|
|
247
|
+
"built-in functions *etc.*). If you need this feature, please "
|
|
248
|
+
"contact the developers."
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
raise AssertionError("Should not have gotten here")
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
255
|
+
def generate_type_with_const_ref_if_applicable(
|
|
256
|
+
type_annotation: intermediate_type_inference.TypeAnnotationUnion,
|
|
257
|
+
types_namespace: Optional[Identifier] = None,
|
|
258
|
+
) -> Tuple[Optional[Stripped], Optional[str]]:
|
|
259
|
+
"""
|
|
260
|
+
Generate the C++ type and wrap it in ``const T&``, if applicable.
|
|
261
|
+
|
|
262
|
+
If ``types_namespace`` is specified, it is prepended to all our types.
|
|
263
|
+
|
|
264
|
+
(mristin, 2023-10-19): We do not handle all the type annotations from
|
|
265
|
+
:py:mod:`aas_core_codegen.intermediate.type_inference` as that would be
|
|
266
|
+
YAGNI (*e.g.*, verification functions, built-in functions *etc.*).
|
|
267
|
+
If we do not know how to generate the type in C++, we return an error message.
|
|
268
|
+
"""
|
|
269
|
+
code, error = generate_type(
|
|
270
|
+
type_annotation=type_annotation, types_namespace=types_namespace
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
if error is not None:
|
|
274
|
+
return None, error
|
|
275
|
+
|
|
276
|
+
assert code is not None
|
|
277
|
+
|
|
278
|
+
referencable, error = determine_whether_referencable(type_annotation)
|
|
279
|
+
if error is not None:
|
|
280
|
+
return None, error
|
|
281
|
+
|
|
282
|
+
assert referencable is not None
|
|
283
|
+
|
|
284
|
+
if referencable:
|
|
285
|
+
return Stripped(f"const {code}&"), None
|
|
286
|
+
|
|
287
|
+
return code, None
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
class Transpiler(
|
|
291
|
+
parse_tree.RestrictedTransformer[Tuple[Optional[Stripped], Optional[Error]]]
|
|
292
|
+
):
|
|
293
|
+
"""Transpile a node of our AST to C++ code, or return an error."""
|
|
294
|
+
|
|
295
|
+
_CPP_COMPARISON_MAP = {
|
|
296
|
+
parse_tree.Comparator.LT: "<",
|
|
297
|
+
parse_tree.Comparator.LE: "<=",
|
|
298
|
+
parse_tree.Comparator.GT: ">",
|
|
299
|
+
parse_tree.Comparator.GE: ">=",
|
|
300
|
+
parse_tree.Comparator.EQ: "==",
|
|
301
|
+
parse_tree.Comparator.NE: "!=",
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
def __init__(
|
|
305
|
+
self,
|
|
306
|
+
type_map: Mapping[
|
|
307
|
+
parse_tree.Node, intermediate_type_inference.TypeAnnotationUnion
|
|
308
|
+
],
|
|
309
|
+
is_optional_map: Mapping[parse_tree.Node, bool],
|
|
310
|
+
environment: intermediate_type_inference.Environment,
|
|
311
|
+
types_namespace: Optional[Identifier] = None,
|
|
312
|
+
) -> None:
|
|
313
|
+
"""
|
|
314
|
+
Initialize with the given values.
|
|
315
|
+
|
|
316
|
+
If ``types_namespace`` is specified, it is prepended to all our types.
|
|
317
|
+
"""
|
|
318
|
+
self.type_map = type_map
|
|
319
|
+
self.is_optional_map = is_optional_map
|
|
320
|
+
self._environment = intermediate_type_inference.MutableEnvironment(
|
|
321
|
+
parent=environment
|
|
322
|
+
)
|
|
323
|
+
self._types_namespace = types_namespace
|
|
324
|
+
|
|
325
|
+
# NOTE (mristin, 2023-06-30):
|
|
326
|
+
# Keep track whenever we define a variable name, so that we can know how to
|
|
327
|
+
# resolve it as a name in the C++ code.
|
|
328
|
+
#
|
|
329
|
+
# While this class does not directly use it, the descendants of this class do!
|
|
330
|
+
self._variable_name_set = set() # type: Set[Identifier]
|
|
331
|
+
|
|
332
|
+
def _transform_enumeration_literal(
|
|
333
|
+
self, enumeration_name: Identifier, literal_name: Identifier
|
|
334
|
+
) -> Stripped:
|
|
335
|
+
"""Generate the code to represent an enumeration literal."""
|
|
336
|
+
cpp_enum_name = cpp_naming.enum_name(enumeration_name)
|
|
337
|
+
cpp_literal_name = cpp_naming.enum_literal_name(literal_name)
|
|
338
|
+
if self._types_namespace is not None:
|
|
339
|
+
return Stripped(
|
|
340
|
+
f"{self._types_namespace}::{cpp_enum_name}::{cpp_literal_name}"
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
return Stripped(f"{cpp_enum_name}::{cpp_literal_name}")
|
|
344
|
+
|
|
345
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
346
|
+
def _transform_and_value_if_necessary(
|
|
347
|
+
self, node: parse_tree.Node
|
|
348
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
349
|
+
"""
|
|
350
|
+
Call ``.value()`` on the given node if it is a ``common::optional``.
|
|
351
|
+
|
|
352
|
+
If the value denoted by ``node`` is not a ``common::optional``, it is returned
|
|
353
|
+
transpiled as-is.
|
|
354
|
+
"""
|
|
355
|
+
code, error = self.transform(node)
|
|
356
|
+
if error is not None:
|
|
357
|
+
return None, error
|
|
358
|
+
|
|
359
|
+
if self.is_optional_map[node]:
|
|
360
|
+
no_parentheses_types = (
|
|
361
|
+
parse_tree.FunctionCall,
|
|
362
|
+
parse_tree.Name,
|
|
363
|
+
parse_tree.Constant,
|
|
364
|
+
)
|
|
365
|
+
if isinstance(node, no_parentheses_types):
|
|
366
|
+
return Stripped(f"*{code}"), None
|
|
367
|
+
|
|
368
|
+
return Stripped(f"(*({code}))"), None
|
|
369
|
+
|
|
370
|
+
return code, None
|
|
371
|
+
|
|
372
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
373
|
+
def transform_member(
|
|
374
|
+
self, node: parse_tree.Member
|
|
375
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
376
|
+
instance, error = self._transform_and_value_if_necessary(node.instance)
|
|
377
|
+
if error is not None:
|
|
378
|
+
return None, error
|
|
379
|
+
|
|
380
|
+
instance_type = self.type_map[node.instance]
|
|
381
|
+
|
|
382
|
+
instance_type_beneath = intermediate_type_inference.beneath_optional(
|
|
383
|
+
instance_type
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
member_type = self.type_map[node]
|
|
387
|
+
member_type_beneath = intermediate_type_inference.beneath_optional(member_type)
|
|
388
|
+
|
|
389
|
+
member_accessor: str
|
|
390
|
+
|
|
391
|
+
if isinstance(
|
|
392
|
+
instance_type_beneath, intermediate_type_inference.OurTypeAnnotation
|
|
393
|
+
) and isinstance(instance_type_beneath.our_type, intermediate.Enumeration):
|
|
394
|
+
# NOTE (mristin, 2023-06-30):
|
|
395
|
+
# This member denotes an enumeration literal of an enumeration.
|
|
396
|
+
# In C++, enumeration literals are mere constants. Hence, we can not
|
|
397
|
+
# "de-reference" the enumeration literals from an enumeration, but
|
|
398
|
+
# generate the constant name here.
|
|
399
|
+
return (
|
|
400
|
+
self._transform_enumeration_literal(
|
|
401
|
+
enumeration_name=instance_type_beneath.our_type.name,
|
|
402
|
+
literal_name=node.name,
|
|
403
|
+
),
|
|
404
|
+
None,
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
elif isinstance(
|
|
408
|
+
member_type_beneath, intermediate_type_inference.MethodTypeAnnotation
|
|
409
|
+
):
|
|
410
|
+
member_accessor = cpp_naming.method_name(node.name)
|
|
411
|
+
|
|
412
|
+
elif isinstance(
|
|
413
|
+
instance_type_beneath, intermediate_type_inference.OurTypeAnnotation
|
|
414
|
+
) and isinstance(instance_type_beneath.our_type, intermediate.Class):
|
|
415
|
+
if node.name in instance_type_beneath.our_type.properties_by_name:
|
|
416
|
+
getter_name = cpp_naming.getter_name(node.name)
|
|
417
|
+
member_accessor = f"{getter_name}()"
|
|
418
|
+
else:
|
|
419
|
+
return None, Error(
|
|
420
|
+
node.original_node,
|
|
421
|
+
f"The property {node.name!r} has not been defined "
|
|
422
|
+
f"in the class {instance_type_beneath.our_type.name!r}",
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
elif isinstance(
|
|
426
|
+
instance_type_beneath,
|
|
427
|
+
intermediate_type_inference.EnumerationAsTypeTypeAnnotation,
|
|
428
|
+
):
|
|
429
|
+
if node.name in instance_type_beneath.enumeration.literals_by_name:
|
|
430
|
+
# NOTE (mristin, 2023-06-30):
|
|
431
|
+
# The member denotes an enumeration literal of an enumeration.
|
|
432
|
+
# In C++, enumeration literals are mere constants. Hence, we can not
|
|
433
|
+
# "de-reference" the enumeration literals from an enumeration, but
|
|
434
|
+
# generate the constant name here.
|
|
435
|
+
return (
|
|
436
|
+
self._transform_enumeration_literal(
|
|
437
|
+
enumeration_name=instance_type_beneath.enumeration.name,
|
|
438
|
+
literal_name=node.name,
|
|
439
|
+
),
|
|
440
|
+
None,
|
|
441
|
+
)
|
|
442
|
+
else:
|
|
443
|
+
return None, Error(
|
|
444
|
+
node.original_node,
|
|
445
|
+
f"The literal {node.name!r} has not been defined "
|
|
446
|
+
f"in the enumeration {instance_type_beneath.enumeration.name!r}",
|
|
447
|
+
)
|
|
448
|
+
else:
|
|
449
|
+
return None, Error(
|
|
450
|
+
node.original_node,
|
|
451
|
+
f"We do not know how to generate the member access. The inferred type "
|
|
452
|
+
f"of the instance was {instance_type}, while the member type "
|
|
453
|
+
f"was {member_type}. However, we do not know how to resolve "
|
|
454
|
+
f"the member {node.name!r} in {instance_type}.",
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
assert isinstance(
|
|
458
|
+
instance_type_beneath, intermediate_type_inference.OurTypeAnnotation
|
|
459
|
+
) and isinstance(instance_type_beneath.our_type, intermediate.Class), (
|
|
460
|
+
f"The access to enumeration literals is expected to have been handled "
|
|
461
|
+
f"before. If we got to this point, the instance is expected to be "
|
|
462
|
+
f"an instance of a class, as we access its members with '->' and "
|
|
463
|
+
f"assume it is a ``std::shared_ptr``. However, we got: {instance_type}"
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
return Stripped(f"{instance}->{member_accessor}"), None
|
|
467
|
+
|
|
468
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
469
|
+
def transform_index(
|
|
470
|
+
self, node: parse_tree.Index
|
|
471
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
472
|
+
collection, error = self._transform_and_value_if_necessary(node.collection)
|
|
473
|
+
if error is not None:
|
|
474
|
+
return None, error
|
|
475
|
+
|
|
476
|
+
index, error = self._transform_and_value_if_necessary(node.index)
|
|
477
|
+
if error is not None:
|
|
478
|
+
return None, error
|
|
479
|
+
assert index is not None
|
|
480
|
+
|
|
481
|
+
index_as_int = None # type: Optional[int]
|
|
482
|
+
try:
|
|
483
|
+
index_as_int = int(index)
|
|
484
|
+
except ValueError:
|
|
485
|
+
pass
|
|
486
|
+
|
|
487
|
+
if index_as_int is not None and index_as_int == -1:
|
|
488
|
+
return Stripped(f"{collection}.back()"), None
|
|
489
|
+
|
|
490
|
+
if index_as_int is not None and index_as_int < -1:
|
|
491
|
+
# pylint: disable=invalid-unary-operand-type
|
|
492
|
+
index = Stripped(f"{collection}.size() - {-index_as_int}")
|
|
493
|
+
|
|
494
|
+
if "\n" in index:
|
|
495
|
+
return (
|
|
496
|
+
Stripped(
|
|
497
|
+
f"""\
|
|
498
|
+
{collection}.at(
|
|
499
|
+
{I}{indent_but_first_line(index, I)}
|
|
500
|
+
)"""
|
|
501
|
+
),
|
|
502
|
+
None,
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
return Stripped(f"{collection}.at({index})"), None
|
|
506
|
+
|
|
507
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
508
|
+
def transform_comparison(
|
|
509
|
+
self, node: parse_tree.Comparison
|
|
510
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
511
|
+
comparator = Transpiler._CPP_COMPARISON_MAP[node.op]
|
|
512
|
+
|
|
513
|
+
errors = []
|
|
514
|
+
|
|
515
|
+
left, error = self._transform_and_value_if_necessary(node.left)
|
|
516
|
+
if error is not None:
|
|
517
|
+
errors.append(error)
|
|
518
|
+
|
|
519
|
+
right, error = self._transform_and_value_if_necessary(node.right)
|
|
520
|
+
if error is not None:
|
|
521
|
+
errors.append(error)
|
|
522
|
+
|
|
523
|
+
if len(errors) > 0:
|
|
524
|
+
return None, Error(
|
|
525
|
+
node.original_node, "Failed to transpile the comparison", errors
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
no_parentheses_types = (
|
|
529
|
+
parse_tree.Member,
|
|
530
|
+
parse_tree.FunctionCall,
|
|
531
|
+
parse_tree.MethodCall,
|
|
532
|
+
parse_tree.Name,
|
|
533
|
+
parse_tree.Constant,
|
|
534
|
+
parse_tree.Index,
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
if isinstance(node.left, no_parentheses_types) and isinstance(
|
|
538
|
+
node.right, no_parentheses_types
|
|
539
|
+
):
|
|
540
|
+
return Stripped(f"{left} {comparator} {right}"), None
|
|
541
|
+
|
|
542
|
+
return Stripped(f"({left}) {comparator} ({right})"), None
|
|
543
|
+
|
|
544
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
545
|
+
def transform_is_in(
|
|
546
|
+
self, node: parse_tree.IsIn
|
|
547
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
548
|
+
errors = []
|
|
549
|
+
|
|
550
|
+
member, error = self._transform_and_value_if_necessary(node.member)
|
|
551
|
+
if error is not None:
|
|
552
|
+
errors.append(error)
|
|
553
|
+
|
|
554
|
+
container, error = self._transform_and_value_if_necessary(node.container)
|
|
555
|
+
if error is not None:
|
|
556
|
+
errors.append(error)
|
|
557
|
+
|
|
558
|
+
if len(errors) > 0:
|
|
559
|
+
return None, Error(
|
|
560
|
+
node.original_node,
|
|
561
|
+
"Failed to transpile the membership relation",
|
|
562
|
+
errors,
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
assert member is not None
|
|
566
|
+
assert container is not None
|
|
567
|
+
|
|
568
|
+
contains_function = cpp_naming.function_name(Identifier("contains"))
|
|
569
|
+
|
|
570
|
+
return (
|
|
571
|
+
Stripped(
|
|
572
|
+
f"""\
|
|
573
|
+
common::{contains_function}(
|
|
574
|
+
{I}{indent_but_first_line(container, I)},
|
|
575
|
+
{I}{indent_but_first_line(member, I)}
|
|
576
|
+
)"""
|
|
577
|
+
),
|
|
578
|
+
None,
|
|
579
|
+
)
|
|
580
|
+
|
|
581
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
582
|
+
def transform_implication(
|
|
583
|
+
self, node: parse_tree.Implication
|
|
584
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
585
|
+
errors = []
|
|
586
|
+
|
|
587
|
+
antecedent, error = self._transform_and_value_if_necessary(node.antecedent)
|
|
588
|
+
if error is not None:
|
|
589
|
+
errors.append(error)
|
|
590
|
+
|
|
591
|
+
consequent, error = self._transform_and_value_if_necessary(node.consequent)
|
|
592
|
+
if error is not None:
|
|
593
|
+
errors.append(error)
|
|
594
|
+
|
|
595
|
+
if len(errors) > 0:
|
|
596
|
+
return None, Error(
|
|
597
|
+
node.original_node, "Failed to transpile the implication", errors
|
|
598
|
+
)
|
|
599
|
+
|
|
600
|
+
assert antecedent is not None
|
|
601
|
+
assert consequent is not None
|
|
602
|
+
|
|
603
|
+
no_parentheses_types_in_this_context = (
|
|
604
|
+
parse_tree.Member,
|
|
605
|
+
parse_tree.FunctionCall,
|
|
606
|
+
parse_tree.MethodCall,
|
|
607
|
+
parse_tree.Name,
|
|
608
|
+
parse_tree.IsIn,
|
|
609
|
+
parse_tree.Index,
|
|
610
|
+
parse_tree.All,
|
|
611
|
+
parse_tree.Any,
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
if isinstance(node.antecedent, no_parentheses_types_in_this_context):
|
|
615
|
+
not_antecedent = f"!{antecedent}"
|
|
616
|
+
else:
|
|
617
|
+
not_antecedent = f"!({antecedent})"
|
|
618
|
+
|
|
619
|
+
if not isinstance(node.consequent, no_parentheses_types_in_this_context):
|
|
620
|
+
consequent = Stripped(f"({consequent})")
|
|
621
|
+
|
|
622
|
+
return Stripped(f"{not_antecedent}\n|| {consequent}"), None
|
|
623
|
+
|
|
624
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
625
|
+
def transform_method_call(
|
|
626
|
+
self, node: parse_tree.MethodCall
|
|
627
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
628
|
+
errors = [] # type: List[Error]
|
|
629
|
+
|
|
630
|
+
member_access, error = self._transform_and_value_if_necessary(node.member)
|
|
631
|
+
if error is not None:
|
|
632
|
+
errors.append(error)
|
|
633
|
+
|
|
634
|
+
args = [] # type: List[Stripped]
|
|
635
|
+
for arg_node in node.args:
|
|
636
|
+
arg_type = self.type_map[arg_node]
|
|
637
|
+
|
|
638
|
+
# NOTE (mristin):
|
|
639
|
+
# This is a tough call to make. We decide that a value, for which we
|
|
640
|
+
# know that it might be null, will not be de-referenced. On the other
|
|
641
|
+
# hand, if the value is certainly not null, we de-reference it.
|
|
642
|
+
#
|
|
643
|
+
# The problem here is that the actual type of the argument in C++ changes
|
|
644
|
+
# depending on whether we check for its nullness before with an implication.
|
|
645
|
+
|
|
646
|
+
arg: Optional[Stripped]
|
|
647
|
+
if isinstance(arg_type, intermediate_type_inference.OptionalTypeAnnotation):
|
|
648
|
+
arg, error = self.transform(arg_node)
|
|
649
|
+
else:
|
|
650
|
+
arg, error = self._transform_and_value_if_necessary(arg_node)
|
|
651
|
+
|
|
652
|
+
if error is not None:
|
|
653
|
+
errors.append(error)
|
|
654
|
+
continue
|
|
655
|
+
|
|
656
|
+
assert arg is not None
|
|
657
|
+
|
|
658
|
+
args.append(arg)
|
|
659
|
+
|
|
660
|
+
if len(errors) > 0:
|
|
661
|
+
return None, Error(
|
|
662
|
+
node.original_node, "Failed to transpile the method call", errors
|
|
663
|
+
)
|
|
664
|
+
|
|
665
|
+
assert member_access is not None
|
|
666
|
+
|
|
667
|
+
if len(args) == 0:
|
|
668
|
+
return Stripped(f"{member_access}()"), None
|
|
669
|
+
|
|
670
|
+
joined_args = ",\n".join(args)
|
|
671
|
+
return (
|
|
672
|
+
Stripped(
|
|
673
|
+
f"""\
|
|
674
|
+
{member_access}(
|
|
675
|
+
{I}{indent_but_first_line(joined_args, I)}
|
|
676
|
+
)"""
|
|
677
|
+
),
|
|
678
|
+
None,
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
682
|
+
def transform_function_call(
|
|
683
|
+
self, node: parse_tree.FunctionCall
|
|
684
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
685
|
+
errors = [] # type: List[Error]
|
|
686
|
+
|
|
687
|
+
args = [] # type: List[Stripped]
|
|
688
|
+
for arg_node in node.args:
|
|
689
|
+
arg_type = self.type_map[arg_node]
|
|
690
|
+
|
|
691
|
+
# NOTE (mristin):
|
|
692
|
+
# This is a tough call to make. We decide that a value, for which we
|
|
693
|
+
# know that it might be null, will not be de-referenced. On the other
|
|
694
|
+
# hand, if the value is certainly not null, we de-reference it.
|
|
695
|
+
#
|
|
696
|
+
# The problem here is that the actual type of the argument in C++ changes
|
|
697
|
+
# depending on whether we check for its nullness before with an implication.
|
|
698
|
+
arg: Optional[Stripped]
|
|
699
|
+
if isinstance(arg_type, intermediate_type_inference.OptionalTypeAnnotation):
|
|
700
|
+
arg, error = self.transform(arg_node)
|
|
701
|
+
else:
|
|
702
|
+
arg, error = self._transform_and_value_if_necessary(arg_node)
|
|
703
|
+
|
|
704
|
+
if error is not None:
|
|
705
|
+
errors.append(error)
|
|
706
|
+
continue
|
|
707
|
+
|
|
708
|
+
assert arg is not None
|
|
709
|
+
|
|
710
|
+
args.append(arg)
|
|
711
|
+
|
|
712
|
+
if len(errors) > 0:
|
|
713
|
+
return None, Error(
|
|
714
|
+
node.original_node, "Failed to transpile the function call", errors
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
# NOTE (mristin, 2023-06-30):
|
|
718
|
+
# The validity of the arguments is checked in
|
|
719
|
+
# :py:func:`aas_core_codegen.intermediate._translate.translate`, so we do not
|
|
720
|
+
# have to test for argument arity here.
|
|
721
|
+
|
|
722
|
+
func_type = self.type_map[node.name]
|
|
723
|
+
|
|
724
|
+
if not isinstance(
|
|
725
|
+
func_type, intermediate_type_inference.FunctionTypeAnnotationUnionAsTuple
|
|
726
|
+
):
|
|
727
|
+
return None, Error(
|
|
728
|
+
node.name.original_node,
|
|
729
|
+
f"Expected the name to refer to a function, "
|
|
730
|
+
f"but its inferred type was {func_type}",
|
|
731
|
+
)
|
|
732
|
+
|
|
733
|
+
if isinstance(
|
|
734
|
+
func_type, intermediate_type_inference.VerificationTypeAnnotation
|
|
735
|
+
):
|
|
736
|
+
function_name, error = self.transform_name(node.name)
|
|
737
|
+
if error is not None:
|
|
738
|
+
return None, error
|
|
739
|
+
|
|
740
|
+
assert function_name is not None
|
|
741
|
+
|
|
742
|
+
if len(args) == 0:
|
|
743
|
+
return Stripped(f"{function_name}()"), None
|
|
744
|
+
|
|
745
|
+
joined_args = ",\n".join(args)
|
|
746
|
+
return (
|
|
747
|
+
Stripped(
|
|
748
|
+
f"""\
|
|
749
|
+
{function_name}(
|
|
750
|
+
{I}{indent_but_first_line(joined_args, I)}
|
|
751
|
+
)"""
|
|
752
|
+
),
|
|
753
|
+
None,
|
|
754
|
+
)
|
|
755
|
+
|
|
756
|
+
elif isinstance(
|
|
757
|
+
func_type, intermediate_type_inference.BuiltinFunctionTypeAnnotation
|
|
758
|
+
):
|
|
759
|
+
if func_type.func.name == "len":
|
|
760
|
+
assert len(args) == 1, (
|
|
761
|
+
f"Expected exactly one argument, but got: {args}; "
|
|
762
|
+
f"this should have been caught before."
|
|
763
|
+
)
|
|
764
|
+
|
|
765
|
+
no_parentheses_types_in_this_context = (
|
|
766
|
+
parse_tree.Member,
|
|
767
|
+
parse_tree.FunctionCall,
|
|
768
|
+
parse_tree.MethodCall,
|
|
769
|
+
parse_tree.Name,
|
|
770
|
+
parse_tree.IsIn,
|
|
771
|
+
parse_tree.Index,
|
|
772
|
+
parse_tree.All,
|
|
773
|
+
parse_tree.Any,
|
|
774
|
+
)
|
|
775
|
+
|
|
776
|
+
first_arg, error = self._transform_and_value_if_necessary(node.args[0])
|
|
777
|
+
if error is not None:
|
|
778
|
+
return None, error
|
|
779
|
+
|
|
780
|
+
assert first_arg is not None
|
|
781
|
+
|
|
782
|
+
if not isinstance(node.args[0], no_parentheses_types_in_this_context):
|
|
783
|
+
first_arg = Stripped(f"({first_arg})")
|
|
784
|
+
|
|
785
|
+
return Stripped(f"{first_arg}.size()"), None
|
|
786
|
+
|
|
787
|
+
else:
|
|
788
|
+
return None, Error(
|
|
789
|
+
node.original_node,
|
|
790
|
+
f"The handling of the built-in function {node.name!r} has not "
|
|
791
|
+
f"been implemented",
|
|
792
|
+
)
|
|
793
|
+
else:
|
|
794
|
+
assert_never(func_type)
|
|
795
|
+
|
|
796
|
+
raise AssertionError("Should not have gotten here")
|
|
797
|
+
|
|
798
|
+
def transform_constant(
|
|
799
|
+
self, node: parse_tree.Constant
|
|
800
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
801
|
+
if isinstance(node.value, bool):
|
|
802
|
+
return Stripped("true" if node.value else "false"), None
|
|
803
|
+
elif isinstance(node.value, (int, float)):
|
|
804
|
+
return Stripped(cpp_common.float_literal(node.value)), None
|
|
805
|
+
elif isinstance(node.value, str):
|
|
806
|
+
return Stripped(cpp_common.wstring_literal(node.value)), None
|
|
807
|
+
elif isinstance(node.value, bytes):
|
|
808
|
+
literal, multiline = cpp_common.bytes_literal(node.value)
|
|
809
|
+
|
|
810
|
+
if not multiline:
|
|
811
|
+
return Stripped(literal), None
|
|
812
|
+
else:
|
|
813
|
+
return (
|
|
814
|
+
Stripped(
|
|
815
|
+
f"""\
|
|
816
|
+
(
|
|
817
|
+
{I}{indent_but_first_line(literal, I)}
|
|
818
|
+
)"""
|
|
819
|
+
),
|
|
820
|
+
None,
|
|
821
|
+
)
|
|
822
|
+
else:
|
|
823
|
+
assert_never(node.value)
|
|
824
|
+
|
|
825
|
+
raise AssertionError("Should not have gotten here")
|
|
826
|
+
|
|
827
|
+
def transform_is_none(
|
|
828
|
+
self, node: parse_tree.IsNone
|
|
829
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
830
|
+
value, error = self.transform(node.value)
|
|
831
|
+
if error is not None:
|
|
832
|
+
return None, error
|
|
833
|
+
|
|
834
|
+
no_parentheses_types = (
|
|
835
|
+
parse_tree.Member,
|
|
836
|
+
parse_tree.FunctionCall,
|
|
837
|
+
parse_tree.MethodCall,
|
|
838
|
+
parse_tree.Name,
|
|
839
|
+
parse_tree.IsIn,
|
|
840
|
+
parse_tree.Index,
|
|
841
|
+
parse_tree.All,
|
|
842
|
+
parse_tree.Any,
|
|
843
|
+
)
|
|
844
|
+
if isinstance(node.value, no_parentheses_types):
|
|
845
|
+
return Stripped(f"!({value}.has_value())"), None
|
|
846
|
+
else:
|
|
847
|
+
return Stripped(f"!(({value}).has_value())"), None
|
|
848
|
+
|
|
849
|
+
def transform_is_not_none(
|
|
850
|
+
self, node: parse_tree.IsNotNone
|
|
851
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
852
|
+
value, error = self.transform(node.value)
|
|
853
|
+
if error is not None:
|
|
854
|
+
return None, error
|
|
855
|
+
|
|
856
|
+
no_parentheses_types_in_this_context = (
|
|
857
|
+
parse_tree.Member,
|
|
858
|
+
parse_tree.FunctionCall,
|
|
859
|
+
parse_tree.MethodCall,
|
|
860
|
+
parse_tree.Name,
|
|
861
|
+
parse_tree.IsIn,
|
|
862
|
+
parse_tree.Index,
|
|
863
|
+
parse_tree.All,
|
|
864
|
+
parse_tree.Any,
|
|
865
|
+
)
|
|
866
|
+
if isinstance(node.value, no_parentheses_types_in_this_context):
|
|
867
|
+
return Stripped(f"{value}.has_value()"), None
|
|
868
|
+
else:
|
|
869
|
+
return Stripped(f"({value}).has_value()"), None
|
|
870
|
+
|
|
871
|
+
@abc.abstractmethod
|
|
872
|
+
def transform_name(
|
|
873
|
+
self, node: parse_tree.Name
|
|
874
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
875
|
+
raise NotImplementedError()
|
|
876
|
+
|
|
877
|
+
def transform_not(
|
|
878
|
+
self, node: parse_tree.Not
|
|
879
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
880
|
+
operand, error = self._transform_and_value_if_necessary(node.operand)
|
|
881
|
+
if error is not None:
|
|
882
|
+
return None, error
|
|
883
|
+
|
|
884
|
+
no_parentheses_types_in_this_context = (
|
|
885
|
+
parse_tree.Member,
|
|
886
|
+
parse_tree.FunctionCall,
|
|
887
|
+
parse_tree.MethodCall,
|
|
888
|
+
parse_tree.Name,
|
|
889
|
+
parse_tree.IsIn,
|
|
890
|
+
parse_tree.Index,
|
|
891
|
+
parse_tree.All,
|
|
892
|
+
parse_tree.Any,
|
|
893
|
+
)
|
|
894
|
+
if not isinstance(node.operand, no_parentheses_types_in_this_context):
|
|
895
|
+
return Stripped(f"!({operand})"), None
|
|
896
|
+
else:
|
|
897
|
+
return Stripped(f"!{operand}"), None
|
|
898
|
+
|
|
899
|
+
def _transform_and_or_or(
|
|
900
|
+
self, node: Union[parse_tree.And, parse_tree.Or]
|
|
901
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
902
|
+
errors = [] # type: List[Error]
|
|
903
|
+
values = [] # type: List[Stripped]
|
|
904
|
+
|
|
905
|
+
for value_node in node.values:
|
|
906
|
+
value, error = self._transform_and_value_if_necessary(value_node)
|
|
907
|
+
if error is not None:
|
|
908
|
+
errors.append(error)
|
|
909
|
+
continue
|
|
910
|
+
|
|
911
|
+
assert value is not None
|
|
912
|
+
|
|
913
|
+
no_parentheses_types_in_this_context = (
|
|
914
|
+
parse_tree.Member,
|
|
915
|
+
parse_tree.FunctionCall,
|
|
916
|
+
parse_tree.MethodCall,
|
|
917
|
+
parse_tree.Name,
|
|
918
|
+
parse_tree.IsIn,
|
|
919
|
+
parse_tree.Index,
|
|
920
|
+
parse_tree.All,
|
|
921
|
+
parse_tree.Any,
|
|
922
|
+
parse_tree.Comparison,
|
|
923
|
+
)
|
|
924
|
+
|
|
925
|
+
if not isinstance(value_node, no_parentheses_types_in_this_context):
|
|
926
|
+
# NOTE (mristin, 2023-06-30):
|
|
927
|
+
# This is a very rudimentary heuristic for breaking the lines, and can
|
|
928
|
+
# be greatly improved by rendering into C++ code. However, at this
|
|
929
|
+
# point, we lack time for more sophisticated reformatting approaches.
|
|
930
|
+
if "\n" in value:
|
|
931
|
+
value = Stripped(
|
|
932
|
+
f"""\
|
|
933
|
+
(
|
|
934
|
+
{I}{indent_but_first_line(value, I)}
|
|
935
|
+
)"""
|
|
936
|
+
)
|
|
937
|
+
else:
|
|
938
|
+
value = Stripped(f"({value})")
|
|
939
|
+
|
|
940
|
+
values.append(value)
|
|
941
|
+
|
|
942
|
+
if len(errors) > 0:
|
|
943
|
+
if isinstance(node, parse_tree.And):
|
|
944
|
+
return None, Error(
|
|
945
|
+
node.original_node, "Failed to transpile the conjunction", errors
|
|
946
|
+
)
|
|
947
|
+
elif isinstance(node, parse_tree.Or):
|
|
948
|
+
return None, Error(
|
|
949
|
+
node.original_node, "Failed to transpile the disjunction", errors
|
|
950
|
+
)
|
|
951
|
+
else:
|
|
952
|
+
assert_never(node)
|
|
953
|
+
|
|
954
|
+
assert len(values) >= 1
|
|
955
|
+
if len(values) == 1:
|
|
956
|
+
return Stripped(values[0]), None
|
|
957
|
+
|
|
958
|
+
writer = io.StringIO()
|
|
959
|
+
writer.write("(\n")
|
|
960
|
+
for i, value in enumerate(values):
|
|
961
|
+
if i == 0:
|
|
962
|
+
writer.write(f"{I}{indent_but_first_line(value, I)}\n")
|
|
963
|
+
else:
|
|
964
|
+
if isinstance(node, parse_tree.And):
|
|
965
|
+
writer.write(f"{I}&& {indent_but_first_line(value, I)}\n")
|
|
966
|
+
elif isinstance(node, parse_tree.Or):
|
|
967
|
+
writer.write(f"{I}|| {indent_but_first_line(value, I)}\n")
|
|
968
|
+
else:
|
|
969
|
+
assert_never(node)
|
|
970
|
+
|
|
971
|
+
writer.write(")")
|
|
972
|
+
|
|
973
|
+
return Stripped(writer.getvalue()), None
|
|
974
|
+
|
|
975
|
+
def transform_and(
|
|
976
|
+
self, node: parse_tree.And
|
|
977
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
978
|
+
return self._transform_and_or_or(node)
|
|
979
|
+
|
|
980
|
+
def transform_or(
|
|
981
|
+
self, node: parse_tree.Or
|
|
982
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
983
|
+
return self._transform_and_or_or(node)
|
|
984
|
+
|
|
985
|
+
def _transform_add_or_sub(
|
|
986
|
+
self, node: Union[parse_tree.Add, parse_tree.Sub]
|
|
987
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
988
|
+
errors = [] # type: List[Error]
|
|
989
|
+
|
|
990
|
+
left, error = self._transform_and_value_if_necessary(node.left)
|
|
991
|
+
if error is not None:
|
|
992
|
+
errors.append(error)
|
|
993
|
+
|
|
994
|
+
right, error = self._transform_and_value_if_necessary(node.right)
|
|
995
|
+
if error is not None:
|
|
996
|
+
errors.append(error)
|
|
997
|
+
|
|
998
|
+
if len(errors) > 0:
|
|
999
|
+
operation_name: str
|
|
1000
|
+
if isinstance(node, parse_tree.Add):
|
|
1001
|
+
operation_name = "the addition"
|
|
1002
|
+
elif isinstance(node, parse_tree.Sub):
|
|
1003
|
+
operation_name = "the subtraction"
|
|
1004
|
+
else:
|
|
1005
|
+
assert_never(node)
|
|
1006
|
+
|
|
1007
|
+
return None, Error(
|
|
1008
|
+
node.original_node, f"Failed to transpile {operation_name}", errors
|
|
1009
|
+
)
|
|
1010
|
+
|
|
1011
|
+
no_parentheses_types_in_this_context = (
|
|
1012
|
+
parse_tree.Member,
|
|
1013
|
+
parse_tree.FunctionCall,
|
|
1014
|
+
parse_tree.MethodCall,
|
|
1015
|
+
parse_tree.Name,
|
|
1016
|
+
parse_tree.IsIn,
|
|
1017
|
+
parse_tree.Index,
|
|
1018
|
+
parse_tree.All,
|
|
1019
|
+
parse_tree.Any,
|
|
1020
|
+
)
|
|
1021
|
+
|
|
1022
|
+
if not isinstance(node.left, no_parentheses_types_in_this_context):
|
|
1023
|
+
left = Stripped(f"({left})")
|
|
1024
|
+
|
|
1025
|
+
if not isinstance(node.right, no_parentheses_types_in_this_context):
|
|
1026
|
+
right = Stripped(f"({right})")
|
|
1027
|
+
|
|
1028
|
+
if isinstance(node, parse_tree.Add):
|
|
1029
|
+
return Stripped(f"{left} + {right}"), None
|
|
1030
|
+
elif isinstance(node, parse_tree.Sub):
|
|
1031
|
+
return Stripped(f"{left} - {right}"), None
|
|
1032
|
+
else:
|
|
1033
|
+
assert_never(node)
|
|
1034
|
+
|
|
1035
|
+
def transform_add(
|
|
1036
|
+
self, node: parse_tree.Add
|
|
1037
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1038
|
+
return self._transform_add_or_sub(node)
|
|
1039
|
+
|
|
1040
|
+
def transform_sub(
|
|
1041
|
+
self, node: parse_tree.Sub
|
|
1042
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1043
|
+
return self._transform_add_or_sub(node)
|
|
1044
|
+
|
|
1045
|
+
def transform_joined_str(
|
|
1046
|
+
self, node: parse_tree.JoinedStr
|
|
1047
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1048
|
+
if all(isinstance(value, str) for value in node.values):
|
|
1049
|
+
text = "".join(node.values) # type: ignore
|
|
1050
|
+
return cpp_common.wstring_literal(text), None
|
|
1051
|
+
|
|
1052
|
+
# NOTE (mristin, 2023-06-30):
|
|
1053
|
+
# We need the interpolation if we got so far.
|
|
1054
|
+
|
|
1055
|
+
args = [] # type: List[str]
|
|
1056
|
+
|
|
1057
|
+
for value in node.values:
|
|
1058
|
+
if isinstance(value, str):
|
|
1059
|
+
args.append(cpp_common.wstring_literal(value))
|
|
1060
|
+
|
|
1061
|
+
elif isinstance(value, parse_tree.FormattedValue):
|
|
1062
|
+
code, error = self._transform_and_value_if_necessary(value.value)
|
|
1063
|
+
if error is not None:
|
|
1064
|
+
return None, error
|
|
1065
|
+
|
|
1066
|
+
assert code is not None
|
|
1067
|
+
|
|
1068
|
+
value_type = self.type_map[value.value]
|
|
1069
|
+
|
|
1070
|
+
if not isinstance(
|
|
1071
|
+
value_type, intermediate_type_inference.PrimitiveTypeAnnotation
|
|
1072
|
+
) and not (
|
|
1073
|
+
isinstance(
|
|
1074
|
+
value_type, intermediate_type_inference.OurTypeAnnotation
|
|
1075
|
+
)
|
|
1076
|
+
and isinstance(
|
|
1077
|
+
value_type.our_type, intermediate.ConstrainedPrimitive
|
|
1078
|
+
)
|
|
1079
|
+
):
|
|
1080
|
+
return None, Error(
|
|
1081
|
+
value.original_node,
|
|
1082
|
+
f"Unexpected non-primitive formatted value type: {value_type}",
|
|
1083
|
+
)
|
|
1084
|
+
|
|
1085
|
+
to_wstring = _determine_which_to_wstring(value_type)
|
|
1086
|
+
|
|
1087
|
+
if to_wstring is None:
|
|
1088
|
+
args.append(code)
|
|
1089
|
+
else:
|
|
1090
|
+
if "\n" in code:
|
|
1091
|
+
args.append(
|
|
1092
|
+
f"""\
|
|
1093
|
+
{to_wstring}(
|
|
1094
|
+
{I}{indent_but_first_line(code, I)}
|
|
1095
|
+
)"""
|
|
1096
|
+
)
|
|
1097
|
+
else:
|
|
1098
|
+
args.append(f"{to_wstring}({code})")
|
|
1099
|
+
|
|
1100
|
+
args_joined = ",\n".join(args)
|
|
1101
|
+
|
|
1102
|
+
concat = cpp_naming.function_name(Identifier("concat"))
|
|
1103
|
+
return (
|
|
1104
|
+
Stripped(
|
|
1105
|
+
f"""\
|
|
1106
|
+
common::{concat}(
|
|
1107
|
+
{I}{indent_but_first_line(args_joined, I)}
|
|
1108
|
+
)"""
|
|
1109
|
+
),
|
|
1110
|
+
None,
|
|
1111
|
+
)
|
|
1112
|
+
|
|
1113
|
+
def _transform_any_or_all(
|
|
1114
|
+
self, node: Union[parse_tree.Any, parse_tree.All]
|
|
1115
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1116
|
+
errors = [] # type: List[Error]
|
|
1117
|
+
|
|
1118
|
+
iteration = None # type: Optional[Stripped]
|
|
1119
|
+
start = None # type: Optional[Stripped]
|
|
1120
|
+
end = None # type: Optional[Stripped]
|
|
1121
|
+
|
|
1122
|
+
if isinstance(node.generator, parse_tree.ForEach):
|
|
1123
|
+
iteration, error = self._transform_and_value_if_necessary(
|
|
1124
|
+
node.generator.iteration
|
|
1125
|
+
)
|
|
1126
|
+
if error is not None:
|
|
1127
|
+
errors.append(error)
|
|
1128
|
+
|
|
1129
|
+
elif isinstance(node.generator, parse_tree.ForRange):
|
|
1130
|
+
start, error = self._transform_and_value_if_necessary(node.generator.start)
|
|
1131
|
+
if error is not None:
|
|
1132
|
+
errors.append(error)
|
|
1133
|
+
|
|
1134
|
+
end, error = self._transform_and_value_if_necessary(node.generator.end)
|
|
1135
|
+
if error is not None:
|
|
1136
|
+
errors.append(error)
|
|
1137
|
+
|
|
1138
|
+
else:
|
|
1139
|
+
assert_never(node.generator)
|
|
1140
|
+
|
|
1141
|
+
variable_name = node.generator.variable.identifier
|
|
1142
|
+
variable_type_annotation = self.type_map[node.generator.variable]
|
|
1143
|
+
|
|
1144
|
+
variable_name_cpp = cpp_naming.variable_name(variable_name)
|
|
1145
|
+
variable_type_cpp, error_msg = generate_type_with_const_ref_if_applicable(
|
|
1146
|
+
type_annotation=variable_type_annotation,
|
|
1147
|
+
types_namespace=self._types_namespace,
|
|
1148
|
+
)
|
|
1149
|
+
if error_msg is not None:
|
|
1150
|
+
errors.append(Error(node.generator.variable.original_node, error_msg))
|
|
1151
|
+
|
|
1152
|
+
try:
|
|
1153
|
+
self._environment.set(
|
|
1154
|
+
identifier=variable_name, type_annotation=variable_type_annotation
|
|
1155
|
+
)
|
|
1156
|
+
self._variable_name_set.add(variable_name)
|
|
1157
|
+
|
|
1158
|
+
condition, error = self._transform_and_value_if_necessary(node.condition)
|
|
1159
|
+
if error is not None:
|
|
1160
|
+
errors.append(error)
|
|
1161
|
+
|
|
1162
|
+
variable, error = self._transform_and_value_if_necessary(
|
|
1163
|
+
node.generator.variable
|
|
1164
|
+
)
|
|
1165
|
+
if error is not None:
|
|
1166
|
+
errors.append(error)
|
|
1167
|
+
|
|
1168
|
+
finally:
|
|
1169
|
+
self._variable_name_set.remove(variable_name)
|
|
1170
|
+
self._environment.remove(variable_name)
|
|
1171
|
+
|
|
1172
|
+
if len(errors) > 0:
|
|
1173
|
+
return None, Error(
|
|
1174
|
+
node.original_node,
|
|
1175
|
+
"Failed to transpile the generator expression",
|
|
1176
|
+
errors,
|
|
1177
|
+
)
|
|
1178
|
+
|
|
1179
|
+
assert (iteration is not None) ^ (start is not None and end is not None)
|
|
1180
|
+
|
|
1181
|
+
assert variable is not None
|
|
1182
|
+
assert condition is not None
|
|
1183
|
+
|
|
1184
|
+
if isinstance(node.generator, parse_tree.ForEach):
|
|
1185
|
+
assert iteration is not None
|
|
1186
|
+
|
|
1187
|
+
qualifier_function: str
|
|
1188
|
+
if isinstance(node, parse_tree.Any):
|
|
1189
|
+
qualifier_function = cpp_naming.function_name(Identifier("Some"))
|
|
1190
|
+
elif isinstance(node, parse_tree.All):
|
|
1191
|
+
qualifier_function = cpp_naming.function_name(Identifier("All"))
|
|
1192
|
+
else:
|
|
1193
|
+
assert_never(node)
|
|
1194
|
+
|
|
1195
|
+
no_parentheses_types_in_this_context = (
|
|
1196
|
+
parse_tree.Member,
|
|
1197
|
+
parse_tree.MethodCall,
|
|
1198
|
+
parse_tree.FunctionCall,
|
|
1199
|
+
parse_tree.Name,
|
|
1200
|
+
parse_tree.IsIn,
|
|
1201
|
+
parse_tree.Index,
|
|
1202
|
+
parse_tree.All,
|
|
1203
|
+
parse_tree.Any,
|
|
1204
|
+
)
|
|
1205
|
+
|
|
1206
|
+
if not isinstance(
|
|
1207
|
+
node.generator.iteration, no_parentheses_types_in_this_context
|
|
1208
|
+
):
|
|
1209
|
+
source = Stripped(f"({iteration})")
|
|
1210
|
+
else:
|
|
1211
|
+
source = iteration
|
|
1212
|
+
|
|
1213
|
+
# NOTE (mristin, 2023-07-01):
|
|
1214
|
+
# We implicitly capture all the variables by reference,
|
|
1215
|
+
# see: https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture.
|
|
1216
|
+
|
|
1217
|
+
return (
|
|
1218
|
+
Stripped(
|
|
1219
|
+
f"""\
|
|
1220
|
+
common::{qualifier_function}(
|
|
1221
|
+
{I}[&]({variable_type_cpp} {variable_name_cpp}) -> bool {{
|
|
1222
|
+
{II}return {indent_but_first_line(condition, II)};
|
|
1223
|
+
{I}}},
|
|
1224
|
+
{I}{indent_but_first_line(source, I)}
|
|
1225
|
+
)"""
|
|
1226
|
+
),
|
|
1227
|
+
None,
|
|
1228
|
+
)
|
|
1229
|
+
|
|
1230
|
+
elif isinstance(node.generator, parse_tree.ForRange):
|
|
1231
|
+
if isinstance(node, parse_tree.Any):
|
|
1232
|
+
qualifier_function = "SomeRange"
|
|
1233
|
+
elif isinstance(node, parse_tree.All):
|
|
1234
|
+
qualifier_function = "AllRange"
|
|
1235
|
+
else:
|
|
1236
|
+
assert_never(node)
|
|
1237
|
+
|
|
1238
|
+
assert start is not None
|
|
1239
|
+
assert end is not None
|
|
1240
|
+
|
|
1241
|
+
return (
|
|
1242
|
+
Stripped(
|
|
1243
|
+
f"""\
|
|
1244
|
+
common::{qualifier_function}(
|
|
1245
|
+
{I}[&]({variable_type_cpp} {variable_name_cpp}) -> bool {{
|
|
1246
|
+
{II}return {indent_but_first_line(condition, II)};
|
|
1247
|
+
{I}}},
|
|
1248
|
+
{I}{indent_but_first_line(start, I)},
|
|
1249
|
+
{I}{indent_but_first_line(end, I)}
|
|
1250
|
+
)"""
|
|
1251
|
+
),
|
|
1252
|
+
None,
|
|
1253
|
+
)
|
|
1254
|
+
|
|
1255
|
+
else:
|
|
1256
|
+
assert_never(node.generator)
|
|
1257
|
+
|
|
1258
|
+
def transform_any(
|
|
1259
|
+
self, node: parse_tree.Any
|
|
1260
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1261
|
+
return self._transform_any_or_all(node)
|
|
1262
|
+
|
|
1263
|
+
def transform_all(
|
|
1264
|
+
self, node: parse_tree.All
|
|
1265
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1266
|
+
return self._transform_any_or_all(node)
|
|
1267
|
+
|
|
1268
|
+
def transform_assignment(
|
|
1269
|
+
self, node: parse_tree.Assignment
|
|
1270
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1271
|
+
errors = [] # type: List[Error]
|
|
1272
|
+
|
|
1273
|
+
value_type = self.type_map[node.value]
|
|
1274
|
+
|
|
1275
|
+
is_definition = False
|
|
1276
|
+
|
|
1277
|
+
target = None # type: Optional[Stripped]
|
|
1278
|
+
if isinstance(node.target, parse_tree.Name):
|
|
1279
|
+
target_type = self._environment.find(identifier=node.target.identifier)
|
|
1280
|
+
if target_type is None:
|
|
1281
|
+
# NOTE (mristin, 2023-07-01):
|
|
1282
|
+
# This is a variable definition as we did not specify the identifier
|
|
1283
|
+
# in the environment.
|
|
1284
|
+
|
|
1285
|
+
is_definition = True
|
|
1286
|
+
|
|
1287
|
+
target_type = value_type
|
|
1288
|
+
self._variable_name_set.add(node.target.identifier)
|
|
1289
|
+
self._environment.set(
|
|
1290
|
+
identifier=node.target.identifier, type_annotation=target_type
|
|
1291
|
+
)
|
|
1292
|
+
|
|
1293
|
+
target, error = self.transform_name(node=node.target)
|
|
1294
|
+
if error is not None:
|
|
1295
|
+
errors.append(error)
|
|
1296
|
+
else:
|
|
1297
|
+
target, error = self.transform(node=node.target)
|
|
1298
|
+
if error is not None:
|
|
1299
|
+
errors.append(error)
|
|
1300
|
+
else:
|
|
1301
|
+
target_type = self.type_map[node.target]
|
|
1302
|
+
|
|
1303
|
+
if len(errors) > 0:
|
|
1304
|
+
return None, Error(
|
|
1305
|
+
node.original_node, "Failed to transpile the assignment", errors
|
|
1306
|
+
)
|
|
1307
|
+
|
|
1308
|
+
assert target is not None
|
|
1309
|
+
assert target_type is not None
|
|
1310
|
+
|
|
1311
|
+
value: Optional[Stripped]
|
|
1312
|
+
|
|
1313
|
+
if isinstance(
|
|
1314
|
+
target_type, intermediate_type_inference.OptionalTypeAnnotation
|
|
1315
|
+
) and isinstance(
|
|
1316
|
+
value_type, intermediate_type_inference.OptionalTypeAnnotation
|
|
1317
|
+
):
|
|
1318
|
+
value, error = self.transform(node.value)
|
|
1319
|
+
elif not isinstance(
|
|
1320
|
+
target_type, intermediate_type_inference.OptionalTypeAnnotation
|
|
1321
|
+
) and isinstance(
|
|
1322
|
+
value_type, intermediate_type_inference.OptionalTypeAnnotation
|
|
1323
|
+
):
|
|
1324
|
+
value, error = self._transform_and_value_if_necessary(node.value)
|
|
1325
|
+
else:
|
|
1326
|
+
# NOTE (mristin, 2023-07-01):
|
|
1327
|
+
# This is the case covering (target non-optional, value non-optional) and
|
|
1328
|
+
# (target optional, value non-optional).
|
|
1329
|
+
value, error = self.transform(node.value)
|
|
1330
|
+
|
|
1331
|
+
if error is not None:
|
|
1332
|
+
return None, error
|
|
1333
|
+
assert value is not None
|
|
1334
|
+
|
|
1335
|
+
maybe_definition_prefix = "" if not is_definition else "auto "
|
|
1336
|
+
|
|
1337
|
+
# NOTE (mristin, 2022-07-12):
|
|
1338
|
+
# This is a rudimentary heuristic for basic line breaks, but works well in
|
|
1339
|
+
# practice.
|
|
1340
|
+
if "\n" in value or len(value) > 50:
|
|
1341
|
+
return (
|
|
1342
|
+
Stripped(
|
|
1343
|
+
f"""\
|
|
1344
|
+
{maybe_definition_prefix}{target} = (
|
|
1345
|
+
{I}{indent_but_first_line(value, I)}
|
|
1346
|
+
);"""
|
|
1347
|
+
),
|
|
1348
|
+
None,
|
|
1349
|
+
)
|
|
1350
|
+
|
|
1351
|
+
return Stripped(f"{maybe_definition_prefix}{target} = {value};"), None
|
|
1352
|
+
|
|
1353
|
+
def transform_return(
|
|
1354
|
+
self, node: parse_tree.Return
|
|
1355
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
1356
|
+
if node.value is None:
|
|
1357
|
+
return Stripped("return;"), None
|
|
1358
|
+
|
|
1359
|
+
value, error = self.transform(node.value)
|
|
1360
|
+
if error is not None:
|
|
1361
|
+
return None, error
|
|
1362
|
+
|
|
1363
|
+
assert value is not None
|
|
1364
|
+
|
|
1365
|
+
# NOTE (mristin, 2023-06-30):
|
|
1366
|
+
# This is a rudimentary heuristic for basic line breaks, but works well in
|
|
1367
|
+
# practice.
|
|
1368
|
+
if "\n" in value or len(value) > 50:
|
|
1369
|
+
return (
|
|
1370
|
+
Stripped(
|
|
1371
|
+
f"""\
|
|
1372
|
+
return (
|
|
1373
|
+
{I}{indent_but_first_line(value, I)}
|
|
1374
|
+
);"""
|
|
1375
|
+
),
|
|
1376
|
+
None,
|
|
1377
|
+
)
|
|
1378
|
+
|
|
1379
|
+
return Stripped(f"return {value};"), None
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
# noinspection PyProtectedMember,PyProtectedMember
|
|
1383
|
+
assert all(op in Transpiler._CPP_COMPARISON_MAP for op in parse_tree.Comparator)
|