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,1513 @@
|
|
|
1
|
+
"""Generate the invariant verifiers from the intermediate representation."""
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
import textwrap
|
|
5
|
+
from typing import (
|
|
6
|
+
Tuple,
|
|
7
|
+
Optional,
|
|
8
|
+
List,
|
|
9
|
+
Sequence,
|
|
10
|
+
Mapping,
|
|
11
|
+
Union,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from icontract import ensure, require
|
|
15
|
+
|
|
16
|
+
from aas_core_codegen import intermediate, specific_implementations
|
|
17
|
+
from aas_core_codegen.common import (
|
|
18
|
+
Error,
|
|
19
|
+
Stripped,
|
|
20
|
+
assert_never,
|
|
21
|
+
Identifier,
|
|
22
|
+
indent_but_first_line,
|
|
23
|
+
wrap_text_into_lines,
|
|
24
|
+
assert_union_without_excluded,
|
|
25
|
+
)
|
|
26
|
+
from aas_core_codegen.intermediate import type_inference as intermediate_type_inference
|
|
27
|
+
from aas_core_codegen.parse import tree as parse_tree, retree as parse_retree
|
|
28
|
+
from aas_core_codegen.golang import (
|
|
29
|
+
common as golang_common,
|
|
30
|
+
naming as golang_naming,
|
|
31
|
+
description as golang_description,
|
|
32
|
+
pointering as golang_pointering,
|
|
33
|
+
transpilation as golang_transpilation,
|
|
34
|
+
)
|
|
35
|
+
from aas_core_codegen.golang.common import (
|
|
36
|
+
INDENT as I,
|
|
37
|
+
INDENT2 as II,
|
|
38
|
+
INDENT3 as III,
|
|
39
|
+
INDENT4 as IIII,
|
|
40
|
+
INDENT5 as IIIII,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# region Verify
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def verify(
|
|
48
|
+
spec_impls: specific_implementations.SpecificImplementations,
|
|
49
|
+
verification_functions: Sequence[intermediate.Verification],
|
|
50
|
+
) -> Optional[List[str]]:
|
|
51
|
+
"""Verify all the implementation snippets related to verification."""
|
|
52
|
+
errors = [] # type: List[str]
|
|
53
|
+
|
|
54
|
+
expected_keys = [] # type: List[specific_implementations.ImplementationKey]
|
|
55
|
+
|
|
56
|
+
for func in verification_functions:
|
|
57
|
+
if isinstance(func, intermediate.ImplementationSpecificVerification):
|
|
58
|
+
expected_keys.append(
|
|
59
|
+
specific_implementations.ImplementationKey(
|
|
60
|
+
f"Verification/{func.name}.go"
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
for key in expected_keys:
|
|
65
|
+
if key not in spec_impls:
|
|
66
|
+
errors.append(f"The implementation snippet is missing for: {key}")
|
|
67
|
+
|
|
68
|
+
if len(errors) == 0:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
return errors
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# endregion
|
|
75
|
+
|
|
76
|
+
# region Generate
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class RegexRenderer(parse_retree.Renderer):
|
|
80
|
+
"""
|
|
81
|
+
Render the regular expressions for Go.
|
|
82
|
+
|
|
83
|
+
Notably, do not escape character points, but leave them as-are, since that is
|
|
84
|
+
what Go regular expression engine expects.
|
|
85
|
+
|
|
86
|
+
For example:
|
|
87
|
+
|
|
88
|
+
.. code-block ::
|
|
89
|
+
|
|
90
|
+
package main
|
|
91
|
+
|
|
92
|
+
import (
|
|
93
|
+
"fmt"
|
|
94
|
+
"regexp"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
func main() {
|
|
98
|
+
re := regexp.MustCompile(
|
|
99
|
+
"^[\x09\x0a\x0d\x20-\ud7ff\ue000-\ufffd\U00010000-\U0010ffff]*$",
|
|
100
|
+
)
|
|
101
|
+
text := "\U0001F600"
|
|
102
|
+
fmt.Printf("%v", re.MatchString(text))
|
|
103
|
+
// Prints "true"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
def char_to_str_and_escape_or_encode_if_necessary(
|
|
109
|
+
self, node: parse_retree.Char, escaping: Mapping[str, str]
|
|
110
|
+
) -> List[Union[str, parse_tree.FormattedValue]]:
|
|
111
|
+
if not node.explicitly_encoded:
|
|
112
|
+
escaped = escaping.get(node.character, None)
|
|
113
|
+
if escaped is not None:
|
|
114
|
+
result: List[Union[str, parse_tree.FormattedValue]] = [escaped]
|
|
115
|
+
else:
|
|
116
|
+
result = [node.character]
|
|
117
|
+
|
|
118
|
+
return result
|
|
119
|
+
|
|
120
|
+
return [node.character]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
_REGEX_RENDERER = RegexRenderer()
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class _PatternVerificationTranspiler(
|
|
127
|
+
parse_tree.RestrictedTransformer[Tuple[Optional[Stripped], Optional[Error]]]
|
|
128
|
+
):
|
|
129
|
+
"""Transpile a statement of a pattern verification into Golang."""
|
|
130
|
+
|
|
131
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
132
|
+
def _transform_joined_str_values(
|
|
133
|
+
self, values: Sequence[Union[str, parse_tree.FormattedValue]]
|
|
134
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
135
|
+
"""Transform the values of a joined string to a Golang string literal."""
|
|
136
|
+
# If we do not need interpolation, simply return the string literals
|
|
137
|
+
# joined together.
|
|
138
|
+
needs_interpolation = any(
|
|
139
|
+
isinstance(value, parse_tree.FormattedValue) for value in values
|
|
140
|
+
)
|
|
141
|
+
if not needs_interpolation:
|
|
142
|
+
return (
|
|
143
|
+
Stripped(
|
|
144
|
+
golang_common.string_literal(
|
|
145
|
+
"".join(value for value in values) # type: ignore
|
|
146
|
+
)
|
|
147
|
+
),
|
|
148
|
+
None,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
parts = [] # type: List[str]
|
|
152
|
+
|
|
153
|
+
for value in values:
|
|
154
|
+
if isinstance(value, str):
|
|
155
|
+
parts.append(golang_common.string_literal(value))
|
|
156
|
+
|
|
157
|
+
elif isinstance(value, parse_tree.FormattedValue):
|
|
158
|
+
code, error = self.transform(value.value)
|
|
159
|
+
if error is not None:
|
|
160
|
+
return None, error
|
|
161
|
+
|
|
162
|
+
assert code is not None
|
|
163
|
+
|
|
164
|
+
parts.append(code)
|
|
165
|
+
else:
|
|
166
|
+
assert_never(value)
|
|
167
|
+
|
|
168
|
+
if len(parts) > 1:
|
|
169
|
+
parts_joined = "\n".join(f"{part}," for part in parts)
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
Stripped(
|
|
173
|
+
f"""\
|
|
174
|
+
aascommon.Concat(
|
|
175
|
+
{I}{indent_but_first_line(parts_joined, I)}
|
|
176
|
+
)"""
|
|
177
|
+
),
|
|
178
|
+
None,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
assert len(parts) == 1, "At least one part expected in the formatted string"
|
|
182
|
+
return Stripped(parts[0]), None
|
|
183
|
+
|
|
184
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
185
|
+
def transform_constant(
|
|
186
|
+
self, node: parse_tree.Constant
|
|
187
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
188
|
+
if isinstance(node.value, str):
|
|
189
|
+
# NOTE (mristin, 2023-04-12):
|
|
190
|
+
# We assume that all the string constants are valid regular expressions.
|
|
191
|
+
# At this point, we could not find any difference between Golang and
|
|
192
|
+
# Python regex languages which are relevant to the features we currently
|
|
193
|
+
# support.
|
|
194
|
+
|
|
195
|
+
regex, parse_error = parse_retree.parse(values=[node.value])
|
|
196
|
+
if parse_error is not None:
|
|
197
|
+
regex_line, pointer_line = parse_retree.render_pointer(
|
|
198
|
+
parse_error.cursor
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
None,
|
|
203
|
+
Error(
|
|
204
|
+
node.original_node,
|
|
205
|
+
f"The string constant could not be parsed "
|
|
206
|
+
f"as a regular expression: \n"
|
|
207
|
+
f"{parse_error.message}\n"
|
|
208
|
+
f"{regex_line}\n"
|
|
209
|
+
f"{pointer_line}",
|
|
210
|
+
),
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
assert regex is not None
|
|
214
|
+
|
|
215
|
+
# NOTE (mristin, 2022-11-04):
|
|
216
|
+
# Strictly speaking, this is a joined string with a single value, a string
|
|
217
|
+
# literal. Thus, do not be confused by the name of the function —
|
|
218
|
+
# this function treats both joined formatted values *and* string literals.
|
|
219
|
+
return self._transform_joined_str_values(
|
|
220
|
+
values=parse_retree.render(regex=regex, renderer=_REGEX_RENDERER)
|
|
221
|
+
)
|
|
222
|
+
else:
|
|
223
|
+
raise AssertionError(f"Unexpected {node=}")
|
|
224
|
+
|
|
225
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
226
|
+
def transform_name(
|
|
227
|
+
self, node: parse_tree.Name
|
|
228
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
229
|
+
return Stripped(golang_naming.variable_name(node.identifier)), None
|
|
230
|
+
|
|
231
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
232
|
+
def transform_joined_str(
|
|
233
|
+
self, node: parse_tree.JoinedStr
|
|
234
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
235
|
+
regex, parse_error = parse_retree.parse(values=node.values)
|
|
236
|
+
if parse_error is not None:
|
|
237
|
+
regex_line, pointer_line = parse_retree.render_pointer(parse_error.cursor)
|
|
238
|
+
|
|
239
|
+
return (
|
|
240
|
+
None,
|
|
241
|
+
Error(
|
|
242
|
+
node.original_node,
|
|
243
|
+
f"The joined string could not be parsed "
|
|
244
|
+
f"as a regular expression: \n"
|
|
245
|
+
f"{parse_error.message}\n"
|
|
246
|
+
f"{regex_line}\n"
|
|
247
|
+
f"{pointer_line}",
|
|
248
|
+
),
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
assert regex is not None
|
|
252
|
+
|
|
253
|
+
return self._transform_joined_str_values(
|
|
254
|
+
values=parse_retree.render(regex=regex)
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
def transform_assignment(
|
|
258
|
+
self, node: parse_tree.Assignment
|
|
259
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
260
|
+
assert isinstance(node.target, parse_tree.Name)
|
|
261
|
+
variable = golang_naming.variable_name(node.target.identifier)
|
|
262
|
+
code, error = self.transform(node.value)
|
|
263
|
+
if error is not None:
|
|
264
|
+
return None, error
|
|
265
|
+
assert code is not None
|
|
266
|
+
|
|
267
|
+
# NOTE (mristin, 2023-04-12):
|
|
268
|
+
# We assume that the variables won't change in the patterns. If this assumption
|
|
269
|
+
# is broken, fix the code here by first inspecting the scope and deciding
|
|
270
|
+
# which variables need to be first defined and which have been already
|
|
271
|
+
# defined.
|
|
272
|
+
return Stripped(f"{variable} := {code}"), None
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
276
|
+
def _transpile_pattern_verification(
|
|
277
|
+
verification: intermediate.PatternVerification,
|
|
278
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
279
|
+
"""Generate the verification function that checks the regular expressions."""
|
|
280
|
+
# NOTE (mristin, 2022-11-12):
|
|
281
|
+
# We assume that we performed all the checks at the intermediate stage.
|
|
282
|
+
|
|
283
|
+
construct_name = golang_naming.private_function_name(
|
|
284
|
+
Identifier(f"construct_{verification.name}")
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
blocks = [] # type: List[Stripped]
|
|
288
|
+
|
|
289
|
+
# region Construct block
|
|
290
|
+
|
|
291
|
+
writer = io.StringIO()
|
|
292
|
+
writer.write(
|
|
293
|
+
f"""\
|
|
294
|
+
func {construct_name}() *regexp.Regexp {{
|
|
295
|
+
"""
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
transpiler = _PatternVerificationTranspiler()
|
|
299
|
+
|
|
300
|
+
for i, stmt in enumerate(verification.parsed.body):
|
|
301
|
+
if i == len(verification.parsed.body) - 1:
|
|
302
|
+
break
|
|
303
|
+
|
|
304
|
+
code, error = transpiler.transform(stmt)
|
|
305
|
+
if error is not None:
|
|
306
|
+
return None, error
|
|
307
|
+
assert code is not None
|
|
308
|
+
|
|
309
|
+
writer.write(textwrap.indent(code, I))
|
|
310
|
+
writer.write("\n")
|
|
311
|
+
|
|
312
|
+
if len(verification.parsed.body) >= 2:
|
|
313
|
+
writer.write("\n")
|
|
314
|
+
|
|
315
|
+
pattern_expr, error = transpiler.transform(verification.pattern_expr)
|
|
316
|
+
if error is not None:
|
|
317
|
+
return None, error
|
|
318
|
+
assert pattern_expr is not None
|
|
319
|
+
|
|
320
|
+
writer.write(
|
|
321
|
+
textwrap.indent(
|
|
322
|
+
f"""\
|
|
323
|
+
return regexp.MustCompile(
|
|
324
|
+
{I}{pattern_expr},
|
|
325
|
+
)""",
|
|
326
|
+
I,
|
|
327
|
+
)
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
writer.write("\n}")
|
|
331
|
+
|
|
332
|
+
blocks.append(Stripped(writer.getvalue()))
|
|
333
|
+
|
|
334
|
+
# endregion
|
|
335
|
+
|
|
336
|
+
# region Initialize the regex
|
|
337
|
+
|
|
338
|
+
regex_name = golang_naming.private_constant_name(
|
|
339
|
+
Identifier(f"{verification.name}_re")
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
blocks.append(Stripped(f"var {regex_name} = {construct_name}()"))
|
|
343
|
+
|
|
344
|
+
# endregion
|
|
345
|
+
|
|
346
|
+
# region Define the verification function
|
|
347
|
+
|
|
348
|
+
assert len(verification.arguments) == 1
|
|
349
|
+
assert isinstance(
|
|
350
|
+
verification.arguments[0].type_annotation, intermediate.PrimitiveTypeAnnotation
|
|
351
|
+
)
|
|
352
|
+
# noinspection PyUnresolvedReferences
|
|
353
|
+
assert (
|
|
354
|
+
verification.arguments[0].type_annotation.a_type
|
|
355
|
+
== intermediate.PrimitiveType.STR
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
arg_name = golang_naming.argument_name(verification.arguments[0].name)
|
|
359
|
+
|
|
360
|
+
function_name = golang_naming.function_name(verification.name)
|
|
361
|
+
|
|
362
|
+
writer = io.StringIO()
|
|
363
|
+
|
|
364
|
+
if verification.description is not None:
|
|
365
|
+
(comment, comment_errors,) = golang_description.generate_comment_for_signature(
|
|
366
|
+
description=verification.description,
|
|
367
|
+
context=golang_description.Context(
|
|
368
|
+
package=golang_common.VERIFICATION_PACKAGE, cls_or_enum=None
|
|
369
|
+
),
|
|
370
|
+
)
|
|
371
|
+
if comment_errors is not None:
|
|
372
|
+
return None, Error(
|
|
373
|
+
verification.description.parsed.node,
|
|
374
|
+
f"Failed to generate the documentation comment for {verification.name!r}",
|
|
375
|
+
comment_errors,
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
assert comment is not None
|
|
379
|
+
|
|
380
|
+
writer.write(comment)
|
|
381
|
+
writer.write("\n")
|
|
382
|
+
|
|
383
|
+
writer.write(
|
|
384
|
+
f"""\
|
|
385
|
+
func {function_name}({arg_name} string) bool {{
|
|
386
|
+
{I}return {regex_name}.MatchString(
|
|
387
|
+
{II}{arg_name},
|
|
388
|
+
{I})
|
|
389
|
+
}}"""
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
blocks.append(Stripped(writer.getvalue()))
|
|
393
|
+
|
|
394
|
+
# endregion
|
|
395
|
+
|
|
396
|
+
writer = io.StringIO()
|
|
397
|
+
for i, block in enumerate(blocks):
|
|
398
|
+
if i > 0:
|
|
399
|
+
writer.write("\n\n")
|
|
400
|
+
|
|
401
|
+
writer.write(block)
|
|
402
|
+
|
|
403
|
+
return Stripped(writer.getvalue()), None
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
class _TranspilableVerificationTranspiler(golang_transpilation.Transpiler):
|
|
407
|
+
"""Transpile the body of a :py:class:`TranspilableVerification`."""
|
|
408
|
+
|
|
409
|
+
# fmt: off
|
|
410
|
+
@require(
|
|
411
|
+
lambda environment, verification:
|
|
412
|
+
all(
|
|
413
|
+
environment.find(arg.name) is not None
|
|
414
|
+
for arg in verification.arguments
|
|
415
|
+
),
|
|
416
|
+
"All arguments defined in the environment"
|
|
417
|
+
)
|
|
418
|
+
# fmt: on
|
|
419
|
+
def __init__(
|
|
420
|
+
self,
|
|
421
|
+
type_map: Mapping[
|
|
422
|
+
parse_tree.Node, intermediate_type_inference.TypeAnnotationUnion
|
|
423
|
+
],
|
|
424
|
+
is_pointer_map: Mapping[parse_tree.Node, bool],
|
|
425
|
+
environment: intermediate_type_inference.Environment,
|
|
426
|
+
symbol_table: intermediate.SymbolTable,
|
|
427
|
+
verification: intermediate.TranspilableVerification,
|
|
428
|
+
) -> None:
|
|
429
|
+
"""Initialize with the given values."""
|
|
430
|
+
golang_transpilation.Transpiler.__init__(
|
|
431
|
+
self,
|
|
432
|
+
type_map=type_map,
|
|
433
|
+
is_pointer_map=is_pointer_map,
|
|
434
|
+
environment=environment,
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
self._symbol_table = symbol_table
|
|
438
|
+
|
|
439
|
+
self._argument_name_set = frozenset(arg.name for arg in verification.arguments)
|
|
440
|
+
|
|
441
|
+
def _transform_enumeration_literal(
|
|
442
|
+
self, enumeration_name: Identifier, literal_name: Identifier
|
|
443
|
+
) -> Stripped:
|
|
444
|
+
literal = golang_naming.enum_literal_name(
|
|
445
|
+
enumeration_name=enumeration_name, literal_name=literal_name
|
|
446
|
+
)
|
|
447
|
+
return Stripped(f"aastypes.{literal}")
|
|
448
|
+
|
|
449
|
+
def transform_name(
|
|
450
|
+
self, node: parse_tree.Name
|
|
451
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
452
|
+
if node.identifier in self._variable_name_set:
|
|
453
|
+
return Stripped(golang_naming.variable_name(node.identifier)), None
|
|
454
|
+
|
|
455
|
+
if node.identifier in self._argument_name_set:
|
|
456
|
+
return Stripped(golang_naming.argument_name(node.identifier)), None
|
|
457
|
+
|
|
458
|
+
if node.identifier in self._symbol_table.constants_by_name:
|
|
459
|
+
constant_name = golang_naming.constant_name(node.identifier)
|
|
460
|
+
return Stripped(f"aasconstants.{constant_name}"), None
|
|
461
|
+
|
|
462
|
+
if node.identifier in self._symbol_table.verification_functions_by_name:
|
|
463
|
+
return Stripped(golang_naming.function_name(node.identifier)), None
|
|
464
|
+
|
|
465
|
+
our_type = self._symbol_table.find_our_type(name=node.identifier)
|
|
466
|
+
if isinstance(our_type, intermediate.Enumeration):
|
|
467
|
+
return (
|
|
468
|
+
Stripped(f"aastypes.{golang_naming.enum_name(node.identifier)}"),
|
|
469
|
+
None,
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
return None, Error(
|
|
473
|
+
node.original_node,
|
|
474
|
+
f"We can not determine how to transpile the name {node.identifier!r} "
|
|
475
|
+
f"to Golang. We could not find it neither in the constants, nor in "
|
|
476
|
+
f"verification functions, nor as an enumeration. "
|
|
477
|
+
f"If you expect this name to be transpilable, please contact "
|
|
478
|
+
f"the developers.",
|
|
479
|
+
)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def _transpile_transpilable_verification(
|
|
483
|
+
verification: intermediate.TranspilableVerification,
|
|
484
|
+
symbol_table: intermediate.SymbolTable,
|
|
485
|
+
environment: intermediate_type_inference.Environment,
|
|
486
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
487
|
+
"""Transpile a verification function."""
|
|
488
|
+
# fmt: off
|
|
489
|
+
type_inference, error = (
|
|
490
|
+
intermediate_type_inference.infer_for_verification(
|
|
491
|
+
verification=verification,
|
|
492
|
+
base_environment=environment
|
|
493
|
+
)
|
|
494
|
+
)
|
|
495
|
+
# fmt: on
|
|
496
|
+
|
|
497
|
+
if error is not None:
|
|
498
|
+
return None, error
|
|
499
|
+
|
|
500
|
+
assert type_inference is not None
|
|
501
|
+
|
|
502
|
+
pointer_inferrer = golang_pointering.Inferrer(
|
|
503
|
+
environment=type_inference.environment_with_args,
|
|
504
|
+
type_map=type_inference.type_map,
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
for node in verification.parsed.body:
|
|
508
|
+
_ = pointer_inferrer.transform(node)
|
|
509
|
+
|
|
510
|
+
if len(pointer_inferrer.errors) > 0:
|
|
511
|
+
return None, Error(
|
|
512
|
+
verification.parsed.node,
|
|
513
|
+
f"Failed to infer whether a node is a Golang pointer "
|
|
514
|
+
f"in the verification function {verification.name!r}",
|
|
515
|
+
pointer_inferrer.errors,
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
transpiler = _TranspilableVerificationTranspiler(
|
|
519
|
+
type_map=type_inference.type_map,
|
|
520
|
+
is_pointer_map=pointer_inferrer.is_pointer_map,
|
|
521
|
+
environment=type_inference.environment_with_args,
|
|
522
|
+
symbol_table=symbol_table,
|
|
523
|
+
verification=verification,
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
body = [] # type: List[Stripped]
|
|
527
|
+
for node in verification.parsed.body:
|
|
528
|
+
stmt, error = transpiler.transform(node)
|
|
529
|
+
if error is not None:
|
|
530
|
+
return None, Error(
|
|
531
|
+
verification.parsed.node,
|
|
532
|
+
f"Failed to transpile the verification function {verification.name!r}",
|
|
533
|
+
[error],
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
assert stmt is not None
|
|
537
|
+
body.append(stmt)
|
|
538
|
+
|
|
539
|
+
writer = io.StringIO()
|
|
540
|
+
|
|
541
|
+
if verification.description is not None:
|
|
542
|
+
(comment, comment_errors,) = golang_description.generate_comment_for_signature(
|
|
543
|
+
description=verification.description,
|
|
544
|
+
context=golang_description.Context(
|
|
545
|
+
package=golang_common.VERIFICATION_PACKAGE,
|
|
546
|
+
cls_or_enum=None,
|
|
547
|
+
),
|
|
548
|
+
)
|
|
549
|
+
if comment_errors is not None:
|
|
550
|
+
return None, Error(
|
|
551
|
+
verification.description.parsed.node,
|
|
552
|
+
f"Failed to generate the comment "
|
|
553
|
+
f"for verification function {verification.name!r}",
|
|
554
|
+
comment_errors,
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
assert comment is not None
|
|
558
|
+
|
|
559
|
+
writer.write(comment)
|
|
560
|
+
writer.write("\n")
|
|
561
|
+
|
|
562
|
+
function_name = golang_naming.function_name(verification.name)
|
|
563
|
+
|
|
564
|
+
if verification.returns is None:
|
|
565
|
+
return_type_suffix = ""
|
|
566
|
+
else:
|
|
567
|
+
return_type = golang_common.generate_type(
|
|
568
|
+
type_annotation=verification.returns, types_package=Identifier("aastypes")
|
|
569
|
+
)
|
|
570
|
+
return_type_suffix = f" {return_type}"
|
|
571
|
+
|
|
572
|
+
arg_defs = [] # type: List[Stripped]
|
|
573
|
+
for arg in verification.arguments:
|
|
574
|
+
arg_type = golang_common.generate_type(
|
|
575
|
+
arg.type_annotation, types_package=Identifier("aastypes")
|
|
576
|
+
)
|
|
577
|
+
arg_name = golang_naming.argument_name(arg.name)
|
|
578
|
+
arg_defs.append(Stripped(f"{arg_name} {arg_type}"))
|
|
579
|
+
|
|
580
|
+
if len(arg_defs) == 0:
|
|
581
|
+
writer.write(
|
|
582
|
+
f"""\
|
|
583
|
+
func {function_name}(){return_type_suffix} {{"""
|
|
584
|
+
)
|
|
585
|
+
else:
|
|
586
|
+
arg_defs_joined = "\n".join(f"{arg_def}," for arg_def in arg_defs)
|
|
587
|
+
writer.write(
|
|
588
|
+
f"""\
|
|
589
|
+
func {function_name}(
|
|
590
|
+
{I}{indent_but_first_line(arg_defs_joined, I)}
|
|
591
|
+
){return_type_suffix} {{"""
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
if len(body) == 0:
|
|
595
|
+
writer.write("\n")
|
|
596
|
+
writer.write("// Intentionally empty.")
|
|
597
|
+
else:
|
|
598
|
+
for stmt in body:
|
|
599
|
+
writer.write("\n")
|
|
600
|
+
writer.write(textwrap.indent(stmt, I))
|
|
601
|
+
|
|
602
|
+
writer.write("\n}")
|
|
603
|
+
|
|
604
|
+
return Stripped(writer.getvalue()), None
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
class _InvariantTranspiler(golang_transpilation.Transpiler):
|
|
608
|
+
def __init__(
|
|
609
|
+
self,
|
|
610
|
+
type_map: Mapping[
|
|
611
|
+
parse_tree.Node, intermediate_type_inference.TypeAnnotationUnion
|
|
612
|
+
],
|
|
613
|
+
is_pointer_map: Mapping[parse_tree.Node, bool],
|
|
614
|
+
environment: intermediate_type_inference.Environment,
|
|
615
|
+
symbol_table: intermediate.SymbolTable,
|
|
616
|
+
) -> None:
|
|
617
|
+
"""Initialize with the given values."""
|
|
618
|
+
golang_transpilation.Transpiler.__init__(
|
|
619
|
+
self,
|
|
620
|
+
type_map=type_map,
|
|
621
|
+
is_pointer_map=is_pointer_map,
|
|
622
|
+
environment=environment,
|
|
623
|
+
types_package=Identifier("aastypes"),
|
|
624
|
+
)
|
|
625
|
+
|
|
626
|
+
self._symbol_table = symbol_table
|
|
627
|
+
|
|
628
|
+
def _transform_enumeration_literal(
|
|
629
|
+
self, enumeration_name: Identifier, literal_name: Identifier
|
|
630
|
+
) -> Stripped:
|
|
631
|
+
literal = golang_naming.enum_literal_name(
|
|
632
|
+
enumeration_name=enumeration_name, literal_name=literal_name
|
|
633
|
+
)
|
|
634
|
+
return Stripped(f"aastypes.{literal}")
|
|
635
|
+
|
|
636
|
+
def transform_name(
|
|
637
|
+
self, node: parse_tree.Name
|
|
638
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
639
|
+
if node.identifier in self._variable_name_set:
|
|
640
|
+
name = Stripped(golang_naming.variable_name(node.identifier))
|
|
641
|
+
|
|
642
|
+
elif node.identifier == "self":
|
|
643
|
+
# The ``that`` refers to the argument of the verification function.
|
|
644
|
+
name = Stripped("that")
|
|
645
|
+
|
|
646
|
+
elif node.identifier in self._symbol_table.constants_by_name:
|
|
647
|
+
constant_name = golang_naming.constant_name(node.identifier)
|
|
648
|
+
name = Stripped(f"aasconstants.{constant_name}")
|
|
649
|
+
|
|
650
|
+
elif node.identifier in self._symbol_table.verification_functions_by_name:
|
|
651
|
+
name = Stripped(golang_naming.function_name(node.identifier))
|
|
652
|
+
|
|
653
|
+
elif (
|
|
654
|
+
our_type := self._symbol_table.find_our_type(name=node.identifier),
|
|
655
|
+
isinstance(our_type, intermediate.Enumeration),
|
|
656
|
+
)[1]:
|
|
657
|
+
name = Stripped(f"aastypes.{golang_naming.enum_name(node.identifier)}")
|
|
658
|
+
else:
|
|
659
|
+
return None, Error(
|
|
660
|
+
node.original_node,
|
|
661
|
+
f"We can not determine how to transpile the name {node.identifier!r} "
|
|
662
|
+
f"to Golang. We could not find it neither in the local variables, "
|
|
663
|
+
f"nor in the global constants, nor in verification functions, "
|
|
664
|
+
f"nor as an enumeration. If you expect this name to be transpilable, "
|
|
665
|
+
f"please contact the developers.",
|
|
666
|
+
)
|
|
667
|
+
|
|
668
|
+
assert name is not None
|
|
669
|
+
return name, None
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
673
|
+
def _transpile_invariant(
|
|
674
|
+
invariant: intermediate.Invariant,
|
|
675
|
+
symbol_table: intermediate.SymbolTable,
|
|
676
|
+
environment: intermediate_type_inference.Environment,
|
|
677
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
678
|
+
"""Translate the invariant from the meta-model into Golang code."""
|
|
679
|
+
# fmt: off
|
|
680
|
+
type_map, inference_error = (
|
|
681
|
+
intermediate_type_inference.infer_for_invariant(
|
|
682
|
+
invariant=invariant,
|
|
683
|
+
environment=environment
|
|
684
|
+
)
|
|
685
|
+
)
|
|
686
|
+
# fmt: on
|
|
687
|
+
|
|
688
|
+
if inference_error is not None:
|
|
689
|
+
return None, inference_error
|
|
690
|
+
|
|
691
|
+
assert type_map is not None
|
|
692
|
+
|
|
693
|
+
pointer_inferrer = golang_pointering.Inferrer(
|
|
694
|
+
environment=environment, type_map=type_map
|
|
695
|
+
)
|
|
696
|
+
|
|
697
|
+
_ = pointer_inferrer.transform(invariant.body)
|
|
698
|
+
|
|
699
|
+
if len(pointer_inferrer.errors) > 0:
|
|
700
|
+
return None, Error(
|
|
701
|
+
invariant.parsed.node,
|
|
702
|
+
"Failed to infer whether a node is a Golang pointer in the invariant",
|
|
703
|
+
pointer_inferrer.errors,
|
|
704
|
+
)
|
|
705
|
+
|
|
706
|
+
transpiler = _InvariantTranspiler(
|
|
707
|
+
type_map=type_map,
|
|
708
|
+
is_pointer_map=pointer_inferrer.is_pointer_map,
|
|
709
|
+
environment=environment,
|
|
710
|
+
symbol_table=symbol_table,
|
|
711
|
+
)
|
|
712
|
+
|
|
713
|
+
expr, error = transpiler.transform(invariant.parsed.body)
|
|
714
|
+
if error is not None:
|
|
715
|
+
return None, error
|
|
716
|
+
|
|
717
|
+
assert expr is not None
|
|
718
|
+
|
|
719
|
+
writer = io.StringIO()
|
|
720
|
+
if len(expr) > 50 or "\n" in expr:
|
|
721
|
+
writer.write(
|
|
722
|
+
f"""\
|
|
723
|
+
if !(
|
|
724
|
+
{I}{indent_but_first_line(expr, I)}) {{
|
|
725
|
+
"""
|
|
726
|
+
)
|
|
727
|
+
else:
|
|
728
|
+
no_parenthesis_type_in_this_context = (
|
|
729
|
+
parse_tree.Index,
|
|
730
|
+
parse_tree.Name,
|
|
731
|
+
parse_tree.Member,
|
|
732
|
+
parse_tree.MethodCall,
|
|
733
|
+
parse_tree.FunctionCall,
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
if isinstance(invariant.parsed.body, no_parenthesis_type_in_this_context):
|
|
737
|
+
not_expr = f"!{expr}"
|
|
738
|
+
else:
|
|
739
|
+
not_expr = f"!({expr})"
|
|
740
|
+
|
|
741
|
+
writer.write(f"if {not_expr} {{\n")
|
|
742
|
+
|
|
743
|
+
new_verification_error_writer = io.StringIO()
|
|
744
|
+
|
|
745
|
+
new_verification_error_writer.write("newVerificationError(\n")
|
|
746
|
+
|
|
747
|
+
# NOTE (mristin, 2023-04-12):
|
|
748
|
+
# We need to wrap the description in multiple literals as a single long
|
|
749
|
+
# string literal is often too much for the readability.
|
|
750
|
+
invariant_description_lines = wrap_text_into_lines(invariant.description)
|
|
751
|
+
|
|
752
|
+
if len(invariant_description_lines) == 1:
|
|
753
|
+
line = invariant_description_lines[0]
|
|
754
|
+
new_verification_error_writer.write(f"{I}{golang_common.string_literal(line)},")
|
|
755
|
+
new_verification_error_writer.write(")")
|
|
756
|
+
else:
|
|
757
|
+
for i, line in enumerate(invariant_description_lines):
|
|
758
|
+
if i == 0:
|
|
759
|
+
new_verification_error_writer.write(
|
|
760
|
+
f"{I}{golang_common.string_literal(line)} +\n"
|
|
761
|
+
)
|
|
762
|
+
elif i < len(invariant_description_lines) - 1:
|
|
763
|
+
new_verification_error_writer.write(
|
|
764
|
+
f"{I}{golang_common.string_literal(line)} +\n"
|
|
765
|
+
)
|
|
766
|
+
else:
|
|
767
|
+
new_verification_error_writer.write(
|
|
768
|
+
f"{I}{golang_common.string_literal(line)},\n"
|
|
769
|
+
)
|
|
770
|
+
new_verification_error_writer.write(")")
|
|
771
|
+
|
|
772
|
+
new_verification_error = Stripped(new_verification_error_writer.getvalue())
|
|
773
|
+
|
|
774
|
+
writer.write(
|
|
775
|
+
f"""\
|
|
776
|
+
{I}abort = onError(
|
|
777
|
+
{II}{indent_but_first_line(new_verification_error, II)},
|
|
778
|
+
{I})
|
|
779
|
+
{I}if abort {{
|
|
780
|
+
{II}return
|
|
781
|
+
{I}}}
|
|
782
|
+
}}"""
|
|
783
|
+
)
|
|
784
|
+
|
|
785
|
+
return Stripped(writer.getvalue()), None
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
OurTypeExceptEnumeration = Union[
|
|
789
|
+
intermediate.ConstrainedPrimitive,
|
|
790
|
+
intermediate.AbstractClass,
|
|
791
|
+
intermediate.ConcreteClass,
|
|
792
|
+
]
|
|
793
|
+
assert_union_without_excluded(
|
|
794
|
+
original_union=intermediate.OurType,
|
|
795
|
+
subset_union=OurTypeExceptEnumeration,
|
|
796
|
+
excluded=[intermediate.Enumeration],
|
|
797
|
+
)
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
801
|
+
def _generate_verify_property_snippet(
|
|
802
|
+
prop: intermediate.Property,
|
|
803
|
+
) -> Tuple[Optional[Stripped], Optional[Error]]:
|
|
804
|
+
"""
|
|
805
|
+
Generate the snippet to verify a property.
|
|
806
|
+
|
|
807
|
+
Return an empty string if there is nothing to be verified for the given property.
|
|
808
|
+
"""
|
|
809
|
+
# NOTE (mristin, 2023-04-12):
|
|
810
|
+
# Instead of writing here a complex but general solution with unrolling we choose
|
|
811
|
+
# to provide a simple, but limited, solution. First, the meta-model is quite
|
|
812
|
+
# limited itself at the moment, so the complexity of the general solution is not
|
|
813
|
+
# warranted. Second, we hope that there will be fewer bugs in the simple solution
|
|
814
|
+
# which is particularly important at this early adoption stage.
|
|
815
|
+
#
|
|
816
|
+
# We anticipate that in the future we will indeed need a general and complex
|
|
817
|
+
# solution. Here are just some thoughts on how to approach it:
|
|
818
|
+
# * Leave the pattern matching to produce more readable code for simple cases,
|
|
819
|
+
# * Unroll only in case of composite types and optional composite types.
|
|
820
|
+
|
|
821
|
+
type_anno = intermediate.beneath_optional(prop.type_annotation)
|
|
822
|
+
|
|
823
|
+
prop_name = golang_naming.property_name(prop.name)
|
|
824
|
+
prop_name_literal = golang_common.string_literal(prop_name)
|
|
825
|
+
|
|
826
|
+
getter_name = golang_naming.getter_name(prop.name)
|
|
827
|
+
|
|
828
|
+
optional = isinstance(prop.type_annotation, intermediate.OptionalTypeAnnotation)
|
|
829
|
+
|
|
830
|
+
block = None # type: Optional[Stripped]
|
|
831
|
+
|
|
832
|
+
if isinstance(type_anno, intermediate.PrimitiveTypeAnnotation):
|
|
833
|
+
if type_anno.a_type is intermediate.PrimitiveType.BYTEARRAY and not optional:
|
|
834
|
+
block = Stripped(
|
|
835
|
+
f"""\
|
|
836
|
+
if that.{getter_name}() == nil {{
|
|
837
|
+
{I}abort = onError(
|
|
838
|
+
{II}newVerificationError(
|
|
839
|
+
{III}"Required property not set: {prop_name}",
|
|
840
|
+
{II}),
|
|
841
|
+
{I})
|
|
842
|
+
{I}if abort {{
|
|
843
|
+
{II}return
|
|
844
|
+
{I}}}
|
|
845
|
+
}}"""
|
|
846
|
+
)
|
|
847
|
+
|
|
848
|
+
elif isinstance(type_anno, intermediate.OurTypeAnnotation):
|
|
849
|
+
our_type = type_anno.our_type
|
|
850
|
+
|
|
851
|
+
if isinstance(our_type, intermediate.Enumeration):
|
|
852
|
+
enum_name = golang_naming.enum_name(our_type.name)
|
|
853
|
+
|
|
854
|
+
# NOTE (mristin, 2023-04-12):
|
|
855
|
+
# The case where we have no literals defined is an edge case where no
|
|
856
|
+
# literal satisfies the condition.
|
|
857
|
+
if len(our_type.literals) == 0:
|
|
858
|
+
block = Stripped(
|
|
859
|
+
f"""\
|
|
860
|
+
err := newVerificationError(
|
|
861
|
+
{I}fmt.Sprintf(
|
|
862
|
+
{II}"The enumeration {enum_name} has no literals defined, " +
|
|
863
|
+
{II}"but you passed in: %v",
|
|
864
|
+
{II}that.{getter_name}()
|
|
865
|
+
{I})
|
|
866
|
+
)
|
|
867
|
+
err.Path.Prepend(
|
|
868
|
+
{I}&aasreporting.NameSegment{{
|
|
869
|
+
{II}Name: {prop_name_literal},
|
|
870
|
+
{I}}},
|
|
871
|
+
)
|
|
872
|
+
abort = onError(err)
|
|
873
|
+
if abort {{
|
|
874
|
+
{I}return
|
|
875
|
+
}}"""
|
|
876
|
+
)
|
|
877
|
+
else:
|
|
878
|
+
first_literal = golang_naming.enum_literal_name(
|
|
879
|
+
enumeration_name=our_type.name,
|
|
880
|
+
literal_name=our_type.literals[0].name,
|
|
881
|
+
)
|
|
882
|
+
last_literal = golang_naming.enum_literal_name(
|
|
883
|
+
enumeration_name=our_type.name,
|
|
884
|
+
literal_name=our_type.literals[-1].name,
|
|
885
|
+
)
|
|
886
|
+
|
|
887
|
+
pointer_prefix = (
|
|
888
|
+
"*"
|
|
889
|
+
if golang_pointering.is_pointer_type(prop.type_annotation)
|
|
890
|
+
else ""
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
block = Stripped(
|
|
894
|
+
f"""\
|
|
895
|
+
if
|
|
896
|
+
{I}{pointer_prefix}that.{getter_name}() < aastypes.{first_literal} ||
|
|
897
|
+
{I}{pointer_prefix}that.{getter_name}() > aastypes.{last_literal} {{
|
|
898
|
+
{I}err := newVerificationError(
|
|
899
|
+
{II}fmt.Sprintf(
|
|
900
|
+
{III}"Invalid literal value for {enum_name}: %v",
|
|
901
|
+
{III}that.{getter_name}(),
|
|
902
|
+
{II}),
|
|
903
|
+
{I})
|
|
904
|
+
{I}err.Path.PrependName(
|
|
905
|
+
{II}&aasreporting.NameSegment{{
|
|
906
|
+
{III}Name: {prop_name_literal},
|
|
907
|
+
{II}}},
|
|
908
|
+
{I})
|
|
909
|
+
{I}abort = onError(err)
|
|
910
|
+
{I}if abort {{
|
|
911
|
+
{II}return
|
|
912
|
+
{I}}}
|
|
913
|
+
}}"""
|
|
914
|
+
)
|
|
915
|
+
|
|
916
|
+
elif isinstance(our_type, intermediate.ConstrainedPrimitive):
|
|
917
|
+
verify_function_name = golang_naming.function_name(
|
|
918
|
+
Identifier(f"verify_{our_type.name}")
|
|
919
|
+
)
|
|
920
|
+
|
|
921
|
+
pointer_prefix = (
|
|
922
|
+
"*" if golang_pointering.is_pointer_type(prop.type_annotation) else ""
|
|
923
|
+
)
|
|
924
|
+
|
|
925
|
+
block = Stripped(
|
|
926
|
+
f"""\
|
|
927
|
+
abort = {verify_function_name}(
|
|
928
|
+
{I}{pointer_prefix}that.{getter_name}(),
|
|
929
|
+
{I}func(err *VerificationError) bool {{
|
|
930
|
+
{II}err.Path.PrependName(
|
|
931
|
+
{III}&aasreporting.NameSegment{{
|
|
932
|
+
{IIII}Name: {prop_name_literal},
|
|
933
|
+
{III}}},
|
|
934
|
+
{II})
|
|
935
|
+
{II}return onError(err)
|
|
936
|
+
{I}}},
|
|
937
|
+
)
|
|
938
|
+
if abort {{
|
|
939
|
+
{I}return
|
|
940
|
+
}}"""
|
|
941
|
+
)
|
|
942
|
+
|
|
943
|
+
elif isinstance(
|
|
944
|
+
our_type, (intermediate.AbstractClass, intermediate.ConcreteClass)
|
|
945
|
+
):
|
|
946
|
+
block = Stripped(
|
|
947
|
+
f"""\
|
|
948
|
+
abort = Verify(
|
|
949
|
+
{I}that.{getter_name}(),
|
|
950
|
+
{I}func(err *VerificationError) bool {{
|
|
951
|
+
{II}err.Path.PrependName(
|
|
952
|
+
{III}&aasreporting.NameSegment{{
|
|
953
|
+
{IIII}Name: {prop_name_literal},
|
|
954
|
+
{III}}},
|
|
955
|
+
{II})
|
|
956
|
+
{II}return onError(err)
|
|
957
|
+
{I}}},
|
|
958
|
+
)
|
|
959
|
+
if abort {{
|
|
960
|
+
{I}return
|
|
961
|
+
}}"""
|
|
962
|
+
)
|
|
963
|
+
else:
|
|
964
|
+
assert_never(our_type)
|
|
965
|
+
|
|
966
|
+
elif isinstance(type_anno, intermediate.ListTypeAnnotation):
|
|
967
|
+
assert isinstance(
|
|
968
|
+
type_anno.items, intermediate.OurTypeAnnotation
|
|
969
|
+
) and isinstance(
|
|
970
|
+
type_anno.items.our_type,
|
|
971
|
+
(intermediate.AbstractClass, intermediate.ConcreteClass),
|
|
972
|
+
), (
|
|
973
|
+
f"NOTE (mristin, 2023-04-12): We expect only lists of classes "
|
|
974
|
+
f"at the moment, but you specified {type_anno}. "
|
|
975
|
+
f"Please contact the developers if you need this feature."
|
|
976
|
+
)
|
|
977
|
+
|
|
978
|
+
block = Stripped(
|
|
979
|
+
f"""\
|
|
980
|
+
for i, v := range that.{getter_name}() {{
|
|
981
|
+
{I}abort = Verify(
|
|
982
|
+
{II}v,
|
|
983
|
+
{II}func(err *VerificationError) bool {{
|
|
984
|
+
{III}err.Path.PrependIndex(
|
|
985
|
+
{IIII}&aasreporting.IndexSegment{{
|
|
986
|
+
{IIIII}Index: i,
|
|
987
|
+
{IIII}}},
|
|
988
|
+
{III})
|
|
989
|
+
|
|
990
|
+
{III}err.Path.PrependName(
|
|
991
|
+
{IIII}&aasreporting.NameSegment{{
|
|
992
|
+
{IIIII}Name: {prop_name_literal},
|
|
993
|
+
{IIII}}},
|
|
994
|
+
{III})
|
|
995
|
+
|
|
996
|
+
{III}return onError(err)
|
|
997
|
+
{II}}},
|
|
998
|
+
{I})
|
|
999
|
+
{I}if abort {{
|
|
1000
|
+
{II}return
|
|
1001
|
+
{I}}}
|
|
1002
|
+
}}"""
|
|
1003
|
+
)
|
|
1004
|
+
|
|
1005
|
+
else:
|
|
1006
|
+
assert_never(type_anno)
|
|
1007
|
+
|
|
1008
|
+
primitive_type = intermediate.try_primitive_type(type_anno)
|
|
1009
|
+
|
|
1010
|
+
is_reference = (
|
|
1011
|
+
optional
|
|
1012
|
+
or primitive_type is intermediate.PrimitiveType.BYTEARRAY
|
|
1013
|
+
or (
|
|
1014
|
+
isinstance(type_anno, intermediate.OurTypeAnnotation)
|
|
1015
|
+
and isinstance(
|
|
1016
|
+
type_anno.our_type,
|
|
1017
|
+
(intermediate.AbstractClass, intermediate.ConcreteClass),
|
|
1018
|
+
)
|
|
1019
|
+
)
|
|
1020
|
+
or isinstance(type_anno, intermediate.ListTypeAnnotation)
|
|
1021
|
+
)
|
|
1022
|
+
|
|
1023
|
+
if not optional and is_reference and block is None:
|
|
1024
|
+
block = Stripped(
|
|
1025
|
+
f"""\
|
|
1026
|
+
if that.{getter_name}() == nil {{
|
|
1027
|
+
{I}abort = onError(
|
|
1028
|
+
{II}newVerificationError(
|
|
1029
|
+
{III}"Required property not set: {prop_name}",
|
|
1030
|
+
{II}),
|
|
1031
|
+
{I})
|
|
1032
|
+
{I}if abort {{
|
|
1033
|
+
{II}return
|
|
1034
|
+
{I}}}
|
|
1035
|
+
}}"""
|
|
1036
|
+
)
|
|
1037
|
+
elif not optional and is_reference and block is not None:
|
|
1038
|
+
block = Stripped(
|
|
1039
|
+
f"""\
|
|
1040
|
+
if that.{getter_name}() == nil {{
|
|
1041
|
+
{I}abort = onError(
|
|
1042
|
+
{II}newVerificationError(
|
|
1043
|
+
{III}"Required property not set: {prop_name}",
|
|
1044
|
+
{II}),
|
|
1045
|
+
{I})
|
|
1046
|
+
{I}if abort {{
|
|
1047
|
+
{II}return
|
|
1048
|
+
{I}}}
|
|
1049
|
+
}} else {{
|
|
1050
|
+
{I}{indent_but_first_line(block, I)}
|
|
1051
|
+
}}"""
|
|
1052
|
+
)
|
|
1053
|
+
elif optional and block is not None:
|
|
1054
|
+
block = Stripped(
|
|
1055
|
+
f"""\
|
|
1056
|
+
if that.{getter_name}() != nil {{
|
|
1057
|
+
{I}{indent_but_first_line(block, I)}
|
|
1058
|
+
}}"""
|
|
1059
|
+
)
|
|
1060
|
+
elif block is None:
|
|
1061
|
+
return Stripped(""), None
|
|
1062
|
+
else:
|
|
1063
|
+
assert AssertionError(f"Unhandled case: {block=}, {optional=}, {is_reference=}")
|
|
1064
|
+
|
|
1065
|
+
return block, None
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
1069
|
+
def _generate_verify_class(
|
|
1070
|
+
cls: intermediate.ConcreteClass,
|
|
1071
|
+
symbol_table: intermediate.SymbolTable,
|
|
1072
|
+
base_environment: intermediate_type_inference.Environment,
|
|
1073
|
+
) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
|
|
1074
|
+
"""Generate the verification function for the given concrete class."""
|
|
1075
|
+
errors = [] # type: List[Error]
|
|
1076
|
+
blocks = [] # type: List[Stripped]
|
|
1077
|
+
|
|
1078
|
+
environment = intermediate_type_inference.MutableEnvironment(
|
|
1079
|
+
parent=base_environment
|
|
1080
|
+
)
|
|
1081
|
+
|
|
1082
|
+
assert environment.find(Identifier("self")) is None
|
|
1083
|
+
environment.set(
|
|
1084
|
+
identifier=Identifier("self"),
|
|
1085
|
+
type_annotation=intermediate_type_inference.OurTypeAnnotation(our_type=cls),
|
|
1086
|
+
)
|
|
1087
|
+
|
|
1088
|
+
# region Generate the non-recursive part verifying the invariants
|
|
1089
|
+
|
|
1090
|
+
for invariant in cls.invariants:
|
|
1091
|
+
invariant_code, error = _transpile_invariant(
|
|
1092
|
+
invariant=invariant, symbol_table=symbol_table, environment=environment
|
|
1093
|
+
)
|
|
1094
|
+
if error is not None:
|
|
1095
|
+
errors.append(
|
|
1096
|
+
Error(
|
|
1097
|
+
cls.parsed.node,
|
|
1098
|
+
f"Failed to transpile the invariant of the class {cls.name!r}",
|
|
1099
|
+
[error],
|
|
1100
|
+
)
|
|
1101
|
+
)
|
|
1102
|
+
continue
|
|
1103
|
+
|
|
1104
|
+
assert invariant_code is not None
|
|
1105
|
+
|
|
1106
|
+
blocks.append(invariant_code)
|
|
1107
|
+
|
|
1108
|
+
# endregion
|
|
1109
|
+
|
|
1110
|
+
# region Recurse into properties
|
|
1111
|
+
|
|
1112
|
+
for prop in cls.properties:
|
|
1113
|
+
block, error = _generate_verify_property_snippet(prop=prop)
|
|
1114
|
+
if error is not None:
|
|
1115
|
+
errors.append(
|
|
1116
|
+
Error(
|
|
1117
|
+
cls.parsed.node,
|
|
1118
|
+
f"Failed to generate the verification of the property {prop.name!r} "
|
|
1119
|
+
f"of the class {cls.name!r}",
|
|
1120
|
+
[error],
|
|
1121
|
+
)
|
|
1122
|
+
)
|
|
1123
|
+
continue
|
|
1124
|
+
|
|
1125
|
+
assert block is not None
|
|
1126
|
+
|
|
1127
|
+
if block != "":
|
|
1128
|
+
blocks.append(block)
|
|
1129
|
+
|
|
1130
|
+
# endregion
|
|
1131
|
+
|
|
1132
|
+
if len(errors) > 0:
|
|
1133
|
+
return None, errors
|
|
1134
|
+
|
|
1135
|
+
interface_name = golang_naming.interface_name(cls.name)
|
|
1136
|
+
|
|
1137
|
+
if len(blocks) == 0:
|
|
1138
|
+
blocks.append(
|
|
1139
|
+
Stripped(
|
|
1140
|
+
f"""\
|
|
1141
|
+
// No verification has been defined for {interface_name}."""
|
|
1142
|
+
)
|
|
1143
|
+
)
|
|
1144
|
+
|
|
1145
|
+
function_name = golang_naming.function_name(Identifier(f"verify_{cls.name}"))
|
|
1146
|
+
|
|
1147
|
+
body = "\n\n".join(blocks)
|
|
1148
|
+
|
|
1149
|
+
return (
|
|
1150
|
+
Stripped(
|
|
1151
|
+
f"""\
|
|
1152
|
+
// Verify `that` instance of [aastypes.{interface_name}].
|
|
1153
|
+
//
|
|
1154
|
+
// You have to supply the callback `onError` to iterate over the errors.
|
|
1155
|
+
// If `onError` returns abort `true`, this function will abort
|
|
1156
|
+
// further verification as well, and return abort `true`. Otherwise,
|
|
1157
|
+
// abort `false` is returned.
|
|
1158
|
+
func {function_name}(
|
|
1159
|
+
{I}that aastypes.{interface_name},
|
|
1160
|
+
{I}onError func(*VerificationError) bool,
|
|
1161
|
+
) (abort bool) {{
|
|
1162
|
+
{I}abort = false
|
|
1163
|
+
|
|
1164
|
+
{I}{indent_but_first_line(body, I)}
|
|
1165
|
+
|
|
1166
|
+
{I}return
|
|
1167
|
+
}}"""
|
|
1168
|
+
),
|
|
1169
|
+
None,
|
|
1170
|
+
)
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
def _generate_verify(symbol_table: intermediate.SymbolTable) -> Stripped:
|
|
1174
|
+
"""Generate the main entry point for verification."""
|
|
1175
|
+
case_blocks = [] # type: List[Stripped]
|
|
1176
|
+
|
|
1177
|
+
for cls in symbol_table.concrete_classes:
|
|
1178
|
+
literal = golang_naming.enum_literal_name(
|
|
1179
|
+
enumeration_name=Identifier("Model_type"), literal_name=cls.name
|
|
1180
|
+
)
|
|
1181
|
+
|
|
1182
|
+
verification_function = golang_naming.function_name(
|
|
1183
|
+
Identifier(f"verify_{cls.name}")
|
|
1184
|
+
)
|
|
1185
|
+
|
|
1186
|
+
interface_name = golang_naming.interface_name(cls.name)
|
|
1187
|
+
|
|
1188
|
+
case_blocks.append(
|
|
1189
|
+
Stripped(
|
|
1190
|
+
f"""\
|
|
1191
|
+
case aastypes.{literal}:
|
|
1192
|
+
{I}abort = {verification_function}(
|
|
1193
|
+
{II}that.(aastypes.{interface_name}),
|
|
1194
|
+
{II}onError,
|
|
1195
|
+
{I})"""
|
|
1196
|
+
)
|
|
1197
|
+
)
|
|
1198
|
+
|
|
1199
|
+
case_blocks.append(
|
|
1200
|
+
Stripped(
|
|
1201
|
+
f"""\
|
|
1202
|
+
default:
|
|
1203
|
+
{I}abort = onError(
|
|
1204
|
+
{II}newVerificationError(
|
|
1205
|
+
{III}fmt.Sprintf(
|
|
1206
|
+
{IIII}"Unexpected model type literal: %v",
|
|
1207
|
+
{IIII}modelType,
|
|
1208
|
+
{III}),
|
|
1209
|
+
{II}),
|
|
1210
|
+
{I})"""
|
|
1211
|
+
)
|
|
1212
|
+
)
|
|
1213
|
+
|
|
1214
|
+
switch_body = Stripped("\n".join(case_blocks))
|
|
1215
|
+
switch_statement = Stripped(
|
|
1216
|
+
f"""\
|
|
1217
|
+
switch modelType {{
|
|
1218
|
+
{switch_body}
|
|
1219
|
+
}}"""
|
|
1220
|
+
)
|
|
1221
|
+
|
|
1222
|
+
model_type_getter = golang_naming.getter_name(Identifier("model_type"))
|
|
1223
|
+
|
|
1224
|
+
return Stripped(
|
|
1225
|
+
f"""\
|
|
1226
|
+
// Verify ``that`` instance.
|
|
1227
|
+
//
|
|
1228
|
+
// You have to supply the callback `onError` to iterate over the errors.
|
|
1229
|
+
// If `onError` returns abort `true`, this function will abort
|
|
1230
|
+
// further verification as well, and return abort `true`. Otherwise,
|
|
1231
|
+
// abort `false` is returned.
|
|
1232
|
+
func Verify(
|
|
1233
|
+
{I}that aastypes.IClass,
|
|
1234
|
+
{I}onError func(*VerificationError) bool,
|
|
1235
|
+
) (abort bool) {{
|
|
1236
|
+
{I}modelType := that.{model_type_getter}()
|
|
1237
|
+
{I}{indent_but_first_line(switch_statement, I)}
|
|
1238
|
+
{I}return
|
|
1239
|
+
}}"""
|
|
1240
|
+
)
|
|
1241
|
+
|
|
1242
|
+
|
|
1243
|
+
def _generate_verify_constrained_primitive(
|
|
1244
|
+
constrained_primitive: intermediate.ConstrainedPrimitive,
|
|
1245
|
+
symbol_table: intermediate.SymbolTable,
|
|
1246
|
+
base_environment: intermediate_type_inference.Environment,
|
|
1247
|
+
) -> Tuple[Optional[Stripped], Optional[List[Error]]]:
|
|
1248
|
+
"""Generate the verify function for the constrained primitives."""
|
|
1249
|
+
errors = [] # type: List[Error]
|
|
1250
|
+
blocks = [] # type: List[Stripped]
|
|
1251
|
+
|
|
1252
|
+
environment = intermediate_type_inference.MutableEnvironment(
|
|
1253
|
+
parent=base_environment
|
|
1254
|
+
)
|
|
1255
|
+
|
|
1256
|
+
assert environment.find(Identifier("self")) is None
|
|
1257
|
+
environment.set(
|
|
1258
|
+
identifier=Identifier("self"),
|
|
1259
|
+
type_annotation=intermediate_type_inference.OurTypeAnnotation(
|
|
1260
|
+
our_type=constrained_primitive
|
|
1261
|
+
),
|
|
1262
|
+
)
|
|
1263
|
+
|
|
1264
|
+
for invariant in constrained_primitive.invariants:
|
|
1265
|
+
invariant_code, error = _transpile_invariant(
|
|
1266
|
+
invariant=invariant, symbol_table=symbol_table, environment=environment
|
|
1267
|
+
)
|
|
1268
|
+
if error is not None:
|
|
1269
|
+
errors.append(
|
|
1270
|
+
Error(
|
|
1271
|
+
constrained_primitive.parsed.node,
|
|
1272
|
+
f"Failed to transpile the invariant of "
|
|
1273
|
+
f"the constrained primitive {constrained_primitive.name!r}",
|
|
1274
|
+
[error],
|
|
1275
|
+
)
|
|
1276
|
+
)
|
|
1277
|
+
continue
|
|
1278
|
+
|
|
1279
|
+
assert invariant_code is not None
|
|
1280
|
+
|
|
1281
|
+
blocks.append(invariant_code)
|
|
1282
|
+
|
|
1283
|
+
if len(errors) > 0:
|
|
1284
|
+
return None, errors
|
|
1285
|
+
|
|
1286
|
+
if len(blocks) == 0:
|
|
1287
|
+
blocks.append(Stripped("// There is no verification specified."))
|
|
1288
|
+
|
|
1289
|
+
body = "\n\n".join(blocks)
|
|
1290
|
+
|
|
1291
|
+
function_name = golang_naming.function_name(
|
|
1292
|
+
Identifier(f"verify_{constrained_primitive.name}")
|
|
1293
|
+
)
|
|
1294
|
+
|
|
1295
|
+
that_type = golang_common.PRIMITIVE_TYPE_MAP[constrained_primitive.constrainee]
|
|
1296
|
+
|
|
1297
|
+
return (
|
|
1298
|
+
Stripped(
|
|
1299
|
+
f"""\
|
|
1300
|
+
// Verify the constraints of `that` value.
|
|
1301
|
+
//
|
|
1302
|
+
// You have to supply the callback `onError` to iterate over the errors.
|
|
1303
|
+
// If `onError` returns abort `true`, this function will abort
|
|
1304
|
+
// further verification as well, and return abort `true`. Otherwise,
|
|
1305
|
+
// abort `false` is returned.
|
|
1306
|
+
func {function_name}(
|
|
1307
|
+
{I}that {that_type},
|
|
1308
|
+
{I}onError func(*VerificationError) bool,
|
|
1309
|
+
) (abort bool) {{
|
|
1310
|
+
{I}abort = false
|
|
1311
|
+
|
|
1312
|
+
{I}{indent_but_first_line(body, I)}
|
|
1313
|
+
|
|
1314
|
+
{I}return
|
|
1315
|
+
}}"""
|
|
1316
|
+
),
|
|
1317
|
+
None,
|
|
1318
|
+
)
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
# fmt: off
|
|
1322
|
+
@ensure(lambda result: (result[0] is not None) ^ (result[1] is not None))
|
|
1323
|
+
@ensure(
|
|
1324
|
+
lambda result:
|
|
1325
|
+
not (result[0] is not None) or result[0].endswith('\n'),
|
|
1326
|
+
"Trailing newline mandatory for valid end-of-files"
|
|
1327
|
+
)
|
|
1328
|
+
# fmt: on
|
|
1329
|
+
def generate(
|
|
1330
|
+
symbol_table: intermediate.SymbolTable,
|
|
1331
|
+
spec_impls: specific_implementations.SpecificImplementations,
|
|
1332
|
+
repo_url: Stripped,
|
|
1333
|
+
) -> Tuple[Optional[str], Optional[List[Error]]]:
|
|
1334
|
+
"""Generate the Golang code for verification based on the symbol table."""
|
|
1335
|
+
errors = [] # type: List[Error]
|
|
1336
|
+
|
|
1337
|
+
aasconstants_url_literal = golang_common.string_literal(f"{repo_url}/constants")
|
|
1338
|
+
|
|
1339
|
+
aascommon_url_literal = golang_common.string_literal(f"{repo_url}/common")
|
|
1340
|
+
|
|
1341
|
+
aasreporting_url_literal = golang_common.string_literal(f"{repo_url}/reporting")
|
|
1342
|
+
|
|
1343
|
+
aastypes_url_literal = golang_common.string_literal(f"{repo_url}/types")
|
|
1344
|
+
|
|
1345
|
+
blocks = [
|
|
1346
|
+
Stripped(
|
|
1347
|
+
"""\
|
|
1348
|
+
// Package verification allows you to verify model instances.
|
|
1349
|
+
//
|
|
1350
|
+
// The main function is [Verify].
|
|
1351
|
+
//
|
|
1352
|
+
// Other verification functions (`Verify*`) are left for modularity, in case you want
|
|
1353
|
+
// to be explicit about the typing in your code. However, in the large majority of
|
|
1354
|
+
// the cases, you only want to call [Verify].
|
|
1355
|
+
package verification"""
|
|
1356
|
+
),
|
|
1357
|
+
golang_common.WARNING,
|
|
1358
|
+
Stripped(
|
|
1359
|
+
f"""\
|
|
1360
|
+
import (
|
|
1361
|
+
{I}"math/big"
|
|
1362
|
+
{I}"fmt"
|
|
1363
|
+
{I}"regexp"
|
|
1364
|
+
{I}"strconv"
|
|
1365
|
+
{I}"strings"
|
|
1366
|
+
{I}aascommon {aascommon_url_literal}
|
|
1367
|
+
{I}aasconstants {aasconstants_url_literal}
|
|
1368
|
+
{I}aasreporting {aasreporting_url_literal}
|
|
1369
|
+
{I}aastypes {aastypes_url_literal}
|
|
1370
|
+
)"""
|
|
1371
|
+
),
|
|
1372
|
+
Stripped(
|
|
1373
|
+
f"""\
|
|
1374
|
+
// Represent a verification violation.
|
|
1375
|
+
//
|
|
1376
|
+
// Implements `error`.
|
|
1377
|
+
type VerificationError struct{{
|
|
1378
|
+
{I}Path *aasreporting.Path
|
|
1379
|
+
{I}Message string
|
|
1380
|
+
}}"""
|
|
1381
|
+
),
|
|
1382
|
+
Stripped(
|
|
1383
|
+
f"""\
|
|
1384
|
+
func newVerificationError(message string) *VerificationError {{
|
|
1385
|
+
{I}return &VerificationError{{
|
|
1386
|
+
{II}Path: &aasreporting.Path{{}},
|
|
1387
|
+
{II}Message: message,
|
|
1388
|
+
{I}}}
|
|
1389
|
+
}}"""
|
|
1390
|
+
),
|
|
1391
|
+
Stripped(
|
|
1392
|
+
f"""\
|
|
1393
|
+
func (ve *VerificationError) Error() string {{
|
|
1394
|
+
{I}return fmt.Sprintf(
|
|
1395
|
+
{II}"%s: %s",
|
|
1396
|
+
{II}ve.PathString(),
|
|
1397
|
+
{II}ve.Message,
|
|
1398
|
+
{I})
|
|
1399
|
+
}}"""
|
|
1400
|
+
),
|
|
1401
|
+
Stripped(
|
|
1402
|
+
f"""\
|
|
1403
|
+
// Render the path as a string.
|
|
1404
|
+
func (ve *VerificationError) PathString() string {{
|
|
1405
|
+
{I}return aasreporting.ToGolangPath(ve.Path)
|
|
1406
|
+
}}"""
|
|
1407
|
+
),
|
|
1408
|
+
] # type: List[Stripped]
|
|
1409
|
+
|
|
1410
|
+
base_environment = intermediate_type_inference.populate_base_environment(
|
|
1411
|
+
symbol_table=symbol_table
|
|
1412
|
+
)
|
|
1413
|
+
|
|
1414
|
+
for verification in symbol_table.verification_functions:
|
|
1415
|
+
if isinstance(verification, intermediate.ImplementationSpecificVerification):
|
|
1416
|
+
implementation_key = specific_implementations.ImplementationKey(
|
|
1417
|
+
f"Verification/{verification.name}.go"
|
|
1418
|
+
)
|
|
1419
|
+
|
|
1420
|
+
implementation = spec_impls.get(implementation_key, None)
|
|
1421
|
+
if implementation is None:
|
|
1422
|
+
errors.append(
|
|
1423
|
+
Error(
|
|
1424
|
+
None,
|
|
1425
|
+
f"The snippet for the verification function "
|
|
1426
|
+
f"{verification.name!r} is missing: {implementation_key}",
|
|
1427
|
+
)
|
|
1428
|
+
)
|
|
1429
|
+
else:
|
|
1430
|
+
blocks.append(implementation)
|
|
1431
|
+
|
|
1432
|
+
elif isinstance(verification, intermediate.PatternVerification):
|
|
1433
|
+
implementation, error = _transpile_pattern_verification(
|
|
1434
|
+
verification=verification
|
|
1435
|
+
)
|
|
1436
|
+
|
|
1437
|
+
if error is not None:
|
|
1438
|
+
errors.append(error)
|
|
1439
|
+
else:
|
|
1440
|
+
assert implementation is not None
|
|
1441
|
+
blocks.append(implementation)
|
|
1442
|
+
|
|
1443
|
+
elif isinstance(verification, intermediate.TranspilableVerification):
|
|
1444
|
+
implementation, error = _transpile_transpilable_verification(
|
|
1445
|
+
verification=verification,
|
|
1446
|
+
symbol_table=symbol_table,
|
|
1447
|
+
environment=base_environment,
|
|
1448
|
+
)
|
|
1449
|
+
|
|
1450
|
+
if error is not None:
|
|
1451
|
+
errors.append(error)
|
|
1452
|
+
else:
|
|
1453
|
+
assert implementation is not None
|
|
1454
|
+
blocks.append(implementation)
|
|
1455
|
+
|
|
1456
|
+
else:
|
|
1457
|
+
assert_never(verification)
|
|
1458
|
+
|
|
1459
|
+
for cls in symbol_table.concrete_classes:
|
|
1460
|
+
block, underlying_errors = _generate_verify_class(
|
|
1461
|
+
cls=cls, symbol_table=symbol_table, base_environment=base_environment
|
|
1462
|
+
)
|
|
1463
|
+
if underlying_errors is not None:
|
|
1464
|
+
errors.append(
|
|
1465
|
+
Error(
|
|
1466
|
+
cls.parsed.node,
|
|
1467
|
+
f"Failed to generate the verification for the class {cls.name!r}",
|
|
1468
|
+
underlying_errors,
|
|
1469
|
+
)
|
|
1470
|
+
)
|
|
1471
|
+
else:
|
|
1472
|
+
assert block is not None
|
|
1473
|
+
blocks.append(block)
|
|
1474
|
+
|
|
1475
|
+
for constrained_primitive in symbol_table.constrained_primitives:
|
|
1476
|
+
block, underlying_errors = _generate_verify_constrained_primitive(
|
|
1477
|
+
constrained_primitive=constrained_primitive,
|
|
1478
|
+
symbol_table=symbol_table,
|
|
1479
|
+
base_environment=base_environment,
|
|
1480
|
+
)
|
|
1481
|
+
if underlying_errors is not None:
|
|
1482
|
+
errors.append(
|
|
1483
|
+
Error(
|
|
1484
|
+
constrained_primitive.parsed.node,
|
|
1485
|
+
f"Failed to generate the verification for "
|
|
1486
|
+
f"the constrained primitive {constrained_primitive.name!r}",
|
|
1487
|
+
underlying_errors,
|
|
1488
|
+
)
|
|
1489
|
+
)
|
|
1490
|
+
else:
|
|
1491
|
+
assert block is not None
|
|
1492
|
+
blocks.append(block)
|
|
1493
|
+
|
|
1494
|
+
blocks.append(_generate_verify(symbol_table=symbol_table))
|
|
1495
|
+
|
|
1496
|
+
blocks.append(golang_common.WARNING)
|
|
1497
|
+
|
|
1498
|
+
if len(errors) > 0:
|
|
1499
|
+
return None, errors
|
|
1500
|
+
|
|
1501
|
+
writer = io.StringIO()
|
|
1502
|
+
for i, block in enumerate(blocks):
|
|
1503
|
+
if i > 0:
|
|
1504
|
+
writer.write("\n\n")
|
|
1505
|
+
|
|
1506
|
+
writer.write(block)
|
|
1507
|
+
|
|
1508
|
+
writer.write("\n")
|
|
1509
|
+
|
|
1510
|
+
return writer.getvalue(), None
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
# endregion
|