├── .dockerignore ├── atdcpp ├── .gitignore ├── test │ ├── .gitignore │ ├── dune │ └── cpp-tests │ │ └── dune ├── src │ ├── lib │ │ ├── dune │ │ ├── Version.ml │ │ ├── Codegen.mli │ │ └── Indent.mli │ └── bin │ │ └── dune └── Makefile ├── atdd ├── .gitignore ├── src │ ├── lib │ │ ├── Version.ml │ │ ├── dune │ │ ├── Codegen.mli │ │ ├── Indent.mli │ │ └── Dlang_annot.mli │ └── bin │ │ └── dune ├── test │ ├── .gitignore │ ├── dune │ └── dlang-tests │ │ └── dune ├── Makefile └── README.md ├── atddiff ├── .gitignore ├── test │ ├── default │ │ ├── unchanged.expected.txt │ │ ├── recursive_types.expected.txt │ │ ├── ignored_type_parameters_are_ok.expected.txt │ │ ├── unchanged_renamed_nonroot_type.expected.txt │ │ ├── type_arity_change_new.atd │ │ ├── forward_incompatible_variant_old.atd │ │ ├── type_arity_change_old.atd │ │ ├── backward_incompatible_variant_new.atd │ │ ├── forward_incompatible_variant_new.atd │ │ ├── backward_incompatible_variant_old.atd │ │ ├── ignored_type_parameters_are_ok_new.atd │ │ ├── ignored_type_parameters_are_ok_old.atd │ │ ├── json_repr_change_old.atd │ │ ├── json_field_name_change_new.atd │ │ ├── json_field_name_change_old.atd │ │ ├── backward_incompatible_record_old.atd │ │ ├── forward_incompatible_record_new.atd │ │ ├── json_repr_change_new.atd │ │ ├── backward_incompatible_record_new.atd │ │ ├── forward_incompatible_record_old.atd │ │ ├── backward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── backward_incompatible_record_if_implicit_defaults_old.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_old.atd │ │ ├── json_variant_name_change_new.atd │ │ ├── json_variant_name_change_old.atd │ │ ├── swapped_type_parameters_new.atd │ │ ├── swapped_type_parameters_old.atd │ │ ├── unchanged_renamed_nonroot_type_old.atd │ │ ├── unchanged_renamed_nonroot_type_new.atd │ │ ├── recursive.expected.txt │ │ ├── forward_incompatible_variant.expected.txt │ │ ├── backward_incompatible_variant.expected.txt │ │ ├── changed_renamed_new.atd │ │ ├── changed_renamed_old.atd │ │ ├── type_name_change_old.atd │ │ ├── type_name_change_new.atd │ │ ├── type_arity_change.expected.txt │ │ ├── json_repr_change.expected.txt │ │ ├── recursive_types_new.atd │ │ ├── recursive_types_old.atd │ │ ├── swapped_type_parameters.expected.txt │ │ ├── changed_renamed.expected.txt │ │ ├── recursive_new.atd │ │ ├── recursive_old.atd │ │ ├── unchanged_old.atd │ │ ├── backward_incompatible_record.expected.txt │ │ ├── forward_incompatible_record.expected.txt │ │ ├── unchanged_new.atd │ │ ├── backward_incompatible_record_if_implicit_defaults.expected.txt │ │ ├── forward_incompatible_record_if_implicit_defaults.expected.txt │ │ ├── json_field_name_change.expected.txt │ │ └── type_name_change.expected.txt │ ├── version │ │ ├── version.expected.txt │ │ └── dune │ ├── no_locations_text │ │ ├── simple_old.atd │ │ ├── simple_new.atd │ │ ├── same_hash_new.atd │ │ ├── same_hash_old.atd │ │ ├── ordering_new.atd │ │ ├── ordering_old.atd │ │ ├── simple.expected.txt │ │ ├── same_hash.expected.txt │ │ ├── ordering.expected.txt │ │ └── dune │ ├── no_locations_json │ │ ├── simple_new.atd │ │ ├── simple_old.atd │ │ ├── ordering_new.atd │ │ ├── ordering_old.atd │ │ ├── same_hash_new.atd │ │ ├── same_hash_old.atd │ │ ├── simple.expected.txt │ │ ├── same_hash.expected.txt │ │ └── dune │ ├── json_defaults │ │ ├── forward_incompatible_record_if_implicit_defaults.expected.txt │ │ ├── backward_incompatible_record_if_implicit_defaults.expected.txt │ │ ├── backward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── backward_incompatible_record_if_implicit_defaults_old.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_old.atd │ │ └── dune │ ├── safe_ignore_error1 │ │ ├── safe_ignore_new.atd │ │ ├── safe_ignore_old.atd │ │ ├── safe_ignore.expected.txt │ │ └── dune │ ├── safe_ignore_error2 │ │ ├── safe_ignore_new.atd │ │ ├── safe_ignore_old.atd │ │ ├── safe_ignore.expected.txt │ │ └── dune │ ├── json_defaults_new │ │ ├── forward_incompatible_record_if_implicit_defaults.expected.txt │ │ ├── backward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── backward_incompatible_record_if_implicit_defaults_old.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_old.atd │ │ ├── backward_incompatible_record_if_implicit_defaults.expected.txt │ │ └── dune │ ├── json_defaults_old │ │ ├── backward_incompatible_record_if_implicit_defaults.expected.txt │ │ ├── backward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── backward_incompatible_record_if_implicit_defaults_old.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_new.atd │ │ ├── forward_incompatible_record_if_implicit_defaults_old.atd │ │ ├── forward_incompatible_record_if_implicit_defaults.expected.txt │ │ └── dune │ ├── filter │ │ ├── filter.expected.txt │ │ ├── filter_new.atd │ │ ├── filter_old.atd │ │ └── dune │ ├── filter_backward │ │ ├── filter_old.atd │ │ ├── filter_new.atd │ │ ├── dune │ │ └── filter.expected.txt │ ├── filter_forward │ │ ├── filter_old.atd │ │ ├── filter_new.atd │ │ ├── dune │ │ └── filter.expected.txt │ ├── safe_ignore │ │ ├── safe_ignore_new.atd │ │ ├── safe_ignore_old.atd │ │ ├── safe_ignore.expected.txt │ │ └── dune │ ├── json_output │ │ ├── dune │ │ ├── all_errors_old.atd │ │ └── all_errors_new.atd │ └── Makefile ├── src │ ├── lib │ │ ├── Version.ml │ │ ├── dune │ │ ├── Format_JSON.mli │ │ ├── Format_text.mli │ │ ├── Loc.mli │ │ ├── Makefile │ │ ├── Compare.mli │ │ ├── Root_types.mli │ │ ├── Atddiff_output_t.ml │ │ └── Atddiff_output_t.mli │ └── bin │ │ └── dune ├── README.md └── Makefile ├── atdpy ├── .gitignore ├── test │ ├── atd-input │ │ └── ALLCAPS.atd │ ├── .gitignore │ ├── dune │ └── python-tests │ │ ├── deco.py │ │ └── dune ├── src │ ├── lib │ │ ├── Version.ml │ │ ├── dune │ │ ├── Codegen.mli │ │ └── Indent.mli │ ├── bin │ │ └── dune │ └── test │ │ ├── dune │ │ └── Main.ml └── Makefile ├── atdts ├── .gitignore ├── test │ ├── .gitignore │ ├── ts-tests │ │ ├── tslint.json │ │ ├── .gitignore │ │ ├── package.json │ │ ├── tsconfig.json │ │ ├── .eslintrc.json │ │ ├── dune │ │ └── Makefile │ └── gen-expect-tests │ │ ├── import.atd │ │ └── dune ├── src │ ├── lib │ │ ├── Version.ml │ │ ├── dune │ │ ├── Codegen.mli │ │ ├── TS_annot.ml │ │ ├── Indent.mli │ │ └── TS_annot.mli │ ├── bin │ │ └── dune │ └── test │ │ ├── dune │ │ └── Main.ml ├── Makefile └── README.md ├── .agignore ├── atdgen ├── src │ ├── version.ml │ ├── dune │ ├── validate.mli │ ├── ox_mapping.mli │ ├── xb_emit.mli │ ├── ob_spe.ml │ ├── ob_mapping.mli │ ├── ov_mapping.mli │ ├── error.mli │ ├── doc_lexer.mli │ ├── oj_mapping.mli │ ├── omelange_emit.mli │ ├── ob_emit.mli │ ├── ov_emit.mli │ ├── error.ml │ ├── oj_emit.mli │ ├── ox_mapping.ml │ ├── biniou.mli │ ├── indent.mli │ └── indent.ml ├── test │ ├── test_unit_biniou.atd │ ├── test_ocaml_keyword_error1.atd │ ├── test_annot_error.expected.stdout │ ├── melange │ │ ├── a_t.ml │ │ ├── a_j.ml │ │ ├── a_mel.ml │ │ └── dune │ ├── test_ocaml_keyword_error1.expected.stdout │ ├── test_ocaml_keyword_error2.atd │ ├── test_ocaml_keyword_error2.expected.stdout │ ├── test_poly_inline_record_error.atd │ ├── test_poly_inline_record_error.expected.stdout │ ├── test_polymorphic_wrap.atd │ ├── array_wrap.ml │ ├── test_classic_inline_record.atd │ ├── test_ppx.atd │ ├── json_adapters.ml │ ├── test_annot_error.atd │ ├── test_ocaml_keyword_error2.expected.stderr │ ├── test_polymorphic_wrap_t.expected.ml │ ├── test_ocaml_keyword_error1.expected.stderr │ ├── test_classic_inline_record_t.expected.ml │ ├── test_classic_inline_record_t.expected.mli │ ├── test_poly_inline_record_error.expected.stderr │ ├── test_ambiguous_record.atd │ ├── test_annot_t.expected.ml │ ├── test_annot_t.expected.mli │ ├── test_int_with_string_repr.atd │ ├── test_int.atd │ ├── test2.atd │ ├── test_annot_error.expected.stderr │ ├── test_abstract_t.expected.ml │ ├── test_abstract_t.expected.mli │ ├── test_annot.atd │ ├── test_ambiguous_variant.atd │ ├── test_abstract.atd │ ├── test5.atd │ ├── test_abstract_v.expected.ml │ ├── test_classic_inline_record_j.expected.mli │ ├── spec_js │ │ ├── spec_j.expected.json │ │ ├── spec_mel.expected.json │ │ ├── test_mel.ml │ │ ├── dune │ │ ├── test_j.ml │ │ └── spec.atd │ ├── test3j_t.expected.ml │ └── test3j_t.expected.mli ├── atdj.descr ├── bin │ └── dune ├── Makefile ├── atdgen-runtime.descr ├── example │ ├── format_v1.atd │ ├── Makefile │ ├── format_v2.atd │ ├── README │ └── example.sh ├── atd.descr ├── README.md ├── atdgen.descr ├── util │ └── recompile-deps └── TODO.md ├── atdgen-runtime ├── src │ ├── version.ml │ ├── dune │ ├── ov_run.mli │ └── ov_run.ml └── Makefile ├── scripts ├── README.md └── install-opam-dependencies ├── atdj ├── test │ ├── expected │ │ ├── package.html │ │ ├── Atdj.java │ │ ├── SimpleRecord.java │ │ └── B.java │ ├── json.jar │ ├── junit-4.8.2.jar │ ├── com │ │ └── mylife │ │ │ └── test │ │ │ └── dune │ ├── run_test.sh │ └── test.atd ├── src │ ├── dune │ └── atdj_env.ml ├── AUTHORS ├── Makefile ├── TODO ├── README.md └── doc │ ├── OMakefile │ └── readme.tex ├── doc ├── atdgen-tutorial-data │ ├── untypable-json │ │ ├── untypable.atd │ │ ├── untypable_v3.atd │ │ ├── untypable_v2.atd │ │ ├── input.json │ │ └── untypable_v1.atd │ ├── modularity │ │ ├── part1.atd │ │ ├── run.t │ │ ├── part3.atd │ │ ├── main.ml │ │ ├── part2.atd │ │ ├── demo.sh │ │ └── dune │ ├── hello │ │ ├── run.t │ │ ├── hello.atd │ │ ├── hello.ml │ │ ├── dune │ │ └── demo.sh │ ├── Makefile │ ├── pretty-json │ │ ├── single.json │ │ ├── stream.json │ │ ├── dune │ │ ├── prettify.ml │ │ ├── demo.sh │ │ └── run.t │ ├── inspect-biniou │ │ ├── tree.atd │ │ ├── demo.sh │ │ ├── dune │ │ └── tree.ml │ ├── config-file │ │ ├── bad-config1.json │ │ ├── sample-config.json │ │ ├── bad-config2.json │ │ ├── config.atd │ │ ├── dune │ │ └── demo.sh │ └── validate │ │ ├── resume.atd │ │ ├── dune │ │ ├── demo.sh │ │ ├── run.t │ │ └── resume.ml ├── atds.rst ├── requirements.txt ├── atdgen.rst ├── atd-language.rst ├── index.rst └── atd-project.rst ├── atdgen-cppo ├── dune ├── example.ml └── cppo-json ├── atds ├── test │ ├── junit-4.8.2.jar │ ├── argonaut_2.11-6.2.2.jar │ ├── argonaut_2.12-6.2.2.jar │ ├── run_test.sh │ ├── dune │ └── AtdsTest.scala ├── src │ ├── dune │ ├── atds_env.ml │ ├── atds_helper.ml │ └── atds_util.ml ├── AUTHORS ├── Makefile ├── TODO └── README.md ├── atdgen-codec-runtime └── src │ ├── dune │ ├── json.mli │ ├── json.ml │ ├── encode.mli │ ├── decode.mli │ └── json_adapter.ml ├── atd ├── Makefile ├── src │ ├── version.ml │ ├── doc_types.ml │ ├── predef.mli │ ├── dune │ ├── check.mli │ ├── loc.mli │ ├── reflect.mli │ ├── inherit.mli │ ├── loc.ml │ ├── print.mli │ ├── jsonschema.mli │ └── predef.ml └── test │ ├── dune │ ├── unit_tests.ml │ └── doc.ml ├── atdcat ├── src │ └── dune ├── Makefile ├── README.md └── test │ ├── data.json │ ├── test2.expected.atd │ ├── test2.atd │ └── schema.atd ├── .github └── pull_request_template.md ├── dune-workspace.dev ├── atd.opam.template ├── dockerfiles ├── atd.dockerfile └── atd-deps.dockerfile ├── .gitignore ├── .circleci ├── setup-opam └── config.yml ├── .readthedocs.yaml ├── dune ├── .ocp-indent └── manual └── Makefile /.dockerignore: -------------------------------------------------------------------------------- 1 | **/_build 2 | -------------------------------------------------------------------------------- /atdcpp/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /atdd/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /atddiff/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /atdpy/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /atdts/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | -------------------------------------------------------------------------------- /atdpy/test/atd-input/ALLCAPS.atd: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.agignore: -------------------------------------------------------------------------------- 1 | *.expected.mli? 2 | expected/ -------------------------------------------------------------------------------- /atddiff/test/default/unchanged.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atdgen/src/version.ml: -------------------------------------------------------------------------------- 1 | ../../atd/src/version.ml -------------------------------------------------------------------------------- /atdts/test/.gitignore: -------------------------------------------------------------------------------- 1 | everything.ts 2 | *.js 3 | -------------------------------------------------------------------------------- /atdd/src/lib/Version.ml: -------------------------------------------------------------------------------- 1 | ../../../atd/src/version.ml -------------------------------------------------------------------------------- /atddiff/src/lib/Version.ml: -------------------------------------------------------------------------------- 1 | ../../../atd/src/version.ml -------------------------------------------------------------------------------- /atddiff/test/default/recursive_types.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atdgen-runtime/src/version.ml: -------------------------------------------------------------------------------- 1 | ../../atd/src/version.ml -------------------------------------------------------------------------------- /atdgen/test/test_unit_biniou.atd: -------------------------------------------------------------------------------- 1 | type t = unit 2 | -------------------------------------------------------------------------------- /atdpy/src/lib/Version.ml: -------------------------------------------------------------------------------- 1 | ../../../atd/src/version.ml -------------------------------------------------------------------------------- /atdts/src/lib/Version.ml: -------------------------------------------------------------------------------- 1 | ../../../atd/src/version.ml -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | Various maintenance scripts 2 | -------------------------------------------------------------------------------- /atddiff/test/version/version.expected.txt: -------------------------------------------------------------------------------- 1 | %%VERSION%% 2 | -------------------------------------------------------------------------------- /atdj/test/expected/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /atdpy/test/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | everything.py 3 | -------------------------------------------------------------------------------- /atdcpp/test/.gitignore: -------------------------------------------------------------------------------- 1 | !cpp-expected/ 2 | cpp-tests/*.d 3 | -------------------------------------------------------------------------------- /atdd/test/.gitignore: -------------------------------------------------------------------------------- 1 | !dlang-expected/ 2 | dlang-tests/*.d 3 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/simple_old.atd: -------------------------------------------------------------------------------- 1 | type t = int 2 | -------------------------------------------------------------------------------- /atdgen/test/test_ocaml_keyword_error1.atd: -------------------------------------------------------------------------------- 1 | type then = int 2 | -------------------------------------------------------------------------------- /atddiff/test/default/ignored_type_parameters_are_ok.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atddiff/test/default/unchanged_renamed_nonroot_type.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/simple_new.atd: -------------------------------------------------------------------------------- 1 | type t = string 2 | -------------------------------------------------------------------------------- /atdgen/test/test_annot_error.expected.stdout: -------------------------------------------------------------------------------- 1 | Failed succesfully! 2 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/untypable-json/untypable.atd: -------------------------------------------------------------------------------- 1 | untypable_v3.atd -------------------------------------------------------------------------------- /atdgen/test/melange/a_t.ml: -------------------------------------------------------------------------------- 1 | type from_module_a = 2 | | Foo 3 | | Bar 4 | -------------------------------------------------------------------------------- /atdgen/test/test_ocaml_keyword_error1.expected.stdout: -------------------------------------------------------------------------------- 1 | Failed succesfully! 2 | -------------------------------------------------------------------------------- /atdgen/test/test_ocaml_keyword_error2.atd: -------------------------------------------------------------------------------- 1 | type t = { 2 | if : int; 3 | } 4 | -------------------------------------------------------------------------------- /atdgen/test/test_ocaml_keyword_error2.expected.stdout: -------------------------------------------------------------------------------- 1 | Failed succesfully! 2 | -------------------------------------------------------------------------------- /atdts/src/lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name atdts) 3 | (libraries re atd)) 4 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/simple_new.atd: -------------------------------------------------------------------------------- 1 | ../no_locations_text/simple_new.atd -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/simple_old.atd: -------------------------------------------------------------------------------- 1 | ../no_locations_text/simple_old.atd -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/same_hash_new.atd: -------------------------------------------------------------------------------- 1 | type t = (string * string) 2 | -------------------------------------------------------------------------------- /atdgen/test/test_poly_inline_record_error.atd: -------------------------------------------------------------------------------- 1 | type foo = [ Foo of {x: int} ] 2 | -------------------------------------------------------------------------------- /atdgen/test/test_poly_inline_record_error.expected.stdout: -------------------------------------------------------------------------------- 1 | Failed succesfully! 2 | -------------------------------------------------------------------------------- /atdts/test/ts-tests/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended" 3 | } 4 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/modularity/part1.atd: -------------------------------------------------------------------------------- 1 | type t = { x : int; y : int } 2 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults/forward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/ordering_new.atd: -------------------------------------------------------------------------------- 1 | ../no_locations_text/ordering_new.atd -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/ordering_old.atd: -------------------------------------------------------------------------------- 1 | ../no_locations_text/ordering_old.atd -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/same_hash_new.atd: -------------------------------------------------------------------------------- 1 | ../no_locations_text/same_hash_new.atd -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/same_hash_old.atd: -------------------------------------------------------------------------------- 1 | ../no_locations_text/same_hash_old.atd -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error1/safe_ignore_new.atd: -------------------------------------------------------------------------------- 1 | ../safe_ignore/safe_ignore_new.atd -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error1/safe_ignore_old.atd: -------------------------------------------------------------------------------- 1 | ../safe_ignore/safe_ignore_old.atd -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error2/safe_ignore_new.atd: -------------------------------------------------------------------------------- 1 | ../safe_ignore/safe_ignore_new.atd -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error2/safe_ignore_old.atd: -------------------------------------------------------------------------------- 1 | ../safe_ignore/safe_ignore_old.atd -------------------------------------------------------------------------------- /doc/atds.rst: -------------------------------------------------------------------------------- 1 | ******************** 2 | Scala Support - atds 3 | ******************** 4 | -------------------------------------------------------------------------------- /atddiff/test/default/type_arity_change_new.atd: -------------------------------------------------------------------------------- 1 | type 'a type_arity_change = ('a * 'a) list 2 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults/backward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults_new/forward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults_old/backward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /atdd/src/lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name atdd) 3 | (libraries 4 | re 5 | atd 6 | ) 7 | ) 8 | -------------------------------------------------------------------------------- /atdgen/test/test_polymorphic_wrap.atd: -------------------------------------------------------------------------------- 1 | type 'a t = 'a list wrap 2 | -------------------------------------------------------------------------------- /atdj/test/json.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Leonidas-from-XIV/atd/master/atdj/test/json.jar -------------------------------------------------------------------------------- /atdts/test/gen-expect-tests/import.atd: -------------------------------------------------------------------------------- 1 | type import_default = bool 2 | type import = string 3 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/hello/run.t: -------------------------------------------------------------------------------- 1 | $ ./hello.exe 2 | {"year":1970,"month":1,"day":1} 3 | -------------------------------------------------------------------------------- /atdcpp/src/lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name atdcpp) 3 | (libraries 4 | re 5 | atd 6 | ) 7 | ) 8 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_variant_old.atd: -------------------------------------------------------------------------------- 1 | type forward_incompatible_variant = [ A ] 2 | -------------------------------------------------------------------------------- /atddiff/test/default/type_arity_change_old.atd: -------------------------------------------------------------------------------- 1 | type ('a, 'b) type_arity_change = ('a * 'b) list 2 | -------------------------------------------------------------------------------- /atdpy/src/lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name atdpy) 3 | (libraries 4 | re 5 | atd 6 | ) 7 | ) 8 | -------------------------------------------------------------------------------- /atddiff/src/lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name atddiff) 3 | (libraries 4 | atd 5 | yojson 6 | ) 7 | ) 8 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_variant_new.atd: -------------------------------------------------------------------------------- 1 | type backward_incompatible_variant = [ A ] 2 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_variant_new.atd: -------------------------------------------------------------------------------- 1 | type forward_incompatible_variant = [ A | B ] 2 | -------------------------------------------------------------------------------- /atdgen-cppo/dune: -------------------------------------------------------------------------------- 1 | (install 2 | (section bin) 3 | (package atdgen) 4 | (files atdgen-cppo cppo-json)) 5 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_variant_old.atd: -------------------------------------------------------------------------------- 1 | type backward_incompatible_variant = [ A | B ] 2 | -------------------------------------------------------------------------------- /atddiff/test/default/ignored_type_parameters_are_ok_new.atd: -------------------------------------------------------------------------------- 1 | type 'a ignored_type_parameters_are_ok = 'a list 2 | -------------------------------------------------------------------------------- /atdgen/test/array_wrap.ml: -------------------------------------------------------------------------------- 1 | type 'a t = 'a array 2 | let wrap = Array.of_list 3 | let unwrap = Array.to_list 4 | -------------------------------------------------------------------------------- /atdgen/test/test_classic_inline_record.atd: -------------------------------------------------------------------------------- 1 | type foo = [ Foo of {x: int; y: float} ] 2 | -------------------------------------------------------------------------------- /atdj/test/junit-4.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Leonidas-from-XIV/atd/master/atdj/test/junit-4.8.2.jar -------------------------------------------------------------------------------- /atds/test/junit-4.8.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Leonidas-from-XIV/atd/master/atds/test/junit-4.8.2.jar -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | # We use cloud_sptheme because it allows advanced tables 2 | sphinx 3 | sphinx_rtd_theme 4 | -------------------------------------------------------------------------------- /atddiff/test/default/ignored_type_parameters_are_ok_old.atd: -------------------------------------------------------------------------------- 1 | type ('a, 'b) ignored_type_parameters_are_ok = 'a list 2 | -------------------------------------------------------------------------------- /atdgen-codec-runtime/src/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name atdgen_codec_runtime) 3 | (public_name atdgen-codec-runtime)) 4 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/hello/hello.atd: -------------------------------------------------------------------------------- 1 | type date = { 2 | year : int; 3 | month : int; 4 | day : int; 5 | } 6 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/modularity/run.t: -------------------------------------------------------------------------------- 1 | $ ./main.exe 2 | {"name":"foo","data":[{"x":1,"y":2},{"x":3,"y":4}]} 3 | -------------------------------------------------------------------------------- /atdgen/test/test_ppx.atd: -------------------------------------------------------------------------------- 1 | type t = { 2 | v: int; 3 | } 4 | -------------------------------------------------------------------------------- /atdj/src/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name atdj_main) 3 | (public_name atdj) 4 | (package atdj) 5 | (libraries re atd)) 6 | -------------------------------------------------------------------------------- /atds/src/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name atds_main) 3 | (public_name atds) 4 | (package atds) 5 | (libraries str atd)) 6 | -------------------------------------------------------------------------------- /atdgen/atdj.descr: -------------------------------------------------------------------------------- 1 | Java generator for atd files 2 | 3 | Generates java serializers and deserializers from atd type definitions. -------------------------------------------------------------------------------- /atdgen/test/melange/a_j.ml: -------------------------------------------------------------------------------- 1 | let write_from_module_a _ _ = () 2 | let read_from_module_a _lexer_state _lexbuf = failwith "" 3 | -------------------------------------------------------------------------------- /atds/test/argonaut_2.11-6.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Leonidas-from-XIV/atd/master/atds/test/argonaut_2.11-6.2.2.jar -------------------------------------------------------------------------------- /atds/test/argonaut_2.12-6.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Leonidas-from-XIV/atd/master/atds/test/argonaut_2.12-6.2.2.jar -------------------------------------------------------------------------------- /atdts/test/ts-tests/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /package-lock.json 3 | 4 | # Test output 5 | /aStr 6 | /bStr 7 | /bStr2 8 | -------------------------------------------------------------------------------- /atddiff/test/default/json_repr_change_old.atd: -------------------------------------------------------------------------------- 1 | type incompatible_record = { 2 | json_repr_changes: (string * int) list; 3 | } 4 | -------------------------------------------------------------------------------- /atdgen-runtime/src/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name atdgen_runtime) 3 | (public_name atdgen-runtime) 4 | (libraries biniou yojson)) 5 | -------------------------------------------------------------------------------- /atdgen/src/dune: -------------------------------------------------------------------------------- 1 | (ocamllex doc_lexer) 2 | 3 | (library 4 | (name atdgen_emit) 5 | (libraries atd biniou easy-format re yojson)) 6 | -------------------------------------------------------------------------------- /atddiff/test/default/json_field_name_change_new.atd: -------------------------------------------------------------------------------- 1 | type with_field_renames = { 2 | a : int; 3 | b : int; 4 | } 5 | -------------------------------------------------------------------------------- /atddiff/test/default/json_field_name_change_old.atd: -------------------------------------------------------------------------------- 1 | type with_field_renames = { 2 | a : int; 3 | b : int; 4 | } 5 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_record_old.atd: -------------------------------------------------------------------------------- 1 | type backward_incompatible_record = { 2 | ?becomes_required: int option; 3 | } 4 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_record_new.atd: -------------------------------------------------------------------------------- 1 | type forward_incompatible_record = { 2 | ?becomes_optional: int option; 3 | } 4 | -------------------------------------------------------------------------------- /atdgen/bin/dune: -------------------------------------------------------------------------------- 1 | (executables 2 | (libraries re atd atdgen_emit) 3 | (names ag_main) 4 | (public_names atdgen) 5 | (package atdgen)) 6 | -------------------------------------------------------------------------------- /atdts/src/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name Atdts_main) 3 | (public_name atdts) 4 | (package atdts) 5 | (libraries cmdliner atdts atd)) 6 | -------------------------------------------------------------------------------- /atdgen/test/json_adapters.ml: -------------------------------------------------------------------------------- 1 | (* Json adapters *) 2 | 3 | module Identity = struct 4 | let normalize x = x 5 | let restore x = x 6 | end 7 | -------------------------------------------------------------------------------- /atd/Makefile: -------------------------------------------------------------------------------- 1 | DUNE ?= dune 2 | 3 | .PHONY: build 4 | build: 5 | $(DUNE) build @all 6 | 7 | .PHONY: test 8 | test: 9 | $(DUNE) runtest -f 10 | -------------------------------------------------------------------------------- /atddiff/test/default/json_repr_change_new.atd: -------------------------------------------------------------------------------- 1 | type incompatible_record = { 2 | json_repr_changes: (string * int) list ; 3 | } 4 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults/backward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | ../default/backward_incompatible_record_if_implicit_defaults_new.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults/backward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | ../default/backward_incompatible_record_if_implicit_defaults_old.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults/forward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | ../default/forward_incompatible_record_if_implicit_defaults_new.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults/forward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | ../default/forward_incompatible_record_if_implicit_defaults_old.atd -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/same_hash_old.atd: -------------------------------------------------------------------------------- 1 | (* 2 | This test produces two findings with the same hash ID 3 | *) 4 | 5 | type t = (int * int) 6 | -------------------------------------------------------------------------------- /atdgen/Makefile: -------------------------------------------------------------------------------- 1 | DUNE ?= dune 2 | 3 | .PHONY: build 4 | build: 5 | $(DUNE) build 6 | 7 | .PHONY: test 8 | test: 9 | $(DUNE) runtest -f 10 | -------------------------------------------------------------------------------- /atdj/AUTHORS: -------------------------------------------------------------------------------- 1 | John Billings 2 | Martin Jambon 3 | and contributors that can be found in the git history. 4 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean 2 | clean: 3 | rm -f */*~ 4 | rm -f */*.cm[ioxa] */*.cmx[as] */*.[oa] */*_[tjv].mli */*_[tjv].ml 5 | -------------------------------------------------------------------------------- /atd/src/version.ml: -------------------------------------------------------------------------------- 1 | (* The version string is replaced by the actual version at release time 2 | by 'dune release'. *) 3 | let version = "%%VERSION%%" 4 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_record_new.atd: -------------------------------------------------------------------------------- 1 | type backward_incompatible_record = { 2 | added_field: int; 3 | becomes_required: int; 4 | } 5 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_record_old.atd: -------------------------------------------------------------------------------- 1 | type forward_incompatible_record = { 2 | removed_field: int; 3 | becomes_optional: int; 4 | } 5 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults_new/backward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | ../default/backward_incompatible_record_if_implicit_defaults_new.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults_new/backward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | ../default/backward_incompatible_record_if_implicit_defaults_old.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults_new/forward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | ../default/forward_incompatible_record_if_implicit_defaults_new.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults_new/forward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | ../default/forward_incompatible_record_if_implicit_defaults_old.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults_old/backward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | ../default/backward_incompatible_record_if_implicit_defaults_new.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults_old/backward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | ../default/backward_incompatible_record_if_implicit_defaults_old.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults_old/forward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | ../default/forward_incompatible_record_if_implicit_defaults_new.atd -------------------------------------------------------------------------------- /atddiff/test/json_defaults_old/forward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | ../default/forward_incompatible_record_if_implicit_defaults_old.atd -------------------------------------------------------------------------------- /atdgen/atdgen-runtime.descr: -------------------------------------------------------------------------------- 1 | Runtime for code generated by atdgen 2 | 3 | Code generated by the atdgen binary should copmile and link against this 4 | library. -------------------------------------------------------------------------------- /atd/src/doc_types.ml: -------------------------------------------------------------------------------- 1 | type inline = 2 | | Text of string 3 | | Code of string 4 | 5 | type block = 6 | | Paragraph of inline list 7 | | Pre of string 8 | -------------------------------------------------------------------------------- /atdcpp/src/lib/Version.ml: -------------------------------------------------------------------------------- 1 | (* The version string is replaced by the actual version at release time 2 | by 'dune release'. *) 3 | let version = "%%VERSION%%" 4 | -------------------------------------------------------------------------------- /atdgen/test/test_annot_error.atd: -------------------------------------------------------------------------------- 1 | type pointA = { 2 | f: float 3 | } 4 | -------------------------------------------------------------------------------- /atdts/src/test/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name Main) 3 | (libraries atdts alcotest)) 4 | 5 | (rule 6 | (alias runtest) 7 | (action 8 | (run ./Main.exe))) 9 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/modularity/part3.atd: -------------------------------------------------------------------------------- 1 | type t2 = abstract 2 | 3 | type t3 = { 4 | name : string; 5 | ?data : t2 option; 6 | } 7 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/pretty-json/single.json: -------------------------------------------------------------------------------- 1 | [1234,"abcde",{"start_date":{"year":1970,"month":1,"day":1}, 2 | "end_date":{"year":1980,"month":1,"day":1}}] 3 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/ordering_new.atd: -------------------------------------------------------------------------------- 1 | type a = string 2 | type b = string 3 | type c = string 4 | type d = string 5 | type e = string 6 | type f = string 7 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/ordering_old.atd: -------------------------------------------------------------------------------- 1 | type a = int 2 | type b = int list 3 | type c = (b * b) 4 | type d = (a * b) 5 | type e = c list 6 | type f = d list 7 | -------------------------------------------------------------------------------- /atdgen-cppo/example.ml: -------------------------------------------------------------------------------- 1 | #ext json 2 | type mytype = string list 3 | #endext 4 | let data = [ "Hello"; "world" ] 5 | let () = print_endline (J.string_of_mytype data) 6 | -------------------------------------------------------------------------------- /atdgen-runtime/Makefile: -------------------------------------------------------------------------------- 1 | DUNE ?= dune 2 | 3 | .PHONY: build 4 | build: 5 | $(DUNE) build @all 6 | 7 | .PHONY: test 8 | test: 9 | $(DUNE) runtest -f 10 | -------------------------------------------------------------------------------- /atdd/src/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name Atdd_main) 3 | (public_name atdd) 4 | (package atdd) 5 | (libraries 6 | cmdliner 7 | atdd 8 | atd 9 | ) 10 | ) 11 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | type backward_incompatible_record_if_implicit_defaults = { 2 | becomes_required: int; 3 | } 4 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | type backward_incompatible_record_if_implicit_defaults = { 2 | ~becomes_required: int; 3 | } 4 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_record_if_implicit_defaults_new.atd: -------------------------------------------------------------------------------- 1 | type forward_incompatible_record_if_implicit_defaults = { 2 | ~becomes_optional: int; 3 | } 4 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_record_if_implicit_defaults_old.atd: -------------------------------------------------------------------------------- 1 | type forward_incompatible_record_if_implicit_defaults = { 2 | becomes_optional: int; 3 | } 4 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/hello/hello.ml: -------------------------------------------------------------------------------- 1 | open Hello_t 2 | let () = 3 | let date = { year = 1970; month = 1; day = 1 } in 4 | print_endline (Hello_j.string_of_date date) 5 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/pretty-json/stream.json: -------------------------------------------------------------------------------- 1 | [1234,"abcde",{"start_date":{"year":1970,"month":1,"day":1}, 2 | "end_date":{"year":1980,"month":1,"day":1}}] 3 | [1,"a",{}] 4 | -------------------------------------------------------------------------------- /doc/atdgen.rst: -------------------------------------------------------------------------------- 1 | ********************** 2 | OCaml Support - atdgen 3 | ********************** 4 | 5 | .. include:: atdgen-tutorial.rst 6 | .. include:: atdgen-reference.rst 7 | -------------------------------------------------------------------------------- /atdcat/src/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name atdcat) 3 | (public_name atdcat) 4 | (package atd) 5 | (libraries 6 | atd 7 | easy-format 8 | re 9 | ) 10 | ) 11 | -------------------------------------------------------------------------------- /atdgen/test/test_ocaml_keyword_error2.expected.stderr: -------------------------------------------------------------------------------- 1 | File "test_ocaml_keyword_error2.atd", line 2, characters 2-10: 2 | "if" cannot be used as field name (reserved OCaml keyword) 3 | -------------------------------------------------------------------------------- /atdgen/test/test_polymorphic_wrap_t.expected.ml: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_polymorphic_wrap.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type 'a t = 'a Array_wrap.t 5 | -------------------------------------------------------------------------------- /atdpy/src/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name Atdpy_main) 3 | (public_name atdpy) 4 | (package atdpy) 5 | (libraries 6 | cmdliner 7 | atdpy 8 | atd 9 | ) 10 | ) 11 | -------------------------------------------------------------------------------- /atds/AUTHORS: -------------------------------------------------------------------------------- 1 | Ivan Jager 2 | John Billings 3 | Martin Jambon 4 | and contributors that can be found in the git history. 5 | -------------------------------------------------------------------------------- /atdcpp/src/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name atdcpp_main) 3 | (public_name atdcpp) 4 | (package atdcpp) 5 | (libraries 6 | cmdliner 7 | atdcpp 8 | atd 9 | ) 10 | ) 11 | -------------------------------------------------------------------------------- /atddiff/test/default/json_variant_name_change_new.atd: -------------------------------------------------------------------------------- 1 | type with_constructor_renames = [ 2 | | A 3 | | B of int 4 | | C 5 | | D of int 6 | ] 7 | -------------------------------------------------------------------------------- /atddiff/test/default/json_variant_name_change_old.atd: -------------------------------------------------------------------------------- 1 | type with_constructor_renames = [ 2 | | A 3 | | B of int 4 | | C 5 | | D of int 6 | ] 7 | -------------------------------------------------------------------------------- /atdgen/example/format_v1.atd: -------------------------------------------------------------------------------- 1 | (* Older version of an imagined data format *) 2 | 3 | type t = { 4 | a : int option; 5 | b : bool; 6 | ?c : int option; 7 | ~d : float; 8 | } 9 | -------------------------------------------------------------------------------- /atdgen/test/test_ocaml_keyword_error1.expected.stderr: -------------------------------------------------------------------------------- 1 | File "test_ocaml_keyword_error1.atd", line 1, characters 0-15: 2 | "then" cannot be used as type name (reserved OCaml keyword) 3 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### PR checklist 2 | 3 | - [ ] New code has tests to catch future regressions 4 | - [ ] Documentation is up-to-date 5 | - [ ] `CHANGES.md` is up-to-date 6 | -------------------------------------------------------------------------------- /atddiff/src/bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name Atddiff_main) 3 | (public_name atddiff) 4 | (package atd) 5 | (libraries 6 | cmdliner 7 | atddiff 8 | atd 9 | ) 10 | ) 11 | -------------------------------------------------------------------------------- /atddiff/test/default/swapped_type_parameters_new.atd: -------------------------------------------------------------------------------- 1 | type ('a, 'b) unchanged_type_parameters = { x: ('a * 'b) list } 2 | 3 | type ('a, 'b) swapped_type_parameters = { x: ('b * 'a) list } 4 | -------------------------------------------------------------------------------- /atddiff/test/default/swapped_type_parameters_old.atd: -------------------------------------------------------------------------------- 1 | type ('k, 'v) unchanged_type_parameters = { x: ('k * 'v) list } 2 | 3 | type ('k, 'v) swapped_type_parameters = { x: ('k * 'v) list } 4 | -------------------------------------------------------------------------------- /atdgen/src/validate.mli: -------------------------------------------------------------------------------- 1 | (** ATD annotations relating to OCaml validators. *) 2 | 3 | type validate_repr = (string option * bool) 4 | 5 | val get_validator : Atd.Annot.t -> string option 6 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/pretty-json/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name prettify) 3 | (libraries atdgen-runtime yojson)) 4 | 5 | (cram 6 | (deps 7 | prettify.exe 8 | (glob_files *.json))) 9 | -------------------------------------------------------------------------------- /atddiff/src/lib/Format_JSON.mli: -------------------------------------------------------------------------------- 1 | (* 2 | Convert (tediously) the atddiff findings to JSON. 3 | *) 4 | 5 | val to_string : 6 | with_locations:bool -> 7 | Atddiff_output_t.result -> string 8 | -------------------------------------------------------------------------------- /atddiff/src/lib/Format_text.mli: -------------------------------------------------------------------------------- 1 | (* 2 | Format comparison results in a human-readable form 3 | *) 4 | 5 | val to_string : 6 | with_locations:bool -> 7 | Atddiff_output_t.result -> string 8 | -------------------------------------------------------------------------------- /atdj/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Java/JSON backend 3 | # 4 | 5 | DUNE ?= dune 6 | 7 | .PHONY: build 8 | build: 9 | $(DUNE) build @all 10 | 11 | .PHONY: test 12 | test: 13 | $(DUNE) runtest -f 14 | -------------------------------------------------------------------------------- /atds/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Scala/JSON backend 3 | # 4 | 5 | DUNE ?= dune 6 | 7 | .PHONY: build 8 | build: 9 | $(DUNE) build @all 10 | 11 | .PHONY: test 12 | test: 13 | $(DUNE) runtest -f 14 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/inspect-biniou/tree.atd: -------------------------------------------------------------------------------- 1 | (* This a binary tree. Just for the purpose of pretty-printing trees. *) 2 | type tree = 3 | [ Empty 4 | | Node of (tree * int * tree) ] 5 | 6 | -------------------------------------------------------------------------------- /atddiff/test/default/unchanged_renamed_nonroot_type_old.atd: -------------------------------------------------------------------------------- 1 | type root = { 2 | field: not_a_root_type list; 3 | } 4 | 5 | type not_a_root_type = not_a_root_type2 6 | 7 | type not_a_root_type2 = [ A ] 8 | -------------------------------------------------------------------------------- /atdgen/test/test_classic_inline_record_t.expected.ml: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_classic_inline_record.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type foo = Foo of { x: int; y: float } 5 | -------------------------------------------------------------------------------- /atdgen/test/test_classic_inline_record_t.expected.mli: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_classic_inline_record.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type foo = Foo of { x: int; y: float } 5 | -------------------------------------------------------------------------------- /atdpy/src/test/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name Main) 3 | (libraries 4 | atdpy 5 | alcotest 6 | ) 7 | ) 8 | 9 | (rule 10 | (alias runtest) 11 | (action (run ./Main.exe)) 12 | ) 13 | -------------------------------------------------------------------------------- /dune-workspace.dev: -------------------------------------------------------------------------------- 1 | (lang dune 1.0) 2 | ;; This file is used by `make all-supported-ocaml-versions` 3 | (context (opam (switch 4.04.2))) 4 | (context (opam (switch 4.05.0))) 5 | (context (opam (switch 4.06.1))) -------------------------------------------------------------------------------- /atd/test/dune: -------------------------------------------------------------------------------- 1 | (executables 2 | (libraries 3 | atd 4 | alcotest 5 | ) 6 | (names unit_tests)) 7 | 8 | (rule 9 | (alias runtest) 10 | (package atd) 11 | (action (run ./unit_tests.exe))) 12 | -------------------------------------------------------------------------------- /atdgen/test/test_poly_inline_record_error.expected.stderr: -------------------------------------------------------------------------------- 1 | File "test_poly_inline_record_error.atd", line 1, characters 13-28: 2 | Inline records are not allowed in polymorphic variants (not valid in OCaml) 3 | -------------------------------------------------------------------------------- /atd/src/predef.mli: -------------------------------------------------------------------------------- 1 | (** The collection of core types known by ATD. *) 2 | 3 | val list : (string * int * Ast.type_def option) list 4 | 5 | val make_table : unit -> (string, int * Ast.type_def option) Hashtbl.t 6 | -------------------------------------------------------------------------------- /atd.opam.template: -------------------------------------------------------------------------------- 1 | build: [ 2 | ["dune" "subst"] {dev} 3 | [ 4 | "dune" 5 | "build" 6 | "-p" 7 | name 8 | "-j" 9 | jobs 10 | "@install" 11 | "@doc" {with-doc} 12 | ] 13 | ] 14 | -------------------------------------------------------------------------------- /atdgen/test/test_ambiguous_record.atd: -------------------------------------------------------------------------------- 1 | type ambiguous = {ambiguous:string;not_ambiguous1:int} 2 | 3 | type ambiguous' = {ambiguous:string;not_ambiguous2:int} 4 | 5 | 6 | -------------------------------------------------------------------------------- /atd/src/dune: -------------------------------------------------------------------------------- 1 | (ocamllex lexer doc_lexer) 2 | (menhir (modules parser)) 3 | 4 | (library 5 | (name atd) 6 | (public_name atd) 7 | (libraries 8 | re 9 | easy-format 10 | unix 11 | yojson 12 | ) 13 | ) 14 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/simple.expected.txt: -------------------------------------------------------------------------------- 1 | [177fee07] Incompatibility in both directions: 2 | Type names 'int' and 'string' are not the same and may not be compatible. 3 | The following types are affected: 4 | t 5 | 6 | -------------------------------------------------------------------------------- /atdgen/src/ox_mapping.mli: -------------------------------------------------------------------------------- 1 | open Atd.Ast 2 | 3 | type analyze_field = 4 | { ocaml_default : string option 5 | ; unwrapped : bool 6 | } 7 | 8 | val analyze_field : Ocaml.target -> loc -> field_kind -> annot -> analyze_field 9 | -------------------------------------------------------------------------------- /doc/atd-language.rst: -------------------------------------------------------------------------------- 1 | **************** 2 | The ATD Language 3 | **************** 4 | 5 | .. include:: atd-language-reference.rst 6 | .. include:: atd-howto-protocol-upgrades.rst 7 | .. include:: atd-language-interoperability.rst 8 | -------------------------------------------------------------------------------- /atddiff/test/default/unchanged_renamed_nonroot_type_new.atd: -------------------------------------------------------------------------------- 1 | type root = { 2 | field: not_a_root_type_renamed list; 3 | } 4 | 5 | type not_a_root_type_renamed = not_a_root_type2_renamed 6 | 7 | type not_a_root_type2_renamed = [ A ] 8 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to ATD's documentation! 2 | =============================== 3 | 4 | .. toctree:: 5 | :maxdepth: 3 6 | 7 | atd-project 8 | atd-language 9 | atdgen 10 | atdj 11 | atds 12 | atdpy 13 | atdts 14 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/pretty-json/prettify.ml: -------------------------------------------------------------------------------- 1 | let json = 2 | "[1234,\"abcde\",{\"start_date\":{\"year\":1970,\"month\":1,\"day\":1}, 3 | \"end_date\":{\"year\":1980,\"month\":1,\"day\":1}}]" 4 | 5 | let () = print_endline (Yojson.Safe.prettify json) 6 | -------------------------------------------------------------------------------- /atddiff/test/default/recursive.expected.txt: -------------------------------------------------------------------------------- 1 | [0ad2992b] Forward incompatibility: 2 | File "recursive_new.atd", line 9, characters 52-53: 3 | Case 'B' is new. 4 | The following types are affected: 5 | changed_recursive 6 | depends_on_changed_recursive 7 | 8 | -------------------------------------------------------------------------------- /atdgen/src/xb_emit.mli: -------------------------------------------------------------------------------- 1 | (** Utilities for writing code generators for Biniou from a decorated 2 | ATD AST. *) 3 | 4 | type 'a def = ('a, Biniou.biniou_repr) Mapping.def 5 | type 'a grouped_defs = (bool * 'a def list) list 6 | 7 | val check : _ grouped_defs -> unit 8 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/untypable-json/untypable_v3.atd: -------------------------------------------------------------------------------- 1 | (* File untypable.atd *) 2 | 3 | type obj_list = obj list 4 | 5 | type obj = { 6 | ?label: string option; 7 | ?labels: string list option; 8 | value: abstract (* requires ATD >= 2.6.0 *) 9 | } 10 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_variant.expected.txt: -------------------------------------------------------------------------------- 1 | [24b8e793] Forward incompatibility: 2 | File "forward_incompatible_variant_new.atd", line 1, characters 42-43: 3 | Case 'B' is new. 4 | The following types are affected: 5 | forward_incompatible_variant 6 | 7 | -------------------------------------------------------------------------------- /atdgen/src/ob_spe.ml: -------------------------------------------------------------------------------- 1 | 2 | (* 3 | Optimization of the biniou representation 4 | *) 5 | 6 | let get_table_info deref x = 7 | match deref x with 8 | `Record y -> y 9 | | _ -> 10 | Error.error (Atd.Ast.loc_of_type_expr x) "Not a record type" 11 | -------------------------------------------------------------------------------- /atdcpp/src/lib/Codegen.mli: -------------------------------------------------------------------------------- 1 | (* 2 | C++ code generation for JSON support (no biniou support) 3 | *) 4 | 5 | (** Take ATD type definitions and translate them to C++, writing 6 | them out to a file which should have the '.d' extension. *) 7 | val run_file : string -> unit 8 | -------------------------------------------------------------------------------- /atdd/src/lib/Codegen.mli: -------------------------------------------------------------------------------- 1 | (* 2 | Dlang code generation for JSON support (no biniou support) 3 | *) 4 | 5 | (** Take ATD type definitions and translate them to Dlang, writing 6 | them out to a file which should have the '.d' extension. *) 7 | val run_file : string -> unit 8 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_variant.expected.txt: -------------------------------------------------------------------------------- 1 | [2e6e3829] Backward incompatibility: 2 | File "backward_incompatible_variant_old.atd", line 1, characters 43-44: 3 | Case 'B' disappeared. 4 | The following types are affected: 5 | backward_incompatible_variant 6 | 7 | -------------------------------------------------------------------------------- /atddiff/test/default/changed_renamed_new.atd: -------------------------------------------------------------------------------- 1 | (* 2 | The root type hasn't changed its name but a field uses 3 | a type that was renamed and has an incompatibility. 4 | *) 5 | 6 | type root_type = { 7 | field: new_name; 8 | } 9 | 10 | type new_name = [ A of float ] 11 | -------------------------------------------------------------------------------- /atddiff/test/default/changed_renamed_old.atd: -------------------------------------------------------------------------------- 1 | (* 2 | The root type hasn't changed its name but a field uses 3 | a type that was renamed and has an incompatibility. 4 | *) 5 | 6 | type root_type = { 7 | field: old_name; 8 | } 9 | 10 | type old_name = [ A of int ] 11 | -------------------------------------------------------------------------------- /atdgen/test/test_annot_t.expected.ml: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_annot.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type pointC = ProtoE_t.pointC = { f: float } 5 | 6 | type pointB = ProtoB_t.pointB = { f: float } 7 | 8 | type pointA = ProtoA_t.pointA = { f: float } 9 | -------------------------------------------------------------------------------- /atdgen/test/test_annot_t.expected.mli: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_annot.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type pointC = ProtoE_t.pointC = { f: float } 5 | 6 | type pointB = ProtoB_t.pointB = { f: float } 7 | 8 | type pointA = ProtoA_t.pointA = { f: float } 9 | -------------------------------------------------------------------------------- /atdpy/src/lib/Codegen.mli: -------------------------------------------------------------------------------- 1 | (* 2 | Python code generation for JSON support (no biniou support) 3 | *) 4 | 5 | (** Take ATD type definitions and translate them to Python, writing 6 | them out to a file which should have the '.py' extension. *) 7 | val run_file : string -> unit 8 | -------------------------------------------------------------------------------- /atdgen/example/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default 2 | default: 3 | ./example.sh 4 | 5 | .PHONY: clean 6 | rm -f *.cm[iox] *.o *.annot \ 7 | format_v[12].mli format_v[12].ml \ 8 | upgrade_demo upgrade_demo.exe \ 9 | old_sample.dat new_sample.dat \ 10 | old_data.dat new_data.dat 11 | -------------------------------------------------------------------------------- /atdgen/test/test_int_with_string_repr.atd: -------------------------------------------------------------------------------- 1 | type char = int 2 | type int32 = int 3 | type int64 = int 4 | type afloat = int 5 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/pretty-json/demo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | set -x 4 | cat single.json 5 | ydump single.json 6 | cat stream.json 7 | ydump -s stream.json 8 | 9 | cat prettify.ml 10 | ocamlfind ocamlopt -o prettify prettify.ml -package atdgen -linkpkg 11 | ./prettify 12 | -------------------------------------------------------------------------------- /atdts/src/lib/Codegen.mli: -------------------------------------------------------------------------------- 1 | (* 2 | TypeScript code generation for JSON support (no biniou support) 3 | *) 4 | 5 | (** Take ATD type definitions and translate them to TypeScript, writing 6 | them out to a file which should have the '.ts' extension. *) 7 | val run_file : string -> unit 8 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/config-file/bad-config1.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Example", 3 | "credentials": [ 4 | { 5 | "name": 0, 6 | "key": "db7c0877bdef3016" 7 | }, 8 | { 9 | "name": "tester", 10 | "key": "09871ff387ac2b10" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /atdcat/Makefile: -------------------------------------------------------------------------------- 1 | DUNE ?= dune 2 | 3 | .PHONY: build 4 | build: 5 | $(DUNE) build 6 | 7 | .PHONY: test 8 | test: 9 | $(DUNE) runtest -f 10 | 11 | # Show the expected JSON Schema in YAML format (for visual inspection) 12 | .PHONY: yaml 13 | yaml: 14 | yq e -P test/schema.expected.json 15 | -------------------------------------------------------------------------------- /atdgen/src/ob_mapping.mli: -------------------------------------------------------------------------------- 1 | (** OCaml-Biniou decorated ATD AST. *) 2 | 3 | type ob_mapping = 4 | (Ocaml.Repr.t, Biniou.biniou_repr) Mapping.mapping 5 | 6 | val defs_of_atd_modules 7 | : ('a * Atd.Ast.module_body) list 8 | -> ('a * (Ocaml.Repr.t, Biniou.biniou_repr) Mapping.def list) list 9 | -------------------------------------------------------------------------------- /dockerfiles/atd.dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Build the atd project from source. Uses an image with all the dependencies 3 | # already installed. 4 | # 5 | FROM atd-deps 6 | 7 | COPY --chown=opam:opam . atd 8 | WORKDIR /home/opam/atd 9 | 10 | RUN opam exec -- make 11 | RUN opam exec -- make test 12 | -------------------------------------------------------------------------------- /atd/src/check.mli: -------------------------------------------------------------------------------- 1 | (** Check the validity of an ATD file beyond syntax. 2 | 3 | For example, this checks that each type definition is unique. 4 | *) 5 | 6 | (** Check the validity of an ATD file. Raises an exception on the first 7 | error encountered. *) 8 | val check : Ast.module_body -> unit 9 | -------------------------------------------------------------------------------- /atdgen/test/test_int.atd: -------------------------------------------------------------------------------- 1 | type char = int (* json repr should default to the same type as atd (int) *) 2 | type int32 = int 3 | type int64 = int 4 | type afloat = int 5 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/config-file/sample-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Example", 3 | "credentials": [ 4 | { 5 | "name": "joeuser", 6 | "key": "db7c0877bdef3016" 7 | }, 8 | { 9 | "name": "tester", 10 | "key": "09871ff387ac2b10" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dockerfiles/atd-deps.dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Build an image with all the dependencies needed to build and test the atd 3 | # project offline. 4 | # 5 | FROM ocaml/opam:ubuntu-20.04-ocaml-4.13 6 | 7 | COPY .circleci/setup-* *.opam tmp/ 8 | RUN cd tmp && ./setup-system 9 | RUN cd tmp && ./setup-opam 10 | -------------------------------------------------------------------------------- /atddiff/test/default/type_name_change_old.atd: -------------------------------------------------------------------------------- 1 | (* Not detected as a rename but as a deleted/created type name. *) 2 | type old_name_for_root_type = int 3 | 4 | (* Undetected incompatibility. Reported as a deleted/created root type name. *) 5 | type old_name_for_root_type_with_changes = { 6 | x: int; 7 | } 8 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/modularity/main.ml: -------------------------------------------------------------------------------- 1 | let v = { 2 | Part3_t.name = "foo"; 3 | data = Some [ 4 | { Part1_t.x = 1; y = 2 }; 5 | { Part1_t.x = 3; y = 4 }; 6 | ] 7 | } 8 | 9 | let () = 10 | Atdgen_runtime.Util.Json.to_channel Part3_j.write_t3 stdout v; 11 | print_newline () 12 | -------------------------------------------------------------------------------- /atddiff/test/default/type_name_change_new.atd: -------------------------------------------------------------------------------- 1 | (* Not detected as a rename but as a deleted/created type name. *) 2 | type new_name_for_root_type = int 3 | 4 | (* Undetected incompatibility. Reported as a deleted/created root type name. *) 5 | type new_name_for_root_type_with_changes = { 6 | x: float; 7 | } 8 | -------------------------------------------------------------------------------- /atddiff/test/version/dune: -------------------------------------------------------------------------------- 1 | (rule 2 | (targets version.txt) 3 | (deps ) 4 | (action 5 | (with-stdout-to version.txt 6 | (run %{bin:atddiff} --version) 7 | ) 8 | ) 9 | ) 10 | 11 | (rule 12 | (alias runtest) 13 | (deps version.txt) 14 | (action (diff version.expected.txt version.txt))) 15 | -------------------------------------------------------------------------------- /atdgen/src/ov_mapping.mli: -------------------------------------------------------------------------------- 1 | (** Decorated ATD AST for OCaml validators. *) 2 | 3 | type ov_mapping = 4 | (Ocaml.Repr.t, Validate.validate_repr) Mapping.mapping 5 | 6 | val defs_of_atd_modules 7 | : ('a * Atd.Ast.module_body) list 8 | -> ('a * (Ocaml.Repr.t, Validate.validate_repr) Mapping.def list) list 9 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/config-file/bad-config2.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Example", 3 | "tiemout": 20, 4 | "credentials": [ 5 | { 6 | "name": "joeuser", 7 | "key": "db7c0877bdef3016" 8 | }, 9 | { 10 | "name": "tester", 11 | "key": "09871ff387ac2b10" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /atd/src/loc.mli: -------------------------------------------------------------------------------- 1 | (* 2 | A location is a region in a source file. 3 | *) 4 | 5 | type t = Lexing.position * Lexing.position 6 | 7 | (* Compare two locations so as to sort them by: 8 | 1. file path 9 | 2. start position in the file 10 | 3. end position in the file 11 | *) 12 | val compare : t -> t -> int 13 | -------------------------------------------------------------------------------- /atddiff/README.md: -------------------------------------------------------------------------------- 1 | atddiff 2 | ======= 3 | 4 | Atddiff is a command for anticipating incompatibilities between JSON 5 | data and data readers when modifying type definitions. 6 | 7 | 8 | 9 | 10 | See `atddiff --help` for examples and options. 11 | -------------------------------------------------------------------------------- /atddiff/test/filter/filter.expected.txt: -------------------------------------------------------------------------------- 1 | [099be5a3] Incompatibility in both directions: 2 | File "filter_old.atd", line 7, characters 16-20 3 | File "filter_new.atd", line 7, characters 16-23: 4 | Type names 'int' and 'string' are not the same and may not be compatible. 5 | The following types are affected: 6 | a 7 | b 8 | 9 | -------------------------------------------------------------------------------- /atdgen/test/test2.atd: -------------------------------------------------------------------------------- 1 | type ('aa, 'bb) poly 2 | = abstract 3 | 4 | type poly_int2 = (int, int) poly 5 | type poly_int_string = (int, string) poly 6 | 7 | type test2 = { 8 | test0 : poly_int2; 9 | test1 : (int, string option) poly 10 | } 11 | -------------------------------------------------------------------------------- /atdgen/atd.descr: -------------------------------------------------------------------------------- 1 | Parser for the ATD data format description language 2 | 3 | ATD is the OCaml library providing a parser for the ATD language and various 4 | utilities. ATD stands for Adjustable Type Definitions in reference to its main 5 | property of supporting annotations that allow a good fit with a variety of data 6 | formats. 7 | -------------------------------------------------------------------------------- /atdgen/test/melange/a_mel.ml: -------------------------------------------------------------------------------- 1 | let write_from_module_a = 2 | Atdgen_codec_runtime.Encode.make (function 3 | | A_t.Foo -> `String "Foo" 4 | | Bar -> `String "Bar") 5 | 6 | let read_from_module_a = 7 | Atdgen_codec_runtime.Decode.enum 8 | [ "Foo", `Single A_t.Foo 9 | ; "Bar", `Single A_t.Bar 10 | ] 11 | -------------------------------------------------------------------------------- /atdgen/test/test_annot_error.expected.stderr: -------------------------------------------------------------------------------- 1 | File "test_annot_error.atd", line 1, characters 19-32: 2 | Duplicate annotation ocaml.from (also in: 3 | File "test_annot_error.atd", line 1, characters 48-61, 4 | File "test_annot_error.atd", line 1, characters 70-83, 5 | File "test_annot_error.atd", line 1, characters 84-97 6 | ) 7 | -------------------------------------------------------------------------------- /atddiff/test/default/type_arity_change.expected.txt: -------------------------------------------------------------------------------- 1 | [319de7a2] Incompatibility in both directions: 2 | File "type_arity_change_old.atd", line 1, characters 0-48 3 | File "type_arity_change_new.atd", line 1, characters 0-42: 4 | Incompatible type variables are being used. 5 | The following types are affected: 6 | type_arity_change 7 | 8 | -------------------------------------------------------------------------------- /atds/TODO: -------------------------------------------------------------------------------- 1 | - produce an output tree using Atd.Indent rather fprintf 2 | (for clarity and atdj performance) 3 | - translate atd syntax tree first, then generate code instead of doing 4 | everything in the same pass (for clarity and atdj performance) 5 | - merge into atdgen 6 | - add location information to exceptions (need own parser) 7 | -------------------------------------------------------------------------------- /atddiff/test/filter_backward/filter_old.atd: -------------------------------------------------------------------------------- 1 | (* 2 | Test that the command-line filters make the correct selection of findings. 3 | *) 4 | 5 | type a = { 6 | deleted_field: int; (* forward incompatibility *) 7 | changing_type: int; 8 | } 9 | 10 | type b = { 11 | uses_a: a; (* backward and forward incompatibilities *) 12 | } 13 | -------------------------------------------------------------------------------- /atddiff/test/filter_forward/filter_old.atd: -------------------------------------------------------------------------------- 1 | (* 2 | Test that the command-line filters make the correct selection of findings. 3 | *) 4 | 5 | type a = { 6 | deleted_field: int; (* forward incompatibility *) 7 | changing_type: int; 8 | } 9 | 10 | type b = { 11 | uses_a: a; (* backward and forward incompatibilities *) 12 | } 13 | -------------------------------------------------------------------------------- /atdgen/test/test_abstract_t.expected.ml: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_abstract.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type int_assoc_list = Testj.int_assoc_list 5 | 6 | type any_items = Yojson.Safe.t list 7 | 8 | type any = Yojson.Safe.t 9 | 10 | type 'x abs2 = 'x Test.abs2 11 | 12 | type 'x abs1 = 'x Test.abs1 13 | -------------------------------------------------------------------------------- /atddiff/test/default/json_repr_change.expected.txt: -------------------------------------------------------------------------------- 1 | [0667c515] Incompatibility in both directions: 2 | File "json_repr_change_old.atd", line 2, characters 21-40 3 | File "json_repr_change_new.atd", line 2, characters 21-61: 4 | Incompatible kinds of types: list/array is now a map. 5 | The following types are affected: 6 | incompatible_record 7 | 8 | -------------------------------------------------------------------------------- /atddiff/test/filter_backward/filter_new.atd: -------------------------------------------------------------------------------- 1 | (* 2 | Test that the command-line filters make the correct selection of findings. 3 | *) 4 | 5 | type a = { 6 | added_field: int; (* backward incompatibility *) 7 | changing_type: string; 8 | } 9 | 10 | type b = { 11 | uses_a: a; (* backward and forward incompatibilities *) 12 | } 13 | -------------------------------------------------------------------------------- /atddiff/test/filter_forward/filter_new.atd: -------------------------------------------------------------------------------- 1 | (* 2 | Test that the command-line filters make the correct selection of findings. 3 | *) 4 | 5 | type a = { 6 | added_field: int; (* backward incompatibility *) 7 | changing_type: string; 8 | } 9 | 10 | type b = { 11 | uses_a: a; (* backward and forward incompatibilities *) 12 | } 13 | -------------------------------------------------------------------------------- /atdgen/test/test_abstract_t.expected.mli: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_abstract.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type int_assoc_list = Testj.int_assoc_list 5 | 6 | type any_items = Yojson.Safe.t list 7 | 8 | type any = Yojson.Safe.t 9 | 10 | type 'x abs2 = 'x Test.abs2 11 | 12 | type 'x abs1 = 'x Test.abs1 13 | -------------------------------------------------------------------------------- /atdgen/test/test_annot.atd: -------------------------------------------------------------------------------- 1 | type pointA = { 2 | f: float 3 | } 4 | 5 | type pointB = { 6 | f: float 7 | } 8 | 9 | type pointC = { 10 | f: float 11 | } 12 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/modularity/part2.atd: -------------------------------------------------------------------------------- 1 | type t1 = abstract 2 | (* 3 | Imports type t defined in file part1.atd. 4 | The local name is t1. Because the local name (t1) is different from the 5 | original name (t), we must specify the original name using t=. 6 | *) 7 | 8 | type t2 = t1 list 9 | -------------------------------------------------------------------------------- /atdts/src/test/Main.ml: -------------------------------------------------------------------------------- 1 | (* 2 | Entry point to the executable running the unit tests 3 | 4 | TODO: We don't have any test suite right now. Remove? 5 | *) 6 | 7 | let test_suites : unit Alcotest.test list = [ 8 | (* Unique_name.test *) 9 | ] 10 | 11 | let main () = 12 | Alcotest.run "atdts" test_suites 13 | 14 | let () = main () 15 | -------------------------------------------------------------------------------- /atddiff/test/default/recursive_types_new.atd: -------------------------------------------------------------------------------- 1 | (* Check that recursive definitions don't cause infinite loops or some 2 | other problem. *) 3 | 4 | type unchanged_recursive = [ Cons of (int * unchanged_recursive) | Nil ] 5 | 6 | type unchanged_recursive_a = [ A of unchanged_recursive_b ] 7 | type unchanged_recursive_b = [ B of unchanged_recursive_a ] 8 | -------------------------------------------------------------------------------- /atddiff/test/default/recursive_types_old.atd: -------------------------------------------------------------------------------- 1 | (* Check that recursive definitions don't cause infinite loops or some 2 | other problem. *) 3 | 4 | type unchanged_recursive = [ Cons of (int * unchanged_recursive) | Nil ] 5 | 6 | type unchanged_recursive_a = [ A of unchanged_recursive_b ] 7 | type unchanged_recursive_b = [ B of unchanged_recursive_a ] 8 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/simple.expected.txt: -------------------------------------------------------------------------------- 1 | { 2 | "findings": [ 3 | { 4 | "hash": "177fee07", 5 | "direction": "Both", 6 | "kind": "Incompatible_type", 7 | "description": "Type names 'int' and 'string' are not the same and may not be compatible.", 8 | "affected_types": [ "t" ] 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore/safe_ignore_new.atd: -------------------------------------------------------------------------------- 1 | type nonrec_root = { 2 | field: b; 3 | new_field: int; 4 | inherit c; 5 | } 6 | 7 | type b = int 8 | 9 | type c = { 10 | field2: int; 11 | } 12 | 13 | type recursive1 = [ Rec2 of recursive2 list | New_case ] 14 | type recursive2 = [ Rec1 of recursive1 list ] 15 | 16 | type new_type = string 17 | -------------------------------------------------------------------------------- /atdgen/src/error.mli: -------------------------------------------------------------------------------- 1 | (** Error reporting for any tool that processes ATD ASTs. *) 2 | 3 | val error : Atd.Ast.loc -> string -> 'a 4 | 5 | val error2 : Atd.Ast.loc -> string -> Atd.Ast.loc -> string -> 'a 6 | 7 | val error3 8 | : Atd.Ast.loc 9 | -> string 10 | -> Atd.Ast.loc 11 | -> string 12 | -> Atd.Ast.loc 13 | -> string -> 'a 14 | -------------------------------------------------------------------------------- /atdgen/test/test_ambiguous_variant.atd: -------------------------------------------------------------------------------- 1 | type ambiguous = [ 2 | | Int of int 3 | | String of string 4 | ] 5 | 6 | 7 | 8 | type ambiguous' = [ 9 | | Int of int 10 | | String of string 11 | ] 12 | 13 | 14 | -------------------------------------------------------------------------------- /atd/src/reflect.mli: -------------------------------------------------------------------------------- 1 | (** 2 | Conversion of an AST value into OCaml source code that creates this value 3 | *) 4 | 5 | val print_full_module_def : Buffer.t -> string -> Ast.full_module -> unit 6 | (** 7 | [print_full_module_def buf name x] prints OCaml source code 8 | that would construct the given ATD tree [x] and call it [name]. 9 | *) 10 | -------------------------------------------------------------------------------- /atddiff/test/default/swapped_type_parameters.expected.txt: -------------------------------------------------------------------------------- 1 | [29041e94] Incompatibility in both directions: 2 | File "swapped_type_parameters_old.atd", line 3, characters 0-61 3 | File "swapped_type_parameters_new.atd", line 3, characters 0-61: 4 | Incompatible type variables are being used. 5 | The following types are affected: 6 | swapped_type_parameters 7 | 8 | -------------------------------------------------------------------------------- /atdpy/src/test/Main.ml: -------------------------------------------------------------------------------- 1 | (* 2 | Entry point to the executable running the unit tests 3 | 4 | TODO: the only test suite we had moved to the atd library. Remove? 5 | *) 6 | 7 | let test_suites : unit Alcotest.test list = [ 8 | (* Unique_name.test *) 9 | ] 10 | 11 | let main () = 12 | Alcotest.run "atdpy" test_suites 13 | 14 | let () = main () 15 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore/safe_ignore_old.atd: -------------------------------------------------------------------------------- 1 | type nonrec_root = { 2 | field: b; 3 | deleted_field: int; 4 | inherit c; 5 | } 6 | 7 | type b = int 8 | 9 | type c = { 10 | field2: int; 11 | } 12 | 13 | type recursive1 = [ Rec2 of recursive2 list | Deleted_case ] 14 | type recursive2 = [ Rec1 of recursive1 list ] 15 | 16 | type deleted_type = int 17 | -------------------------------------------------------------------------------- /atd/test/unit_tests.ml: -------------------------------------------------------------------------------- 1 | (* 2 | Entrypoint to run the unit tests from the command line. 3 | *) 4 | 5 | let test_suites : unit Alcotest.test list = [ 6 | Annot.test; 7 | "Sort", [ 8 | "sort", `Quick, Atd.Sort.test 9 | ]; 10 | Unique_name.test; 11 | Doc.test; 12 | ] 13 | 14 | let main () = Alcotest.run "atd" test_suites 15 | 16 | let () = main () 17 | -------------------------------------------------------------------------------- /atdgen/src/doc_lexer.mli: -------------------------------------------------------------------------------- 1 | (** Parser for the contents of [] annotations. *) 2 | 3 | type inline_element = [ 4 | | `Text of string 5 | | `Code of string 6 | ] 7 | 8 | type block = [ 9 | | `Paragraph of inline_element list 10 | | `Pre of string 11 | ] 12 | 13 | type document = block list 14 | 15 | val parse_string : string -> document 16 | -------------------------------------------------------------------------------- /atdgen-codec-runtime/src/json.mli: -------------------------------------------------------------------------------- 1 | 2 | type t = 3 | [ `Assoc of (string * t) list 4 | | `Bool of bool 5 | | `Float of float 6 | | `Int of int 7 | | `Intlit of string 8 | | `List of t list 9 | | `Null 10 | | `String of string 11 | | `Tuple of t list 12 | | `Variant of string * t option ] 13 | 14 | val constr0 : string -> t 15 | val constr1 : string -> t -> t 16 | -------------------------------------------------------------------------------- /atddiff/test/default/changed_renamed.expected.txt: -------------------------------------------------------------------------------- 1 | [214e5646] Incompatibility in both directions: 2 | File "changed_renamed_old.atd", line 10, characters 22-26 3 | File "changed_renamed_new.atd", line 10, characters 22-28: 4 | Type names 'int' and 'float' are not the same and may not be compatible. 5 | The following types are affected: 6 | new_name 7 | old_name 8 | root_type 9 | 10 | -------------------------------------------------------------------------------- /atdj/test/com/mylife/test/dune: -------------------------------------------------------------------------------- 1 | 2 | (rule 3 | (targets 4 | A.java 5 | Atdj.java 6 | B.java 7 | ComplexRecord.java 8 | E.java 9 | RecordWithDefaults.java 10 | SampleSum.java 11 | SimpleRecord.java 12 | Util.java 13 | package.html) 14 | (deps ../../../test.atd) 15 | (action 16 | (chdir 17 | ../../../ 18 | (run %{bin:atdj} %{deps} -package com.mylife.test)))) 19 | -------------------------------------------------------------------------------- /atdgen/src/oj_mapping.mli: -------------------------------------------------------------------------------- 1 | (** OCaml-Json decorated ATD AST. *) 2 | 3 | type t = (Ocaml.Repr.t, Atd.Json.json_repr) Mapping.mapping 4 | type variant_mapping = 5 | (Ocaml.Repr.t, Atd.Json.json_repr) Mapping.variant_mapping 6 | 7 | val defs_of_atd_modules 8 | : ('a * Atd.Ast.module_body) list 9 | -> target:Ocaml.target 10 | -> ('a * (Ocaml.Repr.t, Atd.Json.json_repr) Mapping.def list) list 11 | -------------------------------------------------------------------------------- /atdgen-codec-runtime/src/json.ml: -------------------------------------------------------------------------------- 1 | 2 | type t = 3 | [ `Assoc of (string * t) list 4 | | `Bool of bool 5 | | `Float of float 6 | | `Int of int 7 | | `Intlit of string 8 | | `List of t list 9 | | `Null 10 | | `String of string 11 | | `Tuple of t list 12 | | `Variant of string * t option ] 13 | 14 | let constr0 s = `Variant (s, None) 15 | 16 | let constr1 s a = `Variant (s, Some a) 17 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/inspect-biniou/demo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | set -x 4 | 5 | cat tree.atd 6 | cat tree.ml 7 | 8 | atdgen -t tree.atd 9 | atdgen -b tree.atd 10 | ocamlfind ocamlopt -o tree \ 11 | tree_t.mli tree_t.ml tree_b.mli tree_b.ml tree.ml \ 12 | -package atdgen -linkpkg 13 | ./tree 14 | 15 | ls -l tree.dat 16 | bdump tree.dat 17 | bdump -w Empty,Node tree.dat 18 | bdump tree.dat 19 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/hello/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name hello) 3 | (libraries atdgen-runtime yojson)) 4 | 5 | (rule 6 | (targets hello_t.ml hello_t.mli) 7 | (deps hello.atd) 8 | (action 9 | (run %{bin:atdgen} %{deps} -t))) 10 | 11 | (rule 12 | (targets hello_j.ml hello_j.mli) 13 | (deps hello.atd) 14 | (action 15 | (run %{bin:atdgen} %{deps} -j))) 16 | 17 | (cram 18 | (deps hello.exe)) 19 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/same_hash.expected.txt: -------------------------------------------------------------------------------- 1 | [177fee07] Incompatibility in both directions: 2 | Type names 'int' and 'string' are not the same and may not be compatible. 3 | The following types are affected: 4 | t 5 | 6 | [177fee07] Incompatibility in both directions: 7 | Type names 'int' and 'string' are not the same and may not be compatible. 8 | The following types are affected: 9 | t 10 | 11 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/inspect-biniou/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name tree) 3 | (libraries atdgen-runtime biniou yojson)) 4 | 5 | (rule 6 | (targets tree_t.ml tree_t.mli) 7 | (deps tree.atd) 8 | (action 9 | (run %{bin:atdgen} %{deps} -t))) 10 | 11 | (rule 12 | (targets tree_b.ml tree_b.mli) 13 | (deps tree.atd) 14 | (action 15 | (run %{bin:atdgen} %{deps} -b))) 16 | 17 | (cram 18 | (deps tree.exe)) 19 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error2/safe_ignore.expected.txt: -------------------------------------------------------------------------------- 1 | Error: Some types in file 'safe_ignore_old.atd' were not declared with '--types' or '--ignore'. You should identify types that are entry points and add them to '--types' if you want to check them or to '--ignore' otherwise. 2 | The following types are not being checked: deleted_type 3 | At least the following types need to be added to '--types' or '--ignore': deleted_type 4 | -------------------------------------------------------------------------------- /atdgen/src/omelange_emit.mli: -------------------------------------------------------------------------------- 1 | 2 | val make_ocaml_files 3 | : opens:string list 4 | -> with_typedefs:bool 5 | -> with_create:bool 6 | -> with_fundefs:bool 7 | -> all_rec:bool 8 | -> pos_fname:string option 9 | -> pos_lnum:int option 10 | -> type_aliases:string option 11 | -> force_defaults:'a 12 | -> ocaml_version:'b 13 | -> pp_convs:'c 14 | -> string option 15 | -> Ox_emit.target 16 | -> unit 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.cmi 3 | *.cmo 4 | *.cmx 5 | *.cma 6 | *.cmxa 7 | *.cmxs 8 | *.a 9 | *.o 10 | *.annot 11 | *.run 12 | *.opt 13 | *.exe 14 | _build 15 | _opam 16 | .merlin 17 | *.install 18 | META 19 | atd_doc_lexer.ml 20 | atd_lexer.ml 21 | atd_parser.ml 22 | atd_parser.mli 23 | atd_version.ml 24 | unit-tests 25 | dep 26 | *.out 27 | html 28 | man1 29 | 30 | # Temporary folder(s) used by some maintenance scripts 31 | tmp 32 | -------------------------------------------------------------------------------- /atdd/test/dune: -------------------------------------------------------------------------------- 1 | ; 2 | ; We test in two phases: 3 | ; 4 | ; 1. Check that the generated Dlang code is what we expect. 5 | ; 6 | 7 | (rule 8 | (alias runtest) 9 | (package atdd) 10 | (action 11 | (diff dlang-expected/everything_atd.d 12 | dlang-tests/everything_atd.d))) 13 | 14 | ; 2. Run the generated Dlang code and check that is reads or writes JSON 15 | ; data as expected. 16 | ; 17 | ; See dlang-tests/dune 18 | -------------------------------------------------------------------------------- /atdpy/test/dune: -------------------------------------------------------------------------------- 1 | ; 2 | ; We test in two phases: 3 | ; 4 | ; 1. Check that the generated Python code is what we expect. 5 | ; 6 | 7 | (rule 8 | (alias runtest) 9 | (package atdpy) 10 | (action 11 | (diff python-expected/everything.py 12 | python-tests/everything.py))) 13 | 14 | ; 2. Run the generated Python code and check that is reads or writes JSON 15 | ; data as expected. 16 | ; 17 | ; See python-tests/dune 18 | -------------------------------------------------------------------------------- /atdpy/test/python-tests/deco.py: -------------------------------------------------------------------------------- 1 | """Test custom decorators. 2 | """ 3 | 4 | from typing import Any 5 | 6 | 7 | def deco1(cls: Any) -> Any: 8 | print(f"Decorating class {cls.__name__} with deco1") 9 | return cls 10 | 11 | 12 | def deco2(n: int) -> Any: 13 | def decorator(cls: Any) -> Any: 14 | print(f"Decorating class {cls.__name__} with deco2({n})") 15 | return cls 16 | return decorator 17 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/untypable-json/untypable_v2.atd: -------------------------------------------------------------------------------- 1 | (* deprecated since ATD 2.6 *) 2 | type raw_json = abstract 3 | (* uses type Yojson.Safe.t, 4 | with the functions Yojson.Safe.write_json 5 | and Yojson.Safe.read_json *) 6 | 7 | type obj_list = obj list 8 | 9 | type obj = { 10 | ?label: string option; 11 | ?labels: string list option; 12 | value: raw_json 13 | } 14 | -------------------------------------------------------------------------------- /atddiff/src/lib/Loc.mli: -------------------------------------------------------------------------------- 1 | (* 2 | Yet another Loc module. 3 | 4 | This one differs from Atd.Loc because it uses a JSON-friendly type. 5 | *) 6 | 7 | type t = Atddiff_output_t.location 8 | 9 | val of_atd_loc : Atd.Loc.t -> t 10 | 11 | val compare : t -> t -> int 12 | 13 | (* Produce something like 14 | 15 | File "atddiff/src/bin/Atddiff_main.ml", lines 247-256, characters 8-5 16 | *) 17 | val to_string : t -> string 18 | -------------------------------------------------------------------------------- /atdgen/example/format_v2.atd: -------------------------------------------------------------------------------- 1 | (* Newer version of an imagined data format. Compare to `format_v1.atd'. *) 2 | 3 | type t = { 4 | a : int option; 5 | (* removed field b, making newer data unreadable with older software since 6 | b was not optional. *) 7 | ?c : int option; 8 | ~d : float; 9 | ~e : string list; (* added optional field e, allowing newer software 10 | to read older data. *) 11 | } 12 | -------------------------------------------------------------------------------- /atdcpp/test/dune: -------------------------------------------------------------------------------- 1 | ; 2 | ; We test in two phases: 3 | ; 4 | ; 1. Check that the generated Dlang code is what we expect. 5 | ; 6 | 7 | (rule 8 | (alias runtest) 9 | (package atdcpp) 10 | (action 11 | (diff cpp-expected/everything_atd.hpp 12 | cpp-tests/everything_atd.hpp) 13 | )) 14 | 15 | ; 2. Run the generated Dlang code and check that is reads or writes JSON 16 | ; data as expected. 17 | ; 18 | ; See cpp-tests/dune 19 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/untypable-json/input.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "label": "flower", 4 | "value": { 5 | "petals": [12, 45, 83.5555], 6 | "water": "a340bcf02e" 7 | } 8 | }, 9 | { 10 | "label": "flower", 11 | "value": { 12 | "petals": "undefined", 13 | "fold": null, 14 | "water": 0 15 | } 16 | }, 17 | { "labels": ["fork", "scissors"], 18 | "value": [ 8, 8 ] 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /atdgen/README.md: -------------------------------------------------------------------------------- 1 | Atdgen uses type definitions in the ATD syntax and generates 2 | efficient [JSON](http://json.org) serializers, deserializers and 3 | validators for OCaml. 4 | 5 | Installation 6 | ------------ 7 | 8 | ``` 9 | $ opam install atdgen 10 | ``` 11 | 12 | Documentation 13 | ------------- 14 | 15 | https://atd.readthedocs.io/ 16 | 17 | How to contribute 18 | ----------------- 19 | 20 | [CONTRIBUTING.md](../CONTRIBUTING.md) 21 | -------------------------------------------------------------------------------- /atdj/test/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CLASSPATH='.:json.jar:junit-4.8.2.jar' 4 | 5 | javac -classpath $CLASSPATH com/mylife/test/*.java 6 | javac -classpath $CLASSPATH AtdjTest.java 7 | javadoc -quiet -Xdoclint:none -classpath $CLASSPATH -d doc/test \ 8 | -public com.mylife.test -quiet \ 9 | | grep -v "Creating destination directory" 10 | java -classpath $CLASSPATH AtdjTest | grep -v -E '^(Time:|JUnit version)' > java.trace 11 | -------------------------------------------------------------------------------- /atds/src/atds_env.ml: -------------------------------------------------------------------------------- 1 | (* Translation environment *) 2 | 3 | type id = string 4 | type ty_name = string 5 | 6 | type env_t = { 7 | module_items : (string * Atd.Ast.type_expr) list; 8 | package : string; 9 | input_file : string option; 10 | output : out_channel; 11 | } 12 | 13 | let default_env = { 14 | module_items = []; 15 | package = "out"; 16 | input_file = None; 17 | output = stdout; 18 | } 19 | -------------------------------------------------------------------------------- /atddiff/test/filter/filter_new.atd: -------------------------------------------------------------------------------- 1 | (* 2 | Test that the command-line filters make the correct selection of findings. 3 | *) 4 | 5 | type a = { 6 | added_field: int; (* backward incompatibility *) 7 | changing_type: string; 8 | } 9 | 10 | type b = { 11 | uses_a: a; (* backward and forward incompatibilities *) 12 | } 13 | 14 | (* Findings affecting only 'c' are ignored. *) 15 | type c = { 16 | added_field_in_ignored_type: int; 17 | } 18 | -------------------------------------------------------------------------------- /atddiff/test/filter/filter_old.atd: -------------------------------------------------------------------------------- 1 | (* 2 | Test that the command-line filters make the correct selection of findings. 3 | *) 4 | 5 | type a = { 6 | deleted_field: int; (* forward incompatibility *) 7 | changing_type: int; 8 | } 9 | 10 | type b = { 11 | uses_a: a; (* backward and forward incompatibilities *) 12 | } 13 | 14 | (* Findings affecting only 'c' are ignored. *) 15 | type c = { 16 | deleted_field_in_ignored_type: int; 17 | } 18 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/untypable-json/untypable_v1.atd: -------------------------------------------------------------------------------- 1 | (* File untypable.atd *) 2 | 3 | (* deprecated since ATD 2.6 *) 4 | type json = abstract 5 | (* uses type Yojson.Safe.t, 6 | with the functions Yojson.Safe.write_json 7 | and Yojson.Safe.read_json *) 8 | 9 | type obj_list = obj list 10 | 11 | type obj = { 12 | ?label: string option; 13 | ?labels: string list option; 14 | value: json 15 | } 16 | -------------------------------------------------------------------------------- /.circleci/setup-opam: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Set up opam and install opam packages required to build and test atd 4 | # 5 | # This is used by the Dockerfile and by the CI build. 6 | # 7 | set -eu 8 | 9 | eval "$(opam env)" 10 | 11 | opam repo add --all-switches -k git \ 12 | github https://github.com/ocaml/opam-repository.git 13 | opam repo remove default 14 | # no need for 'opam update' 15 | 16 | ./scripts/install-opam-dependencies 17 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore/safe_ignore.expected.txt: -------------------------------------------------------------------------------- 1 | [1bd853be] Forward incompatibility: 2 | File "safe_ignore_old.atd", line 3, characters 2-20: 3 | Required field 'deleted_field' disappeared. 4 | The following types are affected: 5 | nonrec_root 6 | 7 | [319452bf] Backward incompatibility: 8 | File "safe_ignore_new.atd", line 3, characters 2-16: 9 | Required field 'new_field' is new. 10 | The following types are affected: 11 | nonrec_root 12 | 13 | -------------------------------------------------------------------------------- /atdgen-runtime/src/ov_run.mli: -------------------------------------------------------------------------------- 1 | (** Runtime library for OCaml validators. *) 2 | 3 | val validate_list 4 | : (([> `Index of int ] as 'a) list -> 'b -> 'c option) 5 | -> 'a list 6 | -> 'b list 7 | -> 'c option 8 | 9 | val validate_array 10 | : (([> `Index of int ] as 'a) list -> 'b -> 'c option) 11 | -> 'a list 12 | -> 'b array 13 | -> 'c option 14 | 15 | val validate_option : ('a -> 'b -> 'c option) -> 'a -> 'b option -> 'c option 16 | -------------------------------------------------------------------------------- /atdts/test/ts-tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "tsc": "tsc", 4 | "lint": "tslint --project tsconfig.json && eslint *.ts" 5 | }, 6 | "devDependencies": { 7 | "@types/node": "^17.0.25", 8 | "@typescript-eslint/eslint-plugin": "^5.49.0", 9 | "@typescript-eslint/parser": "^5.49.0", 10 | "eslint": "^8.32.0", 11 | "typescript": "^4.6.3" 12 | }, 13 | "dependencies": { 14 | "tslint": "^6.1.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/validate/resume.atd: -------------------------------------------------------------------------------- 1 | type text = string 2 | 3 | type date = { 4 | year : int; 5 | month : int; 6 | day : int; 7 | } 8 | 9 | type job = { 10 | company : text; 11 | title : text; 12 | start_date : date; 13 | ?end_date : date option; 14 | } 15 | 16 | type work_experience = job list 17 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error1/safe_ignore.expected.txt: -------------------------------------------------------------------------------- 1 | Error: Some types in file 'safe_ignore_old.atd' were not declared with '--types' or '--ignore'. You should identify types that are entry points and add them to '--types' if you want to check them or to '--ignore' otherwise. 2 | The following types are not being checked: recursive1, recursive2 3 | At least the following types need to be added to '--types' or '--ignore': 4 | -------------------------------------------------------------------------------- /atddiff/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Compare two versions of the same ATD file. 3 | # 4 | 5 | DUNE ?= dune 6 | 7 | .PHONY: build 8 | build: 9 | rm -f bin 10 | $(DUNE) build 11 | ln -s ../_build/install/default/bin . 12 | 13 | .PHONY: test 14 | test: 15 | $(MAKE) -C test 16 | 17 | # Update the output format of atddiff by running 'make types'. 18 | # This requires an external installation of the atdgen command. 19 | .PHONY: types 20 | types: 21 | $(MAKE) -C src/lib types 22 | -------------------------------------------------------------------------------- /atddiff/src/lib/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Generate a .ml file containing just the type definitions derived from 3 | # an ATD file. 4 | # 5 | # We don't generate code that exercises the atdgen runtime library 6 | # due to circular dependencies but atddiff users can. 7 | # 8 | 9 | # This requires an external installation of the atdgen command. 10 | .PHONY: types 11 | types: Atddiff_output_t.ml 12 | 13 | Atddiff_output_t.ml: Atddiff_output.atd 14 | atdgen -t Atddiff_output.atd 15 | -------------------------------------------------------------------------------- /atddiff/test/default/recursive_new.atd: -------------------------------------------------------------------------------- 1 | (* Check that recursive definitions don't cause infinite loops or some 2 | other problem. *) 3 | 4 | type unchanged_recursive = [ Cons of (int * unchanged_recursive) | Nil ] 5 | 6 | type unchanged_recursive_a = [ A of unchanged_recursive_b ] 7 | type unchanged_recursive_b = [ B of unchanged_recursive_a ] 8 | 9 | type changed_recursive = [ A of changed_recursive | B ] 10 | type depends_on_changed_recursive = changed_recursive list 11 | -------------------------------------------------------------------------------- /atddiff/test/default/recursive_old.atd: -------------------------------------------------------------------------------- 1 | (* Check that recursive definitions don't cause infinite loops or some 2 | other problem. *) 3 | 4 | type unchanged_recursive = [ Cons of (int * unchanged_recursive) | Nil ] 5 | 6 | type unchanged_recursive_a = [ A of unchanged_recursive_b ] 7 | type unchanged_recursive_b = [ B of unchanged_recursive_a ] 8 | 9 | type changed_recursive = [ A of changed_recursive ] 10 | type depends_on_changed_recursive = changed_recursive list 11 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/config-file/config.atd: -------------------------------------------------------------------------------- 1 | type config = { 2 | title : string; 3 | ?description : string option; 4 | ~timeout : int; 5 | ~credentials : param list 6 | ; 8 | } 9 | 10 | type param = { 11 | name : string 12 | ; 13 | key : string 14 | ; 15 | } 16 | -------------------------------------------------------------------------------- /atdts/test/ts-tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | "target": "es2016", 5 | "lib": ["es7", "dom"], 6 | 7 | /* Modules */ 8 | "module": "commonjs", /* Specify what module code is generated. */ 9 | 10 | /* Type Checking */ 11 | "strict": true, 12 | 13 | /* Completeness */ 14 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /atdgen/src/ob_emit.mli: -------------------------------------------------------------------------------- 1 | (** OCaml-Biniou code generator. *) 2 | 3 | val make_ocaml_files 4 | : opens:string list 5 | -> with_typedefs:bool 6 | -> with_create:bool 7 | -> with_fundefs:bool 8 | -> all_rec:bool 9 | -> pos_fname:string option 10 | -> pos_lnum:int option 11 | -> type_aliases:string option 12 | -> force_defaults:_ (* not used *) 13 | -> ocaml_version:(int * int) option 14 | -> pp_convs:Ocaml.pp_convs 15 | -> string option -> Ox_emit.target -> unit 16 | -------------------------------------------------------------------------------- /atds/test/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | CLASSPATH=`scala -version 2>&1 | sed 's/^.*version \(2...\).*$/.:argonaut_\1-6.2.2.jar:junit-4.8.2.jar/'` 5 | 6 | scalac -classpath $CLASSPATH test.scala 7 | scalac -classpath $CLASSPATH AtdsTest.scala 8 | scaladoc -classpath $CLASSPATH test.scala -d doc 2>&1 | 9 | grep -q 'model contains [0-9]* documentable templates' 10 | scala -classpath $CLASSPATH AtdsTest > scala.trace || { 11 | cat scala.trace 12 | exit 1 13 | } 14 | -------------------------------------------------------------------------------- /atddiff/test/filter_forward/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets filter.txt) 5 | (deps filter_old.atd filter_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --forward))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps filter.txt) 15 | (action (diff filter.expected.txt filter.txt))) 16 | 17 | -------------------------------------------------------------------------------- /atdcat/README.md: -------------------------------------------------------------------------------- 1 | atdcat 2 | ====== 3 | 4 | `atdcat` is a development tool for working with the ATD language. It 5 | checks the syntax of an ATD file and reformats it. Options offer 6 | transformations of the type definitions that can be useful for 7 | troubleshooting. Check out `atdcat --help` for the list of available options. 8 | 9 | The most noteworthy transformation offered by atdcat is `atdcat -jsonschema` 10 | which translates an ATD file to [JSON Schema](https://json-schema.org/). 11 | -------------------------------------------------------------------------------- /atddiff/test/filter_backward/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets filter.txt) 5 | (deps filter_old.atd filter_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --backward))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps filter.txt) 15 | (action (diff filter.expected.txt filter.txt))) 16 | 17 | -------------------------------------------------------------------------------- /atdgen/src/ov_emit.mli: -------------------------------------------------------------------------------- 1 | (** Code generator for OCaml validators. *) 2 | 3 | val make_ocaml_files 4 | : opens:string list 5 | -> with_typedefs:bool 6 | -> with_create:bool 7 | -> with_fundefs:bool 8 | -> all_rec:bool 9 | -> pos_fname:string option 10 | -> pos_lnum:int option 11 | -> type_aliases:string option 12 | -> force_defaults:_ (* TODO unused *) 13 | -> ocaml_version:_ (* TODO unused *) 14 | -> pp_convs:Ocaml.pp_convs 15 | -> string option -> Ox_emit.target -> unit 16 | -------------------------------------------------------------------------------- /atdd/test/dlang-tests/dune: -------------------------------------------------------------------------------- 1 | ; 2 | ; Convert ATD -> Dlang 3 | ; 4 | (rule 5 | (targets 6 | everything_atd.d 7 | ) 8 | (deps 9 | ../atd-input/everything.atd 10 | ) 11 | (action 12 | (run %{bin:atdd} %{deps}))) 13 | 14 | ; 15 | ; Compile and run the tests on the generated Dlang code. 16 | ; 17 | (rule 18 | (alias runtest) 19 | (package atdd) 20 | (deps 21 | (glob_files *.d)) 22 | (action 23 | (progn 24 | (bash "ldc2 %{deps} --of test") 25 | (bash ./test) 26 | ))) 27 | -------------------------------------------------------------------------------- /atds/test/dune: -------------------------------------------------------------------------------- 1 | 2 | (rule 3 | (targets test.scala) 4 | (deps test.atd) 5 | (action 6 | (run %{bin:atds} %{deps} -package com.mylife.test -o test.scala))) 7 | 8 | (rule 9 | (alias runtest) 10 | (package atds) 11 | (action (diff test.expected.scala test.scala))) 12 | 13 | (rule 14 | (alias runtest) 15 | (package atds) 16 | (deps 17 | AtdsTest.scala 18 | argonaut_2.11-6.2.2.jar 19 | argonaut_2.12-6.2.2.jar 20 | junit-4.8.2.jar 21 | test.scala) 22 | (action (run ./run_test.sh))) 23 | -------------------------------------------------------------------------------- /atddiff/test/filter/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets filter.txt) 5 | (deps filter_old.atd filter_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --backward --forward --types a,b))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps filter.txt) 15 | (action (diff filter.expected.txt filter.txt))) 16 | 17 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/hello/demo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | set -x 4 | cat hello.atd 5 | atdgen -t hello.atd 6 | atdgen -j hello.atd 7 | ls 8 | ocamlfind ocamlc -c hello_t.mli -package atdgen 9 | ocamlfind ocamlc -c hello_j.mli -package atdgen 10 | ocamlfind ocamlopt -c hello_t.ml -package atdgen 11 | ocamlfind ocamlopt -c hello_j.ml -package atdgen 12 | ocamlfind ocamlopt -c hello.ml -package atdgen 13 | ocamlfind ocamlopt -o hello hello_t.cmx hello_j.cmx hello.cmx \ 14 | -package atdgen -linkpkg 15 | ./hello 16 | -------------------------------------------------------------------------------- /atd/src/inherit.mli: -------------------------------------------------------------------------------- 1 | (** Expansion of [inherit] statements *) 2 | 3 | val expand_module_body : 4 | ?inherit_fields : bool -> 5 | ?inherit_variants : bool -> 6 | Ast.module_body -> Ast.module_body 7 | (** 8 | Expand [inherit] statements found in sum types and product types. 9 | 10 | @param inherit_fields specify whether record fields should be expanded. 11 | Default is true. 12 | 13 | @param inherit_variants specify whether sum types 14 | should be expanded. Default is true. 15 | *) 16 | -------------------------------------------------------------------------------- /atdcat/test/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "ID": "abc", 3 | "items": [ [], [ 1, 2 ] ], 4 | "extras": [ 17, 53 ], 5 | "answer": 42, 6 | "aliased": [ 8, 9, 10 ], 7 | "point": [ 3.3, -77.22 ], 8 | "kinds": [ "wow", [ "Thing", 99 ], [ "!!!", [ "a", "b" ] ], "Root" ], 9 | "assoc1": [ [ 1.1, 1 ], [ 2.2, 2 ] ], 10 | "assoc2": { "c": 3, "d": 4 }, 11 | "options": [ [ "Some", 10 ], "None", [ "Some", 88 ] ], 12 | "nullables": [ 13, 71, null ], 13 | "untyped_things": [123, [[""]], {}], 14 | "extra": "ignore me please" 15 | } 16 | -------------------------------------------------------------------------------- /atddiff/test/json_output/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets all_errors.txt) 5 | (deps all_errors_old.atd all_errors_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --output-format json))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps all_errors.txt) 15 | (action (diff all_errors.expected.txt all_errors.txt))) 16 | 17 | -------------------------------------------------------------------------------- /atddiff/test/filter_backward/filter.expected.txt: -------------------------------------------------------------------------------- 1 | [1c4525c6] Backward incompatibility: 2 | File "filter_new.atd", line 6, characters 2-18: 3 | Required field 'added_field' is new. 4 | The following types are affected: 5 | a 6 | b 7 | 8 | [099be5a3] Incompatibility in both directions: 9 | File "filter_old.atd", line 7, characters 16-20 10 | File "filter_new.atd", line 7, characters 16-23: 11 | Type names 'int' and 'string' are not the same and may not be compatible. 12 | The following types are affected: 13 | a 14 | b 15 | 16 | -------------------------------------------------------------------------------- /atddiff/test/filter_forward/filter.expected.txt: -------------------------------------------------------------------------------- 1 | [3d596659] Forward incompatibility: 2 | File "filter_old.atd", line 6, characters 2-20: 3 | Required field 'deleted_field' disappeared. 4 | The following types are affected: 5 | a 6 | b 7 | 8 | [099be5a3] Incompatibility in both directions: 9 | File "filter_old.atd", line 7, characters 16-20 10 | File "filter_new.atd", line 7, characters 16-23: 11 | Type names 'int' and 'string' are not the same and may not be compatible. 12 | The following types are affected: 13 | a 14 | b 15 | 16 | -------------------------------------------------------------------------------- /atdts/test/ts-tests/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended" 9 | ], 10 | "overrides": [ 11 | ], 12 | "parser": "@typescript-eslint/parser", 13 | "parserOptions": { 14 | "ecmaVersion": "latest", 15 | "sourceType": "module" 16 | }, 17 | "plugins": [ 18 | "@typescript-eslint" 19 | ], 20 | "rules": { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/validate/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name resume) 3 | (libraries atdgen-runtime yojson)) 4 | 5 | (rule 6 | (targets resume_t.ml resume_t.mli) 7 | (deps resume.atd) 8 | (action 9 | (run %{bin:atdgen} %{deps} -t))) 10 | 11 | (rule 12 | (targets resume_j.ml resume_j.mli) 13 | (deps resume.atd) 14 | (action 15 | (run %{bin:atdgen} %{deps} -j))) 16 | 17 | (rule 18 | (targets resume_v.ml resume_v.mli) 19 | (deps resume.atd) 20 | (action 21 | (run %{bin:atdgen} %{deps} -v))) 22 | 23 | (cram 24 | (deps resume.exe)) 25 | -------------------------------------------------------------------------------- /atddiff/src/lib/Compare.mli: -------------------------------------------------------------------------------- 1 | (* 2 | Compare two ATD ASTs for incompatibilities 3 | 4 | The findings are sorted nicely. 5 | *) 6 | 7 | type sort_by = Location | Hash 8 | 9 | type options = { 10 | (* Are fields with defaults always populated in old JSON data? *) 11 | json_defaults_old : bool; 12 | (* Are fields with defaults always populated in new JSON data? *) 13 | json_defaults_new : bool; 14 | sort_by: sort_by; 15 | } 16 | 17 | val asts : 18 | options -> Atd.Ast.full_module -> Atd.Ast.full_module -> 19 | Atddiff_output_t.result 20 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error1/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets safe_ignore.txt) 5 | (deps safe_ignore_old.atd safe_ignore_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 1 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --types nonrec_root --ignore deleted_type,new_type))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps safe_ignore.txt) 15 | (action (diff safe_ignore.expected.txt safe_ignore.txt))) 16 | 17 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore_error2/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets safe_ignore.txt) 5 | (deps safe_ignore_old.atd safe_ignore_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 1 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --types nonrec_root --ignore recursive2,new_type))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps safe_ignore.txt) 15 | (action (diff safe_ignore.expected.txt safe_ignore.txt))) 16 | 17 | -------------------------------------------------------------------------------- /atdj/TODO: -------------------------------------------------------------------------------- 1 | Now: 2 | - update documentation for ArrayList and for variants 3 | 4 | Later: 5 | - produce an output tree using Atd.Indent rather fprintf 6 | (for clarity and atdj performance) 7 | - variant implementation: avoid memory leak by clearing previous field 8 | - translate atd syntax tree first, then generate code instead of doing 9 | everything in the same pass (for clarity and atdj performance) 10 | - merge into atdgen 11 | - support top-level lists 12 | - add support for lists of lists 13 | - add location information to exceptions (need own parser) 14 | -------------------------------------------------------------------------------- /atddiff/test/safe_ignore/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets safe_ignore.txt) 5 | (deps safe_ignore_old.atd safe_ignore_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --types nonrec_root --ignore recursive2,deleted_type,new_type))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps safe_ignore.txt) 15 | (action (diff safe_ignore.expected.txt safe_ignore.txt))) 16 | 17 | -------------------------------------------------------------------------------- /atddiff/test/default/unchanged_old.atd: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Type definitions without breaking changes in both directions *) 3 | (****************************************************************************) 4 | 5 | type unchanged_record = { 6 | a: int; 7 | ?b: int option; 8 | ~c: int list; 9 | d : int ; 10 | renamed_field_type: old_name_for_unchanged_type; 11 | } 12 | 13 | type unchanged_variant = [ 14 | | A 15 | | B of int 16 | ] 17 | 18 | type old_name_for_unchanged_type = [ Thing ] 19 | -------------------------------------------------------------------------------- /atdgen/test/test_abstract.atd: -------------------------------------------------------------------------------- 1 | 2 | type 'x abs1 3 | = abstract 4 | 5 | type 'x abs2 6 | = abstract 7 | 8 | (* import an external type *) 9 | type int_assoc_list = abstract 10 | 11 | (* untyped JSON. 12 | 13 | 'abstract' translates to the 'Yojson.Safe.t' type even for the biniou 14 | backend since it shares type definitions with the JSON backend. 15 | *) 16 | type any = abstract 17 | type any_items = abstract list 18 | -------------------------------------------------------------------------------- /atdgen/src/error.ml: -------------------------------------------------------------------------------- 1 | 2 | open Printf 3 | 4 | let error loc msg = 5 | failwith (sprintf "%s:\n%s" (Atd.Ast.string_of_loc loc) msg) 6 | 7 | let error2 loc1 msg1 loc2 msg2 = 8 | failwith (sprintf "%s:\n%s\n%s:\n%s" 9 | (Atd.Ast.string_of_loc loc1) msg1 10 | (Atd.Ast.string_of_loc loc2) msg2) 11 | 12 | let error3 loc1 msg1 loc2 msg2 loc3 msg3 = 13 | failwith (sprintf "%s:\n%s\n%s:\n%s\n%s:\n%s" 14 | (Atd.Ast.string_of_loc loc1) msg1 15 | (Atd.Ast.string_of_loc loc2) msg2 16 | (Atd.Ast.string_of_loc loc3) msg3) 17 | -------------------------------------------------------------------------------- /atdcpp/test/cpp-tests/dune: -------------------------------------------------------------------------------- 1 | ; 2 | ; Convert ATD -> C++ 3 | ; 4 | (rule 5 | (targets 6 | everything_atd.hpp 7 | everything_atd.cpp 8 | ) 9 | (deps 10 | ../atd-input/everything.atd 11 | ) 12 | (action 13 | (run %{bin:atdcpp} %{deps}))) 14 | 15 | ; 16 | ; Compile and run the tests on the generated C++ code. 17 | ; Linking with rapidjson library 18 | ; 19 | (rule 20 | (alias runtest) 21 | (package atdcpp) 22 | (deps 23 | (glob_files *.cpp)) 24 | (action 25 | (progn 26 | (bash "g++ -I../../lib/rapidjson/include -std=c++17 %{deps} -o test") 27 | (bash ./test) 28 | ))) 29 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/same_hash.expected.txt: -------------------------------------------------------------------------------- 1 | { 2 | "findings": [ 3 | { 4 | "hash": "177fee07", 5 | "direction": "Both", 6 | "kind": "Incompatible_type", 7 | "description": "Type names 'int' and 'string' are not the same and may not be compatible.", 8 | "affected_types": [ "t" ] 9 | }, 10 | { 11 | "hash": "177fee07", 12 | "direction": "Both", 13 | "kind": "Incompatible_type", 14 | "description": "Type names 'int' and 'string' are not the same and may not be compatible.", 15 | "affected_types": [ "t" ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /atdgen/atdgen.descr: -------------------------------------------------------------------------------- 1 | Generates efficient JSON serializers, deserializers and validators 2 | 3 | Atdgen is a command-line program that takes as input type definitions in the ATD 4 | syntax and produces OCaml code suitable for data serialization and 5 | deserialization. Two data formats are currently supported, these are biniou and 6 | JSON. Atdgen-biniou and Atdgen-json will refer to Atdgen used in one context or 7 | the other. Atdgen was designed with efficiency and durability in mind. Software 8 | authors are encouraged to use Atdgen directly and to write tools that may reuse 9 | part of Atdgen’s source code. 10 | -------------------------------------------------------------------------------- /atdj/test/expected/Atdj.java: -------------------------------------------------------------------------------- 1 | // Automatically generated; do not edit 2 | package com.mylife.test; 3 | import org.json.*; 4 | 5 | /** 6 | * Common utility interface. 7 | */ 8 | public interface Atdj { 9 | /** 10 | * Get the JSON string representation, failing if some of the data 11 | * was not initialized. 12 | * @return The JSON string. 13 | */ 14 | String toJson() throws JSONException; 15 | 16 | /** 17 | * Write the JSON representation to a buffer, failing if some of the data 18 | * was not initialized. 19 | */ 20 | void toJsonBuffer(StringBuilder out) throws JSONException; 21 | } 22 | -------------------------------------------------------------------------------- /atdpy/test/python-tests/dune: -------------------------------------------------------------------------------- 1 | ; 2 | ; Convert ATD -> Python 3 | ; 4 | (rule 5 | (targets 6 | allcaps.py 7 | everything.py 8 | ) 9 | (deps 10 | ../atd-input/ALLCAPS.atd 11 | ../atd-input/everything.atd 12 | ) 13 | (action 14 | (run %{bin:atdpy} %{deps}))) 15 | 16 | ; 17 | ; Typecheck and run the tests on the generated Python code. 18 | ; 19 | (rule 20 | (alias runtest) 21 | (package atdpy) 22 | (deps 23 | everything.py 24 | (glob_files *.py)) 25 | (action 26 | (progn 27 | (run python3 -m flake8 .) 28 | (run python3 -m mypy --strict .) 29 | (run python3 -m pytest .)))) 30 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_record.expected.txt: -------------------------------------------------------------------------------- 1 | [2283db51] Backward incompatibility: 2 | File "backward_incompatible_record_new.atd", line 2, characters 2-18: 3 | Required field 'added_field' is new. 4 | The following types are affected: 5 | backward_incompatible_record 6 | 7 | [3c1ae3e6] Backward incompatibility: 8 | File "backward_incompatible_record_old.atd", line 2, characters 2-31 9 | File "backward_incompatible_record_new.atd", line 3, characters 2-23: 10 | Formerly optional field 'becomes_required' is now required. 11 | The following types are affected: 12 | backward_incompatible_record 13 | 14 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_record.expected.txt: -------------------------------------------------------------------------------- 1 | [381a0845] Forward incompatibility: 2 | File "forward_incompatible_record_old.atd", line 2, characters 2-20: 3 | Required field 'removed_field' disappeared. 4 | The following types are affected: 5 | forward_incompatible_record 6 | 7 | [06b4c346] Forward incompatibility: 8 | File "forward_incompatible_record_old.atd", line 3, characters 2-23 9 | File "forward_incompatible_record_new.atd", line 2, characters 2-31: 10 | Formerly required field 'becomes_optional' is now optional. 11 | The following types are affected: 12 | forward_incompatible_record 13 | 14 | -------------------------------------------------------------------------------- /atdgen/src/oj_emit.mli: -------------------------------------------------------------------------------- 1 | (** OCaml-Json code generator. *) 2 | 3 | val make_ocaml_files 4 | :opens:string list 5 | -> with_typedefs:bool 6 | -> with_create:bool 7 | -> with_fundefs:bool 8 | -> all_rec:bool 9 | -> std:bool 10 | -> unknown_field_handler:string option 11 | -> pos_fname:string option 12 | -> pos_lnum:int option 13 | -> type_aliases:string option 14 | -> force_defaults:bool 15 | -> preprocess_input:string option 16 | -> ocaml_version:(int * int) option 17 | -> pp_convs:Ocaml.pp_convs 18 | -> add_generic_modules: bool 19 | -> string option 20 | -> Ox_emit.target 21 | -> unit 22 | -------------------------------------------------------------------------------- /atdts/test/ts-tests/dune: -------------------------------------------------------------------------------- 1 | ; Copy generated .ts files here so that the JS tests can find them The 2 | ; reason why we don't put the rules to generate .ts here is because 3 | ; we'd have to use the (mode (promote (until-clean))) atom to have 4 | ; the files added to the source tree and that somehow breaks the 5 | ; diffing-promotion dune mechanism 6 | 7 | (rule 8 | (mode 9 | (promote (until-clean))) 10 | (deps ../gen-expect-tests/everything.ts ../gen-expect-tests/import.ts) 11 | (action 12 | (progn 13 | (copy ../gen-expect-tests/everything.ts everything.ts) 14 | (copy ../gen-expect-tests/import.ts import.ts)))) 15 | -------------------------------------------------------------------------------- /atdts/test/ts-tests/Makefile: -------------------------------------------------------------------------------- 1 | JS ?= node 2 | 3 | .PHONY: test 4 | test: 5 | # To get the latest generated *.ts files 6 | dune build 7 | # Install TypeScript and JavaScript dependencies locally 8 | npm install 9 | $(MAKE) lint 10 | # Compile TypeScript (handwritten + generated by atdts) to JavaScript 11 | npm run tsc 12 | # Run the resulting code (compiled from TypeScript) 13 | $(JS) manual_sample.js 14 | $(JS) test_atdts.js 15 | 16 | # Check for warnings from tslint and eslint, especially in the generated code 17 | .PHONY: lint 18 | lint: 19 | npm run lint 20 | 21 | .PHONY: clean 22 | clean: 23 | dune clean 24 | git clean -dfX 25 | -------------------------------------------------------------------------------- /atddiff/test/default/unchanged_new.atd: -------------------------------------------------------------------------------- 1 | (****************************************************************************) 2 | (* Type definitions without breaking changes in both directions *) 3 | (****************************************************************************) 4 | 5 | type unchanged_variant = [ 6 | | A 7 | | B of int 8 | ] 9 | 10 | (* The order of the type definitions changed on purpose. *) 11 | type unchanged_record = { 12 | a: int; 13 | ?b: int option; 14 | ~c: int list; 15 | d : int ; 16 | renamed_field_type: new_name_for_unchanged_type; 17 | } 18 | 19 | type new_name_for_unchanged_type = [ Thing ] 20 | -------------------------------------------------------------------------------- /atdj/src/atdj_env.ml: -------------------------------------------------------------------------------- 1 | (* Translation environment *) 2 | 3 | type id = string 4 | type ty_name = string 5 | 6 | (* Java types *) 7 | type ty = 8 | [ `Class of ty_name * (id * ty_name) list 9 | (* Class name and constructor parameters *) 10 | | `Interface of ty_name 11 | (* Interface name *) 12 | ] 13 | 14 | type env_t = { 15 | module_items : (string * Atd.Ast.type_expr) list; 16 | package : string; 17 | package_dir : string; 18 | input_file : string option; 19 | } 20 | 21 | let default_env = { 22 | module_items = []; 23 | package = "out"; 24 | package_dir = "out"; 25 | input_file = None; 26 | } 27 | -------------------------------------------------------------------------------- /atdgen/util/recompile-deps: -------------------------------------------------------------------------------- 1 | # -*- sh -*- 2 | # Script for working with development versions of atdgen's dependencies. 3 | # All git repositories (atd, atdgen, etc.) must exist in the same directory. 4 | 5 | # Usage (from within atdgen/): . util/recompile-deps 6 | 7 | # This script is meant to be sourced from the atdgen directory. 8 | # It sets the OCAMLPATH variable such that the development versions 9 | # of atdgen's dependencies are found first when compiling. 10 | 11 | atdgen_dir=$(pwd) 12 | parent=$atdgen_dir/.. 13 | export OCAMLPATH=$parent 14 | for x in cppo easy-format atd biniou yojson atdgen; do 15 | (cd parent/$x; make clean; make) 16 | done 17 | -------------------------------------------------------------------------------- /atd/src/loc.ml: -------------------------------------------------------------------------------- 1 | (* 2 | A location is a region in a source file. 3 | *) 4 | 5 | type t = Lexing.position * Lexing.position 6 | 7 | let compare_pos (a : Lexing.position) (b : Lexing.position) = 8 | let c = String.compare a.pos_fname b.pos_fname in 9 | if c <> 0 then c 10 | else 11 | Int.compare a.pos_cnum b.pos_cnum 12 | 13 | (* Compare two locations so as to sort them by: 14 | 1. file path 15 | 2. start position in the file 16 | 3. end position in the file 17 | *) 18 | let compare ((a_start, a_end) : t) ((b_start, b_end) : t) = 19 | let c = compare_pos a_start b_start in 20 | if c <> 0 then c 21 | else 22 | compare_pos a_end b_end 23 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Set the version of Python and other tools you might need 9 | build: 10 | os: ubuntu-22.04 11 | tools: 12 | python: "3.11" 13 | 14 | # Build documentation in the doc/ directory with Sphinx 15 | sphinx: 16 | configuration: doc/conf.py 17 | 18 | # We recommend specifying your dependencies to enable reproducible builds: 19 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 20 | python: 21 | install: 22 | - requirements: doc/requirements.txt 23 | -------------------------------------------------------------------------------- /atdgen-runtime/src/ov_run.ml: -------------------------------------------------------------------------------- 1 | let validate_list f path l = 2 | let rec loop f path i = function 3 | | [] -> None 4 | | x :: l -> 5 | let subpath = `Index i :: path in 6 | match f subpath x with 7 | None -> loop f path (i+1) l 8 | | err -> err 9 | in 10 | loop f path 0 l 11 | 12 | let validate_array f path a = 13 | let rec loop f path a len i = 14 | if i >= len then None 15 | else 16 | match f (`Index i :: path) a.(i) with 17 | None -> loop f path a len (i+1) 18 | | err -> err 19 | in 20 | loop f path a (Array.length a) 0 21 | 22 | let validate_option f path = function 23 | None -> None 24 | | Some x -> f path x 25 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/modularity/demo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | set -x 4 | cat part1.atd 5 | cat part2.atd 6 | cat part3.atd 7 | for x in part1 part2 part3; do 8 | atdgen -t $x.atd 9 | atdgen -j $x.atd 10 | ocamlfind ocamlc -c ${x}_t.mli -package atdgen 11 | ocamlfind ocamlc -c ${x}_j.mli -package atdgen 12 | ocamlfind ocamlopt -c ${x}_t.ml -package atdgen 13 | ocamlfind ocamlopt -c ${x}_j.ml -package atdgen 14 | done 15 | ocamlfind ocamlopt -c main.ml -package atdgen 16 | 17 | ocamlfind ocamlopt -o test_modularity \ 18 | part1_t.cmx part1_j.cmx \ 19 | part2_t.cmx part2_j.cmx \ 20 | part3_t.cmx part3_j.cmx \ 21 | main.cmx \ 22 | -package atdgen -linkpkg 23 | ./test_modularity 24 | -------------------------------------------------------------------------------- /atddiff/test/json_output/all_errors_old.atd: -------------------------------------------------------------------------------- 1 | type deleted = int 2 | 3 | type changed_record = { 4 | deleted_field: int; 5 | becomes_optional: int; 6 | becomes_optional_with_default: int; 7 | ?becomes_required: int option; 8 | ~with_default_becomes_required: int; 9 | renamed_field: int; 10 | } 11 | 12 | type changed_variant = [ 13 | | Deleted_case 14 | | Deleted_case_with_arg of string 15 | | Added_arg 16 | | Removed_arg of int 17 | | Changed_arg of int 18 | | Renamed_case 19 | ] 20 | 21 | type indirect_changes = { 22 | record: changed_record; 23 | variant: changed_variant; 24 | } 25 | 26 | type changed_map1 = (string * int) list 27 | type changed_map2 = (string * int) list 28 | -------------------------------------------------------------------------------- /atddiff/test/default/backward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | [1963da34] Possible backward incompatibility: 2 | File "backward_incompatible_record_if_implicit_defaults_old.atd", line 2, characters 2-24 3 | File "backward_incompatible_record_if_implicit_defaults_new.atd", line 2, characters 2-23: 4 | Newly required field 'becomes_required' was optional but had a default value. 5 | If old implementations in use always populate the JSON field 6 | with a value (using atdgen's option -j-defaults or equivalent), 7 | then there's no problem and you should use 8 | 'atddiff --json-defaults-old' to disable this warning. 9 | The following types are affected: 10 | backward_incompatible_record_if_implicit_defaults 11 | 12 | -------------------------------------------------------------------------------- /atdj/README.md: -------------------------------------------------------------------------------- 1 | Atdj 2 | ==== 3 | 4 | Atdj is a program that generates a Java interface from type definitions. 5 | In particular, given a set of ATD type definitions, 6 | this tool generates a set of Java classes representing those types 7 | with built-in JSON serializers and deserializers. 8 | 9 | The primary benefits of using the generated interface, over manually 10 | manipulating JSON strings from within Java, are safety and ease of use. 11 | Specifically, the generated interface offers the following features: 12 | 13 | * JSON strings are automatically checked for correctness with 14 | respect to the ATD specification. 15 | * Details such as optional fields and their associated default values are 16 | automatically handled. 17 | -------------------------------------------------------------------------------- /atddiff/test/Makefile: -------------------------------------------------------------------------------- 1 | # Run the tests. 2 | 3 | DUNE ?= dune 4 | 5 | # We generate the dune files from the list of *_old.atd files because 6 | # dune doesn't support dynamic targets. 7 | # 8 | # How to add a test? 9 | # 10 | # 1. Identify the folder corresponding to the atddiff options to be used. 11 | # Look into the script 'generate-dune-rules' to find out which folder 12 | # corresponds to which options. 13 | # 2. Create a pair of files ${name}_old.atd and ${name}_new.atd in that 14 | # folder. 15 | # 3. Run 'make'. 16 | # 4. If you're satisfied with the output, run 'dune promote' to make it the 17 | # new reference for future tests. 18 | # 19 | .PHONY: test 20 | test: 21 | ./generate-dune-rules 22 | $(DUNE) runtest -f 23 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults_new/backward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | [1963da34] Possible backward incompatibility: 2 | File "backward_incompatible_record_if_implicit_defaults_old.atd", line 2, characters 2-24 3 | File "backward_incompatible_record_if_implicit_defaults_new.atd", line 2, characters 2-23: 4 | Newly required field 'becomes_required' was optional but had a default value. 5 | If old implementations in use always populate the JSON field 6 | with a value (using atdgen's option -j-defaults or equivalent), 7 | then there's no problem and you should use 8 | 'atddiff --json-defaults-old' to disable this warning. 9 | The following types are affected: 10 | backward_incompatible_record_if_implicit_defaults 11 | 12 | -------------------------------------------------------------------------------- /atddiff/src/lib/Root_types.mli: -------------------------------------------------------------------------------- 1 | (* 2 | Take a list of possible root types and the contents of an ATD file 3 | and identify if some type definitions remain unvisited after visiting 4 | all the definitions the root types depend on. 5 | 6 | Return (unvisited, unvisited_and_unreferenced) where unvisited is the full 7 | list of type definitions that were not visited and 8 | unvisited_and_unreferenced is the subset of these unvisited definitions 9 | that are known to be root types. Other root types may exist in recursive 10 | definitions but we don't report them. 11 | *) 12 | val check_root_types_superset : 13 | root_types_superset:string list -> 14 | ast_with_inherits:Atd.Ast.full_module -> 15 | string list * string list 16 | -------------------------------------------------------------------------------- /atdgen/src/ox_mapping.ml: -------------------------------------------------------------------------------- 1 | open! Atd.Import 2 | open Atd.Ast 3 | 4 | type analyze_field = 5 | { ocaml_default : string option 6 | ; unwrapped : bool 7 | } 8 | 9 | let analyze_field target loc (f_kind : field_kind) annot = 10 | let ocaml_default, unwrapped = 11 | match f_kind, Ocaml.get_ocaml_default target annot with 12 | Required, None -> None, false 13 | | Optional, None -> Some "None", true 14 | | (Required | Optional), Some _ -> 15 | Error.error loc "Superfluous default OCaml value" 16 | | With_default, Some s -> Some s, false 17 | | With_default, None -> 18 | (* will try to determine implicit default value later *) 19 | None, false 20 | in 21 | { ocaml_default 22 | ; unwrapped 23 | } 24 | -------------------------------------------------------------------------------- /atdgen/test/test5.atd: -------------------------------------------------------------------------------- 1 | (* Basic testing of -allow-name-overlap *) 2 | 3 | type ab1 = { 4 | a : string; 5 | b : int; 6 | } 7 | 8 | type ab2 = { 9 | a : string; 10 | b : int; 11 | } 12 | 13 | type bca = { 14 | b : ab2 list; 15 | c : int list; 16 | a : float; 17 | } 18 | 19 | type cd1 = [ 20 | | C of int 21 | | D of string 22 | ] 23 | 24 | type cd2 = [ 25 | | C of float 26 | | D of bool 27 | ] 28 | 29 | type cde = [ 30 | | C of int 31 | | D of cd1 32 | | E of cd2 33 | ] 34 | 35 | type all = { 36 | a : ab1; 37 | b : ab2; 38 | c : bca list; 39 | d : cde list; 40 | } 41 | 42 | type contains_variant = { 43 | foo : string; 44 | bar : [ One | Two | Three of int ] 45 | } 46 | -------------------------------------------------------------------------------- /atdj/doc/OMakefile: -------------------------------------------------------------------------------- 1 | # No default target. 2 | # `omake pdf' requires pdflatex and builds readme.pdf 3 | # `omake txt' requires hevea and builds readme.txt 4 | # `omake html' requires hevea and builds readme.html 5 | 6 | USEPDFLATEX = true 7 | TEXFILES = readme atdj-body 8 | 9 | .PHONY: all pdf txt html 10 | all: pdf txt html 11 | pdf: readme.pdf 12 | txt: readme.txt 13 | html: readme.html 14 | 15 | readme.txt: $(addsuffix .tex, $(TEXFILES)) 16 | hevea -text readme 17 | hevea -text readme 18 | 19 | readme.html: $(addsuffix .tex, $(TEXFILES)) 20 | hevea readme 21 | hevea readme 22 | 23 | LaTeXDocument(readme, $(TEXFILES)) 24 | 25 | .PHONY: clean 26 | clean: 27 | rm -f *.aux *.toc *.log *.out *.haux *.htoc *.fls \ 28 | readme.pdf readme.txt readme.html 29 | -------------------------------------------------------------------------------- /atddiff/test/json_output/all_errors_new.atd: -------------------------------------------------------------------------------- 1 | type created = int 2 | 3 | type changed_record = { 4 | new_field: int; 5 | ?becomes_optional: int option; 6 | ~becomes_optional_with_default: int; 7 | becomes_required: int; 8 | with_default_becomes_required: int; 9 | renamed_field : int; 10 | } 11 | 12 | type changed_variant = [ 13 | | New_case 14 | | New_case_with_arg of int 15 | | Added_arg of float 16 | | Removed_arg 17 | | Changed_arg of bool 18 | | Renamed_case 19 | ] 20 | 21 | type indirect_changes = { 22 | record: changed_record; 23 | variant: changed_variant; 24 | } 25 | 26 | type changed_map1 = (string * int) list 27 | type changed_map2 = (string * int) list 28 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/validate/demo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | set -x 4 | cat resume.atd 5 | atdgen -t resume.atd 6 | atdgen -j resume.atd 7 | atdgen -v resume.atd 8 | ls 9 | ocamlfind ocamlc -c resume_t.mli -package atdgen 10 | ocamlfind ocamlc -c resume_v.mli -package atdgen 11 | ocamlfind ocamlc -c resume_j.mli -package atdgen 12 | ocamlfind ocamlopt -c resume_t.ml -package atdgen 13 | ocamlfind ocamlopt -c resume_util.ml -package atdgen 14 | ocamlfind ocamlopt -c resume_v.ml -package atdgen 15 | ocamlfind ocamlopt -c resume_j.ml -package atdgen 16 | ocamlfind ocamlopt -c resume.ml -package atdgen 17 | ocamlfind ocamlopt -o test_resume \ 18 | resume_t.cmx resume_util.cmx resume_v.cmx resume_j.cmx resume.cmx \ 19 | -package atdgen -linkpkg 20 | ./test_resume 21 | -------------------------------------------------------------------------------- /dune: -------------------------------------------------------------------------------- 1 | (env 2 | ;; disable warnings against "Innocuous unused variables" 3 | ;; enforce the separation between types `string` and `bytes` 4 | (dev (flags :standard -w -27 -safe-string)) 5 | (release (flags :standard -w -27 -safe-string))) 6 | 7 | (rule (copy atd.opam.template atdgen-codec-runtime.opam.template)) 8 | (rule (copy atd.opam.template atdgen-runtime.opam.template)) 9 | (rule (copy atd.opam.template atdgen.opam.template)) 10 | (rule (copy atd.opam.template atdj.opam.template)) 11 | (rule (copy atd.opam.template atdpy.opam.template)) 12 | (rule (copy atd.opam.template atds.opam.template)) 13 | (rule (copy atd.opam.template atdts.opam.template)) 14 | (rule (copy atd.opam.template atdd.opam.template)) 15 | (rule (copy atd.opam.template atdcpp.opam.template)) 16 | -------------------------------------------------------------------------------- /scripts/install-opam-dependencies: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | # 3 | # Install the opam dependencies as specified in the opam packages 4 | # except for the packages defined by this project. 5 | # 6 | set -eu -o pipefail 7 | 8 | workspace=tmp/install-deps 9 | rm -rf "$workspace" 10 | mkdir -p "$workspace" 11 | 12 | # Remove the dependencies on packages provided by this very project. 13 | for x in *.opam; do 14 | grep -v \ 15 | '"atd"\|"atdgen"\|"atdgen-codec-runtime"\|"atdgen-runtime"\|"atdj"\|"atdpy"\|"atds"\|"atdts"\|"atdd"\|"atdcpp"' "$x" \ 16 | > "$workspace"/"$x" 17 | done 18 | 19 | # Install the dependencies, which should be now only external dependencies. 20 | ( 21 | cd "$workspace" 22 | opam install --deps-only --with-test --with-doc ./*.opam 23 | ) 24 | -------------------------------------------------------------------------------- /atdgen/example/README: -------------------------------------------------------------------------------- 1 | 2 | Example using atdgen 3 | ==================== 4 | 5 | 6 | This simple but standalone example illustrates the use of atdgen to 7 | manage a backward-compatible change of data format. 8 | 9 | The old data format is defined in `format_v1.atd'. The newer data 10 | format is defined in `format_v2.atd'. It is a record type from which 11 | one field was removed and another field was added. 12 | 13 | The program `upgrade_demo' demonstrates the use of atdgen in general 14 | and how to make a data format evolve without losing compatibility 15 | with legacy data files or services. 16 | 17 | 1. Atdgen must be installed properly 18 | 2. Run `make' 19 | 3. Inspect the files starting with example.sh 20 | -------------------------------------------------------------------------------- /atddiff/test/default/forward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | [2e39bd55] Possible forward incompatibility: 2 | File "forward_incompatible_record_if_implicit_defaults_old.atd", line 2, characters 2-23 3 | File "forward_incompatible_record_if_implicit_defaults_new.atd", line 2, characters 2-24: 4 | Formerly required field 'becomes_optional' is now optional but has a default value. 5 | You must ensure that new implementations always populate the JSON field 6 | with a value (using atdgen's option -j-defaults or equivalent) so that older 7 | implementations can read newer data. If this is already the case, use 8 | 'atddiff --json-defaults-new' to disable this warning. 9 | The following types are affected: 10 | forward_incompatible_record_if_implicit_defaults 11 | 12 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults_old/forward_incompatible_record_if_implicit_defaults.expected.txt: -------------------------------------------------------------------------------- 1 | [2e39bd55] Possible forward incompatibility: 2 | File "forward_incompatible_record_if_implicit_defaults_old.atd", line 2, characters 2-23 3 | File "forward_incompatible_record_if_implicit_defaults_new.atd", line 2, characters 2-24: 4 | Formerly required field 'becomes_optional' is now optional but has a default value. 5 | You must ensure that new implementations always populate the JSON field 6 | with a value (using atdgen's option -j-defaults or equivalent) so that older 7 | implementations can read newer data. If this is already the case, use 8 | 'atddiff --json-defaults-new' to disable this warning. 9 | The following types are affected: 10 | forward_incompatible_record_if_implicit_defaults 11 | 12 | -------------------------------------------------------------------------------- /atdd/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Dlang/JSON backend 3 | # 4 | 5 | DUNE ?= dune 6 | 7 | .PHONY: build 8 | build: 9 | rm -f bin/atdd 10 | $(MAKE) clean-for-dune 11 | $(DUNE) build @all 12 | mkdir -p bin 13 | ln -s ../../_build/install/default/bin/atdd bin/atdd 14 | 15 | # The symlink facilitates the development of test code that depends on the 16 | # generated code. 17 | .PHONY: test 18 | test: 19 | $(MAKE) clean-for-dune 20 | $(DUNE) runtest -f; status=$$?; \ 21 | ln -s ../../../_build/default/atdd/test/dlang-tests/everything.d \ 22 | test/dlang-tests/everything.d && \ 23 | exit "$$status" 24 | 25 | .PHONY: clean-for-dune 26 | clean-for-dune: 27 | rm -f test/dlang-tests/everything.d 28 | 29 | .PHONY: clean 30 | clean: 31 | $(MAKE) clean-for-dune 32 | $(DUNE) clean 33 | rm -rf bin 34 | -------------------------------------------------------------------------------- /atdts/test/gen-expect-tests/dune: -------------------------------------------------------------------------------- 1 | ; 2 | ; Convert ATD -> TypeScript 3 | ; 4 | 5 | (rule 6 | (deps everything.atd) 7 | (targets everything.ts) 8 | (action 9 | (run %{bin:atdts} %{deps}))) 10 | 11 | (rule 12 | (deps import.atd) 13 | (targets import.ts) 14 | (action 15 | (run %{bin:atdts} %{deps}))) 16 | 17 | ; 18 | ; We test in two phases: 19 | ; 20 | ; 1. Check that the generated TypeScript code is what we expect. 21 | ; 22 | 23 | (rule 24 | (alias runtest) 25 | (package atdts) 26 | (deps everything.ts import.ts) 27 | (action 28 | (progn 29 | (diff import.ts.expected import.ts) 30 | (diff everything.ts.expected everything.ts)))) 31 | 32 | ; 2. Run the generated TypeScript code and check that is reads or writes JSON 33 | ; data as expected. 34 | ; 35 | ; See ../ts-tests/dune 36 | -------------------------------------------------------------------------------- /atdpy/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Python-mypy/JSON backend 3 | # 4 | 5 | DUNE ?= dune 6 | 7 | .PHONY: build 8 | build: 9 | rm -f bin/atdpy 10 | $(MAKE) clean-for-dune 11 | $(DUNE) build @all 12 | mkdir -p bin 13 | ln -s ../../_build/install/default/bin/atdpy bin/atdpy 14 | 15 | # The symlink facilitates the development of test code that depends on the 16 | # generated code. 17 | .PHONY: test 18 | test: 19 | $(MAKE) clean-for-dune 20 | $(DUNE) runtest -f; status=$$?; \ 21 | ln -s ../../../_build/default/atdpy/test/python-tests/everything.py \ 22 | test/python-tests/everything.py && \ 23 | exit "$$status" 24 | 25 | .PHONY: clean-for-dune 26 | clean-for-dune: 27 | rm -f test/python-tests/everything.py 28 | 29 | .PHONY: clean 30 | clean: 31 | $(MAKE) clean-for-dune 32 | $(DUNE) clean 33 | rm -rf bin 34 | -------------------------------------------------------------------------------- /atdcat/test/test2.expected.atd: -------------------------------------------------------------------------------- 1 | type z = abstract list 2 | type 'a t = int 3 | type x = float t 4 | type 'a l = [ Nil | Cons of ('a * 'a l) ] 5 | type int_l = int l 6 | type float_l = float l 7 | type tup = (int l * float_l) 8 | type ('a, 'b) tbl = ('a * 'b) list list 9 | type 'a string_tbl = (string, 'a) tbl 10 | type string_bool_tbl = bool string_tbl 11 | type 'a b = 'a a 12 | type 'a a = 'a b 13 | type c = c a b a 14 | type 'id gen_profile = { id: 'id; name: string option; age: int option } 15 | type basic_profile = int gen_profile 16 | type profile_enhancements = { credit_card_number: string } 17 | type ('id, 'self) nested_profile = { 18 | inherit 'id gen_profile; 19 | sub_profiles: 'self list 20 | } 21 | type profile = { 22 | inherit (int, profile) nested_profile; 23 | inherit profile_enhancements 24 | } 25 | -------------------------------------------------------------------------------- /atdgen/test/test_abstract_v.expected.ml: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_abstract.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type int_assoc_list = Testj.int_assoc_list 5 | 6 | type any_items = Test_abstract_t.any_items 7 | 8 | type any = Test_abstract_t.any 9 | 10 | type 'x abs2 = 'x Test.abs2 11 | 12 | type 'x abs1 = 'x Test_abstract_t.abs1 13 | 14 | let validate_int_assoc_list = ( 15 | Testj.validate_int_assoc_list 16 | ) 17 | let validate__abstract_list = ( 18 | Atdgen_runtime.Ov_run.validate_list ( 19 | (fun _ _ -> None) 20 | ) 21 | ) 22 | let validate_any_items = ( 23 | validate__abstract_list 24 | ) 25 | let validate_any = ( 26 | (fun _ _ -> None) 27 | ) 28 | let validate_abs2 validate__x = ( 29 | Test.validate_abs2 validate__x 30 | ) 31 | let validate_abs1 validate__x = ( 32 | (fun _ _ -> None) 33 | ) 34 | -------------------------------------------------------------------------------- /atd/src/print.mli: -------------------------------------------------------------------------------- 1 | (** Pretty-printing of ATD data *) 2 | 3 | val default_annot : Ast.annot_section -> Easy_format.t 4 | 5 | val format : 6 | ?annot: (Ast.annot_section -> Easy_format.t) -> 7 | Ast.full_module -> Easy_format.t 8 | (** Pretty-printing. Use the functions of the [Easy_format.Pretty] 9 | module to convert an [Easy_format.t] into a string 10 | or add it to a channel or buffer. 11 | 12 | @param annot can be used to specify another way of formatting 13 | annotations. The default is available as 14 | [default_format_annot]. 15 | *) 16 | 17 | val string_of_type_name : 18 | string -> Ast.type_expr list -> Ast.annot -> string 19 | (** Convert a type name with its arguments and its annotations 20 | into a string. *) 21 | 22 | val string_of_type_expr : Ast.type_expr -> string 23 | -------------------------------------------------------------------------------- /atds/README.md: -------------------------------------------------------------------------------- 1 | Atds 2 | ==== 3 | 4 | Atds is a program that generates a Scala interface from type definitions. 5 | In particular, given a set of ATD type definitions, 6 | this tool generates a set of Scala case classes representing those types 7 | with built-in JSON serializers. (Deserializers planned.) 8 | 9 | The primary benefits of using the generated interface, over using a 10 | JSON library and writing case classes directly, are safety and ease of use 11 | when the same interface is needed in other languages. 12 | 13 | Don't repeat yourself when defining a JSON interface in multiple languages. 14 | Instead generate compatible interfaces for all languages from a single definition. 15 | 16 | Even if you're only using Scala, you may find the ATD definitions more concise 17 | and less boilerplaity than the equivalent Scala types. (Especially for sum types) 18 | -------------------------------------------------------------------------------- /atdgen/test/test_classic_inline_record_j.expected.mli: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test_classic_inline_record.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type foo = Test_classic_inline_record_t.foo = Foo of { x: int; y: float } 5 | 6 | val write_foo : 7 | Buffer.t -> foo -> unit 8 | (** Output a JSON value of type {!type:foo}. *) 9 | 10 | val string_of_foo : 11 | ?len:int -> foo -> string 12 | (** Serialize a value of type {!type:foo} 13 | into a JSON string. 14 | @param len specifies the initial length 15 | of the buffer used internally. 16 | Default: 1024. *) 17 | 18 | val read_foo : 19 | Yojson.Safe.lexer_state -> Lexing.lexbuf -> foo 20 | (** Input JSON data of type {!type:foo}. *) 21 | 22 | val foo_of_string : 23 | string -> foo 24 | (** Deserialize JSON data of type {!type:foo}. *) 25 | 26 | -------------------------------------------------------------------------------- /atdts/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # TypeScript/JSON backend 3 | # 4 | 5 | DUNE ?= dune 6 | 7 | .PHONY: build 8 | build: 9 | rm -f bin/atdts 10 | $(MAKE) clean-for-dune 11 | $(DUNE) build @all 12 | mkdir -p bin 13 | ln -s ../../_build/install/default/bin/atdts bin/atdts 14 | 15 | # The symlink facilitates the development of test code that depends on the 16 | # generated code. 17 | .PHONY: test 18 | test: 19 | # Run atdts to convert ATD -> TypeScript 20 | $(DUNE) runtest -f; status=$$?; \ 21 | if [ "$$status" != 0 ]; then \ 22 | echo "Run 'dune promote' to accept diffs, if any."; \ 23 | fi; \ 24 | exit "$$status" 25 | # Compile and run the TypeScript code 26 | $(MAKE) -C test/ts-tests 27 | 28 | .PHONY: clean-for-dune 29 | clean-for-dune: 30 | 31 | 32 | .PHONY: clean 33 | clean: 34 | $(MAKE) clean-for-dune 35 | $(DUNE) clean 36 | rm -rf bin 37 | -------------------------------------------------------------------------------- /atdgen/test/spec_js/spec_j.expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "r1": "testing" }, 3 | { "r2": [ "Some", 2 ] }, 4 | { "r2": "None" }, 5 | { "r3": 3 }, 6 | {}, 7 | { "r4": true }, 8 | { "r5": [ "Some", 5 ] }, 9 | {}, 10 | { "r6": 6 }, 11 | {}, 12 | { "r7": -1000 }, 13 | { "r8": [ 1, 2, 3 ] }, 14 | [ "foo", "bar" ], 15 | [], 16 | null, 17 | [ 1, 2, 3 ], 18 | 99, 19 | { "foo": 7, "bar": 8, "baz": 43 }, 20 | { "foo2": 5, "bar2": 6, "baz2": 41, "42": 42 }, 21 | [ 100, "foo" ], 22 | [ 100, 200, 42 ], 23 | [ 100, 200, -1 ], 24 | [ 25 | "V1", 26 | "v22", 27 | [ "V3", "testing" ], 28 | [ "v44", 255 ], 29 | [ "V5", "None" ], 30 | [ "V5", [ "Some", true ] ] 31 | ], 32 | { "v2": "A" }, 33 | { "v2": [ "B", 100 ] }, 34 | [ "C1", [ "C2", true ], [ "C2", false ] ], 35 | [ 50, 30, 1, 100 ], 36 | "hello", 37 | [ "Alpha", "hello" ] 38 | ] -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/config-file/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name config) 3 | (libraries atdgen-runtime yojson)) 4 | 5 | (rule 6 | (targets config_t.ml config_t.mli) 7 | (deps config.atd) 8 | (action 9 | (run %{bin:atdgen} %{deps} -t))) 10 | 11 | (rule 12 | (targets config_j.ml config_j.mli) 13 | (deps config.atd) 14 | (action 15 | (run %{bin:atdgen} %{deps} -j -j-defaults -j-strict-fields))) 16 | 17 | (rule 18 | (targets config_v.ml config_v.mli) 19 | (deps config.atd) 20 | (action 21 | (run %{bin:atdgen} %{deps} -v))) 22 | 23 | (rule 24 | (targets config_atd.ml) 25 | (deps config.atd) 26 | (action 27 | (with-stdout-to 28 | %{targets} 29 | (progn 30 | (run echo "let contents = \"\\") 31 | (run sed -e "s/\\(\\\\\\|\\\"\\)/\\\\\\1/g" %{deps}) 32 | (run echo "\""))))) 33 | 34 | (cram 35 | (deps 36 | config.exe 37 | (glob_files *.json))) 38 | -------------------------------------------------------------------------------- /atddiff/test/default/json_field_name_change.expected.txt: -------------------------------------------------------------------------------- 1 | [2befd23c] Forward incompatibility: 2 | File "json_field_name_change_old.atd", line 2, characters 2-26: 3 | Required field 'a!' disappeared. 4 | The following types are affected: 5 | with_field_renames 6 | 7 | [1dad2f90] Forward incompatibility: 8 | File "json_field_name_change_old.atd", line 3, characters 2-9: 9 | Required field 'b' disappeared. 10 | The following types are affected: 11 | with_field_renames 12 | 13 | [0948d4d7] Backward incompatibility: 14 | File "json_field_name_change_new.atd", line 2, characters 2-9: 15 | Required field 'a' is new. 16 | The following types are affected: 17 | with_field_renames 18 | 19 | [2f0c378c] Backward incompatibility: 20 | File "json_field_name_change_new.atd", line 3, characters 2-27: 21 | Required field 'bee' is new. 22 | The following types are affected: 23 | with_field_renames 24 | 25 | -------------------------------------------------------------------------------- /atdj/doc/readme.tex: -------------------------------------------------------------------------------- 1 | \documentclass[letterpaper,10pt]{article} 2 | 3 | \usepackage{ae} 4 | \usepackage{hyperref} 5 | \usepackage{hevea} 6 | 7 | \usepackage{verbatim} 8 | \usepackage{alltt} 9 | 10 | \usepackage[latin1]{inputenc} 11 | \usepackage[T1]{fontenc} 12 | \usepackage{url} 13 | 14 | \usepackage{booktabs} 15 | 16 | \title{ATD for Java (ATDJ)} 17 | %\author{John Doe} 18 | %\date{October 19, 2072} 19 | \pagestyle{headings} 20 | 21 | % We suppress indentation at the beginning of each paragraph because paragraphs 22 | % are short and indentation is used heavily for bullet points and code examples 23 | \setlength{\parindent}{0mm} 24 | \setlength{\parskip}{2mm} 25 | 26 | % Thickness of top and bottom lines of tables (\toprule, \bottomrule) 27 | \setlength{\heavyrulewidth}{1.5pt} 28 | 29 | \begin{document} 30 | \maketitle 31 | \tableofcontents 32 | \include{atdj-body} 33 | \end{document} 34 | -------------------------------------------------------------------------------- /atd/src/jsonschema.mli: -------------------------------------------------------------------------------- 1 | (** 2 | Translate an ATD file to JSON Schema, honoring the annotations. 3 | *) 4 | 5 | (** These are the versions of the JSON Schema currently supported. 6 | 7 | See https://json-schema.org/draft/2020-12/release-notes.html 8 | for the differences between 2019-09 and 2020-12. 9 | *) 10 | type version = 11 | | Draft_2019_09 12 | | Draft_2020_12 13 | 14 | val default_version : version 15 | 16 | (** This is for validating the ATD file, not for JSON Schema. *) 17 | val annot_schema : Annot.schema 18 | 19 | (** Translate an ATD AST to a JSON Schema. 20 | 21 | @param xprop whether to allow extra fields in JSON objects. The default 22 | is true, which is JSON Schema's default. 23 | *) 24 | val print : 25 | ?version:version -> 26 | ?xprop:bool -> 27 | src_name:string -> 28 | root_type:string -> 29 | out_channel -> Ast.full_module -> unit 30 | -------------------------------------------------------------------------------- /atdgen/test/spec_js/spec_mel.expected.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "r1": "testing" }, 3 | { "r2": [ "Some", 2 ] }, 4 | { "r2": "None" }, 5 | { "r3": 3 }, 6 | {}, 7 | { "r4": true }, 8 | { "r5": [ "Some", 5 ] }, 9 | { "r5": "None" }, 10 | { "r6": 6 }, 11 | { "r6": 42 }, 12 | { "r7": -1000 }, 13 | { "r8": [ 1, 2, 3 ] }, 14 | [ "foo", "bar" ], 15 | [], 16 | null, 17 | [ 1, 2, 3 ], 18 | "c", 19 | { "baz": 43, "bar": 8, "foo": 7 }, 20 | { "42": 42, "baz2": 41, "bar2": 6, "foo2": 5 }, 21 | [ 100, "foo" ], 22 | [ 100, 200, 42 ], 23 | [ 100, 200, -1 ], 24 | [ 25 | "V1", 26 | "v22", 27 | [ "V3", "testing" ], 28 | [ "v44", 255 ], 29 | [ "V5", "None" ], 30 | [ "V5", [ "Some", true ] ] 31 | ], 32 | { "v2": "A" }, 33 | { "v2": [ "B", 100 ] }, 34 | [ "C1", [ "C2", true ], [ "C2", false ] ], 35 | [ 50, 30, 1, 100 ], 36 | "hello", 37 | [ "Alpha", "hello" ] 38 | ] -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/modularity/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name main) 3 | (libraries atdgen-runtime yojson)) 4 | 5 | (rule 6 | (targets part1_t.ml part1_t.mli) 7 | (deps part1.atd) 8 | (action 9 | (run %{bin:atdgen} %{deps} -t))) 10 | 11 | (rule 12 | (targets part1_j.ml part1_j.mli) 13 | (deps part1.atd) 14 | (action 15 | (run %{bin:atdgen} %{deps} -j))) 16 | 17 | (rule 18 | (targets part2_t.ml part2_t.mli) 19 | (deps part2.atd) 20 | (action 21 | (run %{bin:atdgen} %{deps} -t))) 22 | 23 | (rule 24 | (targets part2_j.ml part2_j.mli) 25 | (deps part2.atd) 26 | (action 27 | (run %{bin:atdgen} %{deps} -j))) 28 | 29 | (rule 30 | (targets part3_t.ml part3_t.mli) 31 | (deps part3.atd) 32 | (action 33 | (run %{bin:atdgen} %{deps} -t))) 34 | 35 | (rule 36 | (targets part3_j.ml part3_j.mli) 37 | (deps part3.atd) 38 | (action 39 | (run %{bin:atdgen} %{deps} -j))) 40 | 41 | (cram 42 | (deps main.exe)) 43 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/inspect-biniou/tree.ml: -------------------------------------------------------------------------------- 1 | open Printf 2 | 3 | (* sample value *) 4 | let tree : Tree_t.tree = 5 | `Node ( 6 | `Node (`Empty, 1, `Empty), 7 | 2, 8 | `Node ( 9 | `Node (`Empty, 3, `Empty), 10 | 4, 11 | `Node (`Empty, 5, `Empty) 12 | ) 13 | ) 14 | 15 | let () = 16 | (* write sample value to file *) 17 | let fname = "tree.dat" in 18 | Atdgen_runtime.Util.Biniou.to_file Tree_b.write_tree fname tree; 19 | 20 | (* write sample value to string *) 21 | let s = Tree_b.string_of_tree tree in 22 | printf "raw value (saved as %s):\n%S\n" fname s; 23 | printf "length: %i\n" (String.length s); 24 | 25 | printf "pretty-printed value (without dictionary):\n"; 26 | print_endline (Bi_io.view s); 27 | 28 | printf "pretty-printed value (with dictionary):\n"; 29 | let unhash = Bi_io.make_unhash ["Empty"; "Node"; "foo"; "bar" ] in 30 | print_endline (Bi_io.view ~unhash s) 31 | -------------------------------------------------------------------------------- /atdgen/src/biniou.mli: -------------------------------------------------------------------------------- 1 | (** Biniou-specific options derived from ATD annotations. *) 2 | 3 | type biniou_int = 4 | [ `Svint | `Uvint | `Int8 | `Int16 | `Int32 | `Int64 ] 5 | 6 | type biniou_float = [ `Float32 | `Float64 ] 7 | 8 | type biniou_list = [ `Array | `Table ] 9 | 10 | type biniou_field = { biniou_unwrapped : bool } 11 | 12 | (** Biniou-specific options that decorate each kind of ATD AST node. *) 13 | type biniou_repr = 14 | | Unit 15 | | Bool 16 | | Int of biniou_int 17 | | Float of biniou_float 18 | 19 | | String 20 | | Sum 21 | | Record 22 | | Tuple 23 | | List of biniou_list 24 | | Option 25 | | Nullable 26 | | Wrap 27 | | External 28 | 29 | | Cell 30 | | Field of biniou_field 31 | | Variant 32 | | Def 33 | 34 | val annot_schema_biniou : Atd.Annot.schema 35 | 36 | val get_biniou_float : Atd.Annot.t -> biniou_float 37 | val get_biniou_int : Atd.Annot.t -> biniou_int 38 | val get_biniou_list : Atd.Annot.t -> biniou_list 39 | -------------------------------------------------------------------------------- /.ocp-indent: -------------------------------------------------------------------------------- 1 | # See https://github.com/OCamlPro/ocp-indent/blob/master/.ocp-indent for more 2 | 3 | # Indent for clauses inside a pattern-match (after the arrow): 4 | # match foo with 5 | # | _ -> 6 | # ^^^^bar 7 | # the default is 2, which aligns the pattern and the expression 8 | match_clause = 4 9 | 10 | # When nesting expressions on the same line, their indentation are in 11 | # some cases stacked, so that it remains correct if you close them one 12 | # at a line. This may lead to large indents in complex code though, so 13 | # this parameter can be used to set a maximum value. Note that it only 14 | # affects indentation after function arrows and opening parens at end 15 | # of line. 16 | # 17 | # for example (left: `none`; right: `4`) 18 | # let f = g (h (i (fun x -> # let f = g (h (i (fun x -> 19 | # x) # x) 20 | # ) # ) 21 | # ) # ) 22 | max_indent = 2 23 | -------------------------------------------------------------------------------- /atdcpp/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Dlang/JSON backend 3 | # 4 | 5 | DUNE ?= dune 6 | 7 | .PHONY: build 8 | build: 9 | rm -f bin/atdcpp 10 | $(MAKE) clean-for-dune 11 | $(DUNE) build @all 12 | mkdir -p bin 13 | ln -s ../../_build/install/default/bin/atdcpp bin/atdcpp 14 | 15 | # The symlink facilitates the development of test code that depends on the 16 | # generated code. 17 | .PHONY: test 18 | test: 19 | $(MAKE) clean-for-dune 20 | $(DUNE) runtest -f; status=$$?; \ 21 | ln -s ../../../_build/default/atdcpp/test/cpp-tests/everything_atd.hpp \ 22 | test/cpp-tests/everything_atd.hpp && \ 23 | ln -s ../../../_build/default/atdcpp/test/cpp-tests/everything_atd.cpp \ 24 | test/cpp-tests/everything_atd.cpp && \ 25 | exit "$$status" 26 | 27 | .PHONY: clean-for-dune 28 | clean-for-dune: 29 | rm -f test/cpp-tests/everything_atd.hpp 30 | rm -f test/cpp-tests/everything_atd.cpp 31 | 32 | .PHONY: clean 33 | clean: 34 | $(MAKE) clean-for-dune 35 | $(DUNE) clean 36 | rm -rf bin 37 | -------------------------------------------------------------------------------- /atddiff/src/lib/Atddiff_output_t.ml: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "Atddiff_output.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type variant_info = { variant_name: string } 5 | 6 | type position = { path: string; line: int; column: int } 7 | 8 | type location = { start: position; end_ (*atd end *): position } 9 | 10 | type field_info = { field_name: string } 11 | 12 | type incompatibility_kind = 13 | Missing_field of field_info 14 | | Missing_variant of variant_info 15 | | Missing_variant_argument of variant_info 16 | | Default_required of field_info 17 | | Incompatible_type 18 | | Deleted_type 19 | | Added_type 20 | 21 | 22 | type direction = Backward | Forward | Both 23 | 24 | type finding = { 25 | hash: string; 26 | direction: direction; 27 | kind: incompatibility_kind; 28 | location_old: location option; 29 | location_new: location option; 30 | description: string; 31 | affected_types: string list 32 | } 33 | 34 | type result = { findings: finding list } 35 | -------------------------------------------------------------------------------- /atddiff/src/lib/Atddiff_output_t.mli: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "Atddiff_output.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type variant_info = { variant_name: string } 5 | 6 | type position = { path: string; line: int; column: int } 7 | 8 | type location = { start: position; end_ (*atd end *): position } 9 | 10 | type field_info = { field_name: string } 11 | 12 | type incompatibility_kind = 13 | Missing_field of field_info 14 | | Missing_variant of variant_info 15 | | Missing_variant_argument of variant_info 16 | | Default_required of field_info 17 | | Incompatible_type 18 | | Deleted_type 19 | | Added_type 20 | 21 | 22 | type direction = Backward | Forward | Both 23 | 24 | type finding = { 25 | hash: string; 26 | direction: direction; 27 | kind: incompatibility_kind; 28 | location_old: location option; 29 | location_new: location option; 30 | description: string; 31 | affected_types: string list 32 | } 33 | 34 | type result = { findings: finding list } 35 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/validate/run.t: -------------------------------------------------------------------------------- 1 | Capturing the current output of the demo. 2 | 3 | $ ./resume.exe 4 | VALID: 5 | [ 6 | { 7 | "company": "Acme Corp.", 8 | "title": "Tester", 9 | "start_date": { "year": 2005, "month": 8, "day": 1 }, 10 | "end_date": { "year": 2006, "month": 3, "day": 22 } 11 | }, 12 | { 13 | "company": "Acme Corp.", 14 | "title": "Tester", 15 | "start_date": { "year": 2000, "month": 2, "day": 29 }, 16 | "end_date": { "year": 2006, "month": 3, "day": 22 } 17 | } 18 | ] 19 | INVALID: 20 | [ 21 | { 22 | "company": "Acme Corp.", 23 | "title": "Tester", 24 | "start_date": { "year": 2005, "month": 8, "day": 1 }, 25 | "end_date": { "year": 2006, "month": 3, "day": 22 } 26 | }, 27 | { 28 | "company": "Acme Corp.", 29 | "title": "Tester", 30 | "start_date": { "year": 2005, "month": 8, "day": 1 }, 31 | "end_date": { "year": 1900, "month": 0, "day": 0 } 32 | } 33 | ] 34 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/ordering.expected.txt: -------------------------------------------------------------------------------- 1 | [0ba447bf] Incompatibility in both directions: 2 | Incompatible kinds of types: list/array is now a string. 3 | The following types are affected: 4 | e 5 | 6 | [1c2c4aae] Incompatibility in both directions: 7 | Incompatible kinds of types: tuple is now a string. 8 | The following types are affected: 9 | c 10 | 11 | [2182fd1f] Incompatibility in both directions: 12 | Incompatible kinds of types: list/array is now a string. 13 | The following types are affected: 14 | b 15 | 16 | [2e525f5c] Incompatibility in both directions: 17 | Incompatible kinds of types: list/array is now a string. 18 | The following types are affected: 19 | f 20 | 21 | [3b527108] Incompatibility in both directions: 22 | Incompatible kinds of types: tuple is now a string. 23 | The following types are affected: 24 | d 25 | 26 | [3f176ef7] Incompatibility in both directions: 27 | Type names 'int' and 'string' are not the same and may not be compatible. 28 | The following types are affected: 29 | a 30 | 31 | -------------------------------------------------------------------------------- /atdts/src/lib/TS_annot.ml: -------------------------------------------------------------------------------- 1 | (* 2 | ATD annotations to be interpreted specifically by atdts. 3 | 4 | Atdts also honors json-related annotations defined in Atd.Json. 5 | *) 6 | 7 | type assoc_repr = 8 | | Array 9 | | Map 10 | 11 | let get_ts_default an : string option = 12 | Atd.Annot.get_opt_field 13 | ~parse:(fun s -> Some s) 14 | ~sections:["ts"] 15 | ~field:"default" 16 | an 17 | 18 | let get_ts_assoc_repr an : assoc_repr = 19 | Atd.Annot.get_field 20 | ~parse:(function 21 | | "array" -> Some Array 22 | | "map" -> Some Map 23 | | _ -> None 24 | ) 25 | ~default:Array 26 | ~sections:["ts"] 27 | ~field:"repr" 28 | an 29 | 30 | let get_ts_from an : string option = 31 | Atd.Annot.get_opt_field 32 | ~parse:(fun s -> Some s) 33 | ~sections:["ts"] 34 | ~field:"from" 35 | an 36 | 37 | let get_ts_type an : string option = 38 | Atd.Annot.get_opt_field 39 | ~parse:(fun s -> Some s) 40 | ~sections:["ts"] 41 | ~field:"t" 42 | an 43 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/pretty-json/run.t: -------------------------------------------------------------------------------- 1 | $ cat single.json 2 | [1234,"abcde",{"start_date":{"year":1970,"month":1,"day":1}, 3 | "end_date":{"year":1980,"month":1,"day":1}}] 4 | 5 | $ ydump single.json 6 | [ 7 | 1234, 8 | "abcde", 9 | { 10 | "start_date": { "year": 1970, "month": 1, "day": 1 }, 11 | "end_date": { "year": 1980, "month": 1, "day": 1 } 12 | } 13 | ] 14 | 15 | $ cat stream.json 16 | [1234,"abcde",{"start_date":{"year":1970,"month":1,"day":1}, 17 | "end_date":{"year":1980,"month":1,"day":1}}] 18 | [1,"a",{}] 19 | 20 | $ ydump -s stream.json 21 | [ 22 | 1234, 23 | "abcde", 24 | { 25 | "start_date": { "year": 1970, "month": 1, "day": 1 }, 26 | "end_date": { "year": 1980, "month": 1, "day": 1 } 27 | } 28 | ] 29 | [ 1, "a", {} ] 30 | 31 | $ ./prettify.exe 32 | [ 33 | 1234, 34 | "abcde", 35 | { 36 | "start_date": { "year": 1970, "month": 1, "day": 1 }, 37 | "end_date": { "year": 1980, "month": 1, "day": 1 } 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Circle CI configuration. Runs each time we push a new commit to Github. 3 | # 4 | version: 2.1 5 | 6 | commands: 7 | build: 8 | steps: 9 | - checkout 10 | - run: 11 | name: Install system dependencies 12 | command: ./.circleci/setup-system 13 | - run: 14 | name: Install opam dependencies 15 | command: ./.circleci/setup-opam 16 | - run: 17 | name: Build 18 | command: opam exec -- make 19 | - run: 20 | name: Test 21 | command: opam exec -- make test 22 | 23 | jobs: 24 | build_latest_ocaml: 25 | docker: 26 | - image: ocaml/opam:ubuntu-20.04-ocaml-4.13 27 | working_directory: ~/atd 28 | steps: 29 | - build 30 | 31 | build_min_ocaml: 32 | docker: 33 | - image: ocaml/opam:ubuntu-20.04-ocaml-4.08 34 | working_directory: ~/atd 35 | steps: 36 | - build 37 | 38 | workflows: 39 | version: 2 40 | build: 41 | jobs: 42 | - build_latest_ocaml 43 | - build_min_ocaml 44 | -------------------------------------------------------------------------------- /atds/src/atds_helper.ml: -------------------------------------------------------------------------------- 1 | (* Helper classes *) 2 | 3 | open Atd.Import 4 | open Atds_env 5 | 6 | (* TODO: Extract to to a plain file? *) 7 | 8 | let output_atds env = 9 | fprintf env.output "\ 10 | /** 11 | * Common utility interface. 12 | */ 13 | trait Atds { 14 | 15 | /** 16 | * Get the Argonaut JSON representation. 17 | * Please use the argonaut encoder rather than calling this directly. 18 | */ 19 | protected def toArgonaut: argonaut.Json 20 | 21 | // These may be optimized later, and the dependency on Argonaut could be removed. 22 | 23 | /** 24 | * Get the JSON string representation. 25 | * @return The JSON string. 26 | */ 27 | def toJson: String = toArgonaut.nospaces 28 | 29 | /** 30 | * Write the JSON representation to a buffer. 31 | */ 32 | def toJsonBuffer(out: java.lang.StringBuilder): Unit = out.append(toJson) 33 | 34 | } 35 | 36 | object Atds { 37 | 38 | implicit def argonautCodecAtds[A <: Atds] = new argonaut.EncodeJson[A] { 39 | override def encode(a: A) = a.toArgonaut 40 | } 41 | 42 | } 43 | " 44 | -------------------------------------------------------------------------------- /atd/test/doc.ml: -------------------------------------------------------------------------------- 1 | (* 2 | Unit tests for Atd.Doc 3 | *) 4 | 5 | open Printf 6 | 7 | let normalize s = 8 | s 9 | |> Atd.Doc.parse_text Atd.Ast.dummy_loc 10 | |> Atd.Doc.print_text 11 | 12 | let test_parser_and_printer = 13 | [ 14 | "", ""; 15 | "a", "a"; 16 | "a b", "a b"; 17 | "a\nb", "a b"; 18 | "a b", "a b"; 19 | "a \n b", "a b"; 20 | "a \n\n b", "a\n\nb"; 21 | " a ", "a"; 22 | "\n\na\n\n", "a"; 23 | "{{}}", ""; 24 | "{{a}}", "{{a}}"; 25 | "{{ a b\n\nc\n }}", "{{a b c}}"; 26 | "{{ {a} }}", "{{ {a} }}"; 27 | "{{{}}}", ""; 28 | "{{{a}}}", "{{{\na\n}}}"; 29 | "{{{ }}}", "{{{\n \n}}}"; 30 | "{{{ {{a}} }}}", "{{{\n {{a}} \n}}}"; 31 | "{{{ a\n\n b }}}", "{{{\n a\n\n b \n}}}"; 32 | ] 33 | |> List.map (fun (input, expected_output) -> 34 | let name = sprintf "normalize %S" input in 35 | name, `Quick, (fun () -> 36 | let output = normalize input in 37 | Alcotest.(check string) "equal" expected_output output 38 | ) 39 | ) 40 | 41 | let test = "Doc", test_parser_and_printer 42 | -------------------------------------------------------------------------------- /doc/atd-project.rst: -------------------------------------------------------------------------------- 1 | *************** 2 | The ATD Project 3 | *************** 4 | 5 | The ATD project aims to facilitate the design and the implementation of 6 | APIs, and in particular JSON APIs. It offers type safety and automatic 7 | data validation by deriving boilerplate code from type definitions. 8 | The data ends up being represented with idiomatic data structures in 9 | the target programming language, removing the hassle of manually 10 | converting from/to the JSON representation. 11 | 12 | Currently, the supported target languages are OCaml, Java, Scala, and 13 | Python. The project is run by volunteers and users from various 14 | organizations. Check out the 15 | `ATD project on GitHub `_ for any bug 16 | report, feature request, or question. 17 | 18 | Some properties of interest of ATD schemas include: 19 | 20 | * support for optional fields and default field values 21 | * support for sum types aka algebraic data types or tagged unions 22 | * options to select alternate representations than the default, e.g. 23 | use a JSON object rather than an array of pairs 24 | -------------------------------------------------------------------------------- /atdcat/test/test2.atd: -------------------------------------------------------------------------------- 1 | type z = abstract list 2 | 3 | type 'a t = int 4 | type x = float t 5 | 6 | type 'a l = [ Nil | Cons of ('a * 'a l) ] 7 | 8 | type int_l = int l 9 | type float_l = float l 10 | type tup = (int l * float_l) 11 | 12 | type ('a, 'b) tbl = ('a * 'b) list list 13 | type 'a string_tbl = (string, 'a) tbl 14 | type string_bool_tbl = bool string_tbl 15 | 16 | type 'a b = 'a a 17 | type 'a a = 'a b 18 | type c = c a b a 19 | 20 | 21 | type 'id gen_profile = { 22 | id : 'id; 23 | name : string option; 24 | age : int option 25 | } 26 | 27 | type basic_profile = int gen_profile 28 | 29 | type profile_enhancements = { 30 | credit_card_number : string 31 | } 32 | 33 | type ('id, 'self) nested_profile = { 34 | inherit 'id gen_profile; 35 | sub_profiles : 'self list 36 | } 37 | 38 | type profile = { 39 | inherit (int, profile) nested_profile; 40 | inherit profile_enhancements 41 | } 42 | (* expands to: 43 | 44 | type profile = { 45 | id: int; 46 | name: string option; 47 | age: int option; 48 | sub_profiles: profile list; 49 | credit_card_number: string 50 | } 51 | 52 | *) 53 | -------------------------------------------------------------------------------- /atddiff/test/default/type_name_change.expected.txt: -------------------------------------------------------------------------------- 1 | [20f6af79] Possible backward incompatibility: 2 | File "type_name_change_old.atd", line 2, characters 0-33: 3 | The definition for type 'old_name_for_root_type' no longer exists. 4 | The following types are affected: 5 | old_name_for_root_type 6 | 7 | [23b8d853] Possible backward incompatibility: 8 | File "type_name_change_old.atd", line 5, character 0 to line 7, character 1: 9 | The definition for type 'old_name_for_root_type_with_changes' no longer exists. 10 | The following types are affected: 11 | old_name_for_root_type_with_changes 12 | 13 | [3ad32ed9] Possible forward incompatibility: 14 | File "type_name_change_new.atd", line 2, characters 0-33: 15 | There is a new type named 'new_name_for_root_type'. 16 | The following types are affected: 17 | new_name_for_root_type 18 | 19 | [1b1d2804] Possible forward incompatibility: 20 | File "type_name_change_new.atd", line 5, character 0 to line 7, character 1: 21 | There is a new type named 'new_name_for_root_type_with_changes'. 22 | The following types are affected: 23 | new_name_for_root_type_with_changes 24 | 25 | -------------------------------------------------------------------------------- /atdgen-codec-runtime/src/encode.mli: -------------------------------------------------------------------------------- 1 | type 'a t = 'a -> Json.t 2 | 3 | val make : ('a -> Json.t) -> 'a t 4 | 5 | val encode : 'a t -> 'a -> Json.t 6 | 7 | val unit : unit t 8 | val string : string t 9 | val float : float t 10 | val int : int t 11 | val bool : bool t 12 | val char : char t 13 | 14 | val list : 'a t -> 'a list t 15 | val array : 'a t -> 'a array t 16 | 17 | val int32 : int32 t 18 | val int64 : int64 t 19 | 20 | type field 21 | 22 | val field : ?default:'a -> 'a t -> name:string -> 'a -> field 23 | val field_o : ?default:'a -> 'a t -> name:string -> 'a option -> field 24 | 25 | val obj : field list -> Json.t 26 | 27 | val tuple1 : 'a t -> 'a t 28 | val tuple2 : 'a t -> 'b t -> ('a * 'b) t 29 | val tuple3 : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t 30 | val tuple4 : 'a t -> 'b t -> 'c t -> 'd t -> ('a * 'b * 'c * 'd) t 31 | 32 | val constr0 : string -> Json.t 33 | val constr1 : string -> 'a t -> 'a -> Json.t 34 | 35 | val contramap : ('b -> 'a) -> 'a t -> 'b t 36 | 37 | val nullable : 'a t -> 'a option t 38 | 39 | val option_as_constr : 'a t -> 'a option t 40 | 41 | val adapter: (Json.t -> Json.t) -> 'a t -> 'a t 42 | -------------------------------------------------------------------------------- /atdgen/test/test3j_t.expected.ml: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test3j.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type rec_type = { more: rec_type list } 5 | 6 | type unixtime_list = float list 7 | 8 | type json = Yojson.Safe.t 9 | 10 | type tf_variant2 = [ 11 | `A of int 12 | | `B of int 13 | | `Unknown of (string * json option) 14 | ] 15 | 16 | type tf_variant = [ `A of int | `B of int ] 17 | 18 | type tf_record2 = { the_value2: tf_variant2; etc2: string } 19 | 20 | type tf_record = { the_value: tf_variant; etc: string } 21 | 22 | type dyn = Yojson.Safe.t 23 | 24 | type t = { foo: int; bar: json; baz: dyn } 25 | 26 | type sf_adapted = [ `A of bool | `B of int ] 27 | 28 | type sample_open_enum = [ `Alpha | `Beta | `Other of string ] 29 | 30 | type sample_open_enums = sample_open_enum list 31 | 32 | type patch = { 33 | patch1: int option option; 34 | patch2: int option option; 35 | patch3: int option option 36 | } 37 | 38 | type b = { thing: int } 39 | 40 | type a = { thing: string; other_thing: bool } 41 | 42 | type adapted_f = [ `FA of a | `FB of b ] 43 | 44 | type adapted = [ `A of a | `B of b ] 45 | -------------------------------------------------------------------------------- /atdgen/test/test3j_t.expected.mli: -------------------------------------------------------------------------------- 1 | (* Auto-generated from "test3j.atd" *) 2 | [@@@ocaml.warning "-27-32-33-35-39"] 3 | 4 | type rec_type = { more: rec_type list } 5 | 6 | type unixtime_list = float list 7 | 8 | type json = Yojson.Safe.t 9 | 10 | type tf_variant2 = [ 11 | `A of int 12 | | `B of int 13 | | `Unknown of (string * json option) 14 | ] 15 | 16 | type tf_variant = [ `A of int | `B of int ] 17 | 18 | type tf_record2 = { the_value2: tf_variant2; etc2: string } 19 | 20 | type tf_record = { the_value: tf_variant; etc: string } 21 | 22 | type dyn = Yojson.Safe.t 23 | 24 | type t = { foo: int; bar: json; baz: dyn } 25 | 26 | type sf_adapted = [ `A of bool | `B of int ] 27 | 28 | type sample_open_enum = [ `Alpha | `Beta | `Other of string ] 29 | 30 | type sample_open_enums = sample_open_enum list 31 | 32 | type patch = { 33 | patch1: int option option; 34 | patch2: int option option; 35 | patch3: int option option 36 | } 37 | 38 | type b = { thing: int } 39 | 40 | type a = { thing: string; other_thing: bool } 41 | 42 | type adapted_f = [ `FA of a | `FB of b ] 43 | 44 | type adapted = [ `A of a | `B of b ] 45 | -------------------------------------------------------------------------------- /manual/Makefile: -------------------------------------------------------------------------------- 1 | # `make pdf' requires pdflatex and builds readme.pdf 2 | # `make txt' requires hevea and builds readme.txt 3 | # `make html' requires hevea and builds readme.html 4 | 5 | TEXFILES = atd-manual atd-body 6 | 7 | .PHONY: all pdf txt html clean 8 | 9 | all: pdf txt html 10 | pdf: atd-manual.pdf 11 | txt: atd-manual.txt 12 | html: atd-manual.html 13 | 14 | atd-manual.tex: ../atd_version.ml atd-manual.mlx 15 | OCAMLPATH=../..:$$OCAMLPATH camlmix atd-manual.mlx -o atd-manual.tex 16 | 17 | atd-body.tex: ../atd_version.ml macros.ml atd-body.mlx 18 | OCAMLPATH=../..:$$OCAMLPATH camlmix atd-body.mlx -o atd-body.tex 19 | 20 | atd-manual.txt: $(addsuffix .tex, $(TEXFILES)) 21 | rm -f *.aux 22 | hevea -fix -text atd-manual 23 | iconv -f ISO_8859-1 -t UTF-8 < atd-manual.txt > ../atd-manual.txt 24 | 25 | atd-manual.html: $(addsuffix .tex, $(TEXFILES)) 26 | rm -f *.aux 27 | hevea -fix atd-manual 28 | 29 | atd-manual.pdf: $(addsuffix .tex, $(TEXFILES)) 30 | pdflatex atd-manual 31 | pdflatex atd-manual 32 | 33 | clean: 34 | rm -f *.aux *.toc *.log *.out *.haux *.htoc *.fls *.mlx.ml \ 35 | atd-manual.pdf atd-manual.txt atd-manual.html 36 | -------------------------------------------------------------------------------- /atdgen/test/spec_js/test_mel.ml: -------------------------------------------------------------------------------- 1 | let make = Atdgen_codec_runtime.Encode.encode 2 | 3 | module M = Spec_js.Make(struct 4 | open Spec_js.Mel 5 | 6 | let r1 = make write_r1 7 | let r2 = make write_r2 8 | let r3 = make write_r3 9 | let r4 = make write_r4 10 | let r5 = make write_r5 11 | let r6 = make write_r6 12 | let r7 = make write_r7 13 | let r8 = make write_r8 14 | let j1 = make write_j1 15 | let j2 = make write_j2 16 | let j3 = make write_j3 17 | let j4 = make write_j4 18 | let o1 = make write_o1 19 | let o2 = make write_o2 20 | let t1 = make write_t1 21 | let t2 = make write_t2 22 | let v1list = make write_v1list 23 | let v2 = make write_v2 24 | let v3list = make write_v3list 25 | let ages = make write_ages 26 | let open_enum = make write_open_enum 27 | let open_enum_list = make write_open_enum_list 28 | end) 29 | 30 | let () = M.run () 31 | -------------------------------------------------------------------------------- /atdgen/TODO.md: -------------------------------------------------------------------------------- 1 | * Support JSON object syntax for variants, e.g.: 2 | type t = A | B of int 3 | Currently supported: "A" 4 | ["B", 123] 5 | <"A"> 6 | <"B":123> 7 | To do: {"A": null} 8 | {"B": 123} 9 | 10 | * Find a good way to support variants represented as records whose type is 11 | given by one of their fields. 12 | 13 | * Plans for atdgen 2: 14 | - create one (sub)command for each target language 15 | (atdgen-ocaml, atdgen-java, atdgen-atd, atdgen-ts) 16 | - imply -std-json, i.e. do not produce code that produces JSON 17 | in the extended syntax for variants (<"A">, <"B":123>) 18 | or tuples (("a", 123, {"x":0})) 19 | - make it possible to produce all outputs in one call to atdgen. 20 | "atdgen foo -m tjv" would read file "foo.atd" and produce 21 | files foo_{t|j|v}.{ml|mli} 22 | - use classic variants instead of polymorphic variants by default 23 | since ocaml >= 4.01 makes them easier to use 24 | 25 | * Support for other languages: 26 | - merge atdj (JSON serializers for Java) into atdgen 27 | - translate ATD into TypeScript type definitions 28 | -------------------------------------------------------------------------------- /atdj/test/test.atd: -------------------------------------------------------------------------------- 1 | (* Sum (enum) *) 2 | type e = [ Alpha | Beta ] 3 | 4 | (* Sum *) 5 | type sample_sum = [ 6 | | Simple_tag 7 | | Bool of bool 8 | | Int of int 9 | | Float of float 10 | | String of string 11 | | Simple_record of simple_record 12 | | Complex_record of complex_record 13 | | Record_with_defaults of record_with_defaults 14 | ] 15 | 16 | (* Record *) 17 | type complex_record = { 18 | b : bool; 19 | i : int; 20 | s : string; 21 | l : bool list; 22 | sample_sum : sample_sum; 23 | 24 | (* Java keywords used as field names *) 25 | ?class : int option; 26 | ?final : int option; 27 | 28 | (* List of records *) 29 | l2 : record_with_defaults list; 30 | } 31 | 32 | 33 | 34 | (* Record with default fields *) 35 | type record_with_defaults = { 36 | ~b : bool; 37 | ~i : int; 38 | ~s : string; 39 | ~o : bool option; 40 | ~l : bool list; 41 | ~e : e; 42 | } 43 | 44 | (* Record with optional field *) 45 | type simple_record = { ?o : bool option } 46 | 47 | (* https://github.com/esperco/atdj/issues/2 *) 48 | type a = [ A of b list ] 49 | type b = [ B ] 50 | -------------------------------------------------------------------------------- /atds/test/AtdsTest.scala: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | import org.junit.Assert._; 3 | import com.mylife.test._; 4 | import argonaut._, Argonaut._ 5 | 6 | class AtdsTest { 7 | 8 | @Test 9 | def testSimpleSum() { 10 | val i: SampleSum = SampleSum.Integer(42) 11 | assertEquals("""["Int",42]""", i.asJson.nospaces) 12 | 13 | val b = SampleSum.Bool(true) 14 | assertEquals("""["Bool",true]""", b.asJson.nospaces) 15 | 16 | val s = SampleSum.SimpleTag 17 | assertEquals("\"Simple_tag\"", s.asJson.nospaces) 18 | } 19 | 20 | @Test 21 | def testDefaults() { 22 | val r = RecordWithDefaults(e = E.Alpha) 23 | assertEquals("""{"e":"Alpha","s":"","i":0,"b":false,"l":[],"o":null}""", r.asJson.nospaces) 24 | } 25 | 26 | @Test 27 | def testSumWithRecord { 28 | val r = SimpleRecord(57, None) 29 | val s = SampleSum.SimpleRec(r) 30 | 31 | val rstr = """{"int_field":57,"opt":null}""" 32 | assertEquals(rstr, r.asJson.nospaces) 33 | assertEquals(s"""["Simple_rec",$rstr]""", s.asJson.nospaces) 34 | } 35 | 36 | } 37 | object AtdsTest { 38 | 39 | def main(args: Array[String]) { 40 | org.junit.runner.JUnitCore.main("AtdsTest"); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /atdts/README.md: -------------------------------------------------------------------------------- 1 | Atdts 2 | == 3 | 4 | Atdts takes type definitions in the ATD format and derives TypeScript 5 | classes that can read and write JSON data. This saves the developer the 6 | labor writing boilerplate that converts between dicts and classes. 7 | 8 | This allows safe interoperability with other languages supported by 9 | ATD such as OCaml, Java, Scala, or Python. 10 | 11 | See the sample input type definitions 12 | [everything.atd](test/atd-input/everything.atd) and 13 | the TypeScript output [everything.ts](test/ts-expected/everything.ts). 14 | 15 | Requirements 16 | -- 17 | 18 | ... 19 | 20 | Documentation 21 | -- 22 | 23 | * [Main documentation for 24 | atdts](https://atd.readthedocs.io/en/latest/atdts.html) 25 | * Command-line documentation: `atdts --help` 26 | 27 | Development notes 28 | -- 29 | 30 | ... 31 | 32 | Contributing 33 | -- 34 | 35 | Help is welcome and there are various ways to help: 36 | * Add examples to the documentation 37 | * File a GitHub issue to report a problem 38 | * Pick an issue that [has the `target:typescript` 39 | label](https://github.com/ahrefs/atd/issues?q=is%3Aissue+is%3Aopen+label%3Atarget%3Atypescript) 40 | and implement a solution 41 | -------------------------------------------------------------------------------- /atdgen/test/spec_js/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name spec_js) 3 | (modules spec_t spec_j spec_js spec_mel) 4 | (libraries atdgen-runtime atdgen-codec-runtime biniou yojson)) 5 | 6 | (rule 7 | (targets spec_t.ml spec_t.mli) 8 | (deps spec.atd) 9 | (action (run atdgen %{deps} -t))) 10 | 11 | (rule 12 | (targets spec_j.ml spec_j.mli) 13 | (deps spec.atd) 14 | (action (run atdgen %{deps} -j -j-std))) 15 | 16 | (rule 17 | (targets spec_mel.ml spec_mel.mli) 18 | (deps spec.atd) 19 | (action (run atdgen %{deps} -mel))) 20 | 21 | (executable 22 | (name test_j) 23 | (modules test_j) 24 | (libraries spec_js atdgen-runtime yojson)) 25 | 26 | (executable 27 | (name test_mel) 28 | (modules test_mel) 29 | (libraries spec_js atdgen-codec-runtime yojson)) 30 | 31 | (rule 32 | (targets spec_j.json) 33 | (action (with-stdout-to %{targets} (run ./test_j.exe)))) 34 | 35 | (rule 36 | (alias runtest) 37 | (package atdgen) 38 | (action (diff spec_j.expected.json spec_j.json))) 39 | 40 | (rule 41 | (targets spec_mel.json) 42 | (action (with-stdout-to %{targets} (run ./test_mel.exe)))) 43 | 44 | (rule 45 | (alias runtest) 46 | (package atdgen) 47 | (action (diff spec_mel.expected.json spec_mel.json))) 48 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/config-file/demo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | set -x 4 | 5 | # Embed the contents of the .atd file into our OCaml program 6 | echo 'let contents = "\' > config_atd.ml 7 | sed -e 's/\([\\"]\)/\\\1/g' config.atd >> config_atd.ml 8 | echo '"' >> config_atd.ml 9 | 10 | # Derive OCaml type definitions from .atd file 11 | atdgen -t config.atd 12 | 13 | # Derive JSON-related functions from .atd file 14 | atdgen -j -j-defaults -j-strict-fields config.atd 15 | 16 | # Derive validator from .atd file 17 | atdgen -v config.atd 18 | 19 | # Compile the OCaml program 20 | ocamlfind ocamlopt -o config \ 21 | config_t.mli config_t.ml config_j.mli config_j.ml config_v.mli config_v.ml \ 22 | config_atd.ml config.ml -package atdgen -linkpkg 23 | 24 | # Output a sample config 25 | ./config -template 26 | 27 | # Print the original type definitions 28 | ./config -format 29 | 30 | # Fail to validate an invalid config file 31 | ./config -validate bad-config1.json || : 32 | 33 | # Fail to validate another invalid config file (using custom validators) 34 | ./config -validate bad-config2.json || : 35 | 36 | # Validate, inject missing defaults and pretty-print 37 | ./config -validate sample-config.json 38 | -------------------------------------------------------------------------------- /atdj/test/expected/SimpleRecord.java: -------------------------------------------------------------------------------- 1 | // Automatically generated; do not edit 2 | package com.mylife.test; 3 | import org.json.*; 4 | 5 | public class SimpleRecord implements Atdj { 6 | /** 7 | * Construct from a fresh record with null fields. 8 | */ 9 | public SimpleRecord() { 10 | } 11 | 12 | /** 13 | * Construct from a JSON string. 14 | */ 15 | public SimpleRecord(String s) throws JSONException { 16 | this(new JSONObject(s)); 17 | } 18 | 19 | SimpleRecord(JSONObject jo) throws JSONException { 20 | if (jo.has("o")) { 21 | o = jo.optBoolean("o"); 22 | } 23 | 24 | } 25 | 26 | public void toJsonBuffer(StringBuilder _out) throws JSONException { 27 | boolean _isFirst = true; 28 | _out.append("{"); 29 | if (o != null) { 30 | if (_isFirst) 31 | _isFirst = false; 32 | else 33 | _out.append(","); 34 | _out.append("\"o\":"); 35 | _out.append(String.valueOf(o)); 36 | } 37 | 38 | _out.append("}"); 39 | } 40 | 41 | public String toJson() throws JSONException { 42 | StringBuilder out = new StringBuilder(128); 43 | toJsonBuffer(out); 44 | return out.toString(); 45 | } 46 | public Boolean o; 47 | } 48 | -------------------------------------------------------------------------------- /atdcat/test/schema.atd: -------------------------------------------------------------------------------- 1 | (* Input ATD file for testing the translation to JSON Schema *) 2 | 3 | 9 | 10 | type different_kinds_of_things = [ 11 | | Root 12 | | Thing of int 13 | | WOW 14 | | Amaze of string list 15 | ] 16 | 17 | type root 18 | 20 | = { 21 | id 22 | 23 | 24 | : string; 25 | items 26 | 27 | : int list list; 28 | ?maybe: int option; 29 | ~extras: int list; 30 | ~answer: int; 31 | aliased: alias; 32 | point: (float * float); 33 | kinds: different_kinds_of_things list; 34 | assoc1: (float * int) list; 35 | assoc2: (string * int) list ; 36 | ~options: int option list; 37 | ~nullables: int nullable list; 38 | ~untyped_things: abstract list; 39 | } 40 | 41 | type alias = int list 42 | 43 | type pair = (string * int) 44 | -------------------------------------------------------------------------------- /atdgen/src/indent.mli: -------------------------------------------------------------------------------- 1 | (** Simple indentation utility for code generators *) 2 | 3 | type t = 4 | | Line of string (** single line (not indented) **) 5 | | Block of t list (** indented sequence **) 6 | | Inline of t list (** in-line sequence (not indented) **) 7 | | Annot of string * t (** arbitrary annotation **) 8 | 9 | val paren : t -> t 10 | 11 | val strip : t -> t 12 | 13 | val concat : 'a -> 'a list -> 'a list 14 | 15 | val to_buffer : ?offset:int -> ?indent:int -> Buffer.t -> t list -> unit 16 | (** Write to a buffer. 17 | 18 | @param offset defines the number of space characters 19 | to use for the left margin. Default: 0. 20 | 21 | @param indent defines the number of space characters to use for 22 | indenting blocks. Default: 2. 23 | *) 24 | 25 | val to_string : ?offset:int -> ?indent:int -> t list -> string 26 | (** Write to a string. See [to_buffer] for the options. *) 27 | 28 | val to_channel : ?offset:int -> ?indent:int -> out_channel -> t list -> unit 29 | (** Write to a channel. See [to_buffer] for the options. *) 30 | 31 | val to_stdout : ?offset:int -> ?indent:int -> t list -> unit 32 | (** Write to [stdout]. See [to_buffer] for the options. *) 33 | -------------------------------------------------------------------------------- /atds/src/atds_util.ml: -------------------------------------------------------------------------------- 1 | (* Utilities *) 2 | 3 | open Atd.Import 4 | open Atds_env 5 | 6 | (* Get rid of `wrap' constructors that we don't support on the Java side yet. 7 | They could be useful for timestamps, though. *) 8 | let rec unwrap atd_ty = 9 | match atd_ty with 10 | | Atd.Ast.Wrap (_, x, _) -> unwrap x 11 | | x -> x 12 | 13 | (* Normalise an ATD type by expanding `top-level' type aliases *) 14 | let rec norm_ty env atd_ty = 15 | let atd_ty = unwrap atd_ty in 16 | match atd_ty with 17 | | Atd.Ast.Name (_, (_, name, _), _) -> 18 | (match name with 19 | | "bool" | "int" | "float" | "string" | "abstract" -> atd_ty 20 | | _ -> 21 | (match List.assoc name env.module_items with 22 | | Some x -> norm_ty env x 23 | | None -> 24 | eprintf "Warning: unknown type %s\n%!" name; 25 | atd_ty) 26 | ) 27 | | _ -> 28 | atd_ty 29 | 30 | let type_not_supported x = 31 | let loc = Atd.Ast.loc_of_type_expr x in 32 | Atd.Ast.error_at loc "Type not supported by atds." 33 | 34 | let warning loc msg = 35 | let loc_s = Atd.Ast.string_of_loc loc in 36 | eprintf "\ 37 | Warning: 38 | %s 39 | %s 40 | %!" 41 | loc_s 42 | msg 43 | -------------------------------------------------------------------------------- /atdgen/test/spec_js/test_j.ml: -------------------------------------------------------------------------------- 1 | open Spec_js.J 2 | 3 | let make f x = 4 | Yojson.Safe.from_string (f x) 5 | 6 | module M = Spec_js.Make(struct 7 | let r1 = make string_of_r1 8 | let r2 = make string_of_r2 9 | let r3 = make string_of_r3 10 | let r4 = make string_of_r4 11 | let r5 = make string_of_r5 12 | let r6 = make string_of_r6 13 | let r7 = make string_of_r7 14 | let r8 = make string_of_r8 15 | let j1 = make string_of_j1 16 | let j2 = make string_of_j2 17 | let j3 = make string_of_j3 18 | let j4 = make string_of_j4 19 | let o1 = make string_of_o1 20 | let o2 = make string_of_o2 21 | let t1 = make string_of_t1 22 | let t2 = make string_of_t2 23 | let v1list = make string_of_v1list 24 | let v2 = make string_of_v2 25 | let v3list = make string_of_v3list 26 | let ages = make string_of_ages 27 | let open_enum = make string_of_open_enum 28 | let open_enum_list = make string_of_open_enum_list 29 | end) 30 | 31 | let () = M.run() 32 | -------------------------------------------------------------------------------- /doc/atdgen-tutorial-data/validate/resume.ml: -------------------------------------------------------------------------------- 1 | let check_experience x = 2 | let is_valid = match Resume_v.validate_work_experience [] x with 3 | | None -> true 4 | | _ -> false 5 | in 6 | Printf.printf "%s:\n%s\n" 7 | (if is_valid then "VALID" else "INVALID") 8 | (Yojson.Safe.prettify (Resume_j.string_of_work_experience x)) 9 | 10 | let () = 11 | (* one valid date *) 12 | let valid = { Resume_t.year = 2000; month = 2; day = 29 } in 13 | (* one invalid date *) 14 | let invalid = { Resume_t.year = 1900; month = 0; day = 0 } in 15 | (* two more valid dates, created with Resume_v.create_date *) 16 | let date1 = { Resume_t.year = 2005; month = 8; day = 1 } in 17 | let date2 = { Resume_t.year = 2006; month = 3; day = 22 } in 18 | 19 | let job = { 20 | Resume_t.company = "Acme Corp."; 21 | title = "Tester"; 22 | start_date = date1; 23 | end_date = Some date2; 24 | } 25 | in 26 | let valid_job = { job with Resume_t.start_date = valid } in 27 | let invalid_job = { job with Resume_t.end_date = Some invalid } in 28 | let valid_experience = [ job; valid_job ] in 29 | let invalid_experience = [ job; invalid_job ] in 30 | check_experience valid_experience; 31 | check_experience invalid_experience 32 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_json/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets ordering.txt) 5 | (deps ordering_old.atd ordering_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --no-locations -f json))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps ordering.txt) 15 | (action (diff ordering.expected.txt ordering.txt))) 16 | 17 | (rule 18 | (targets same_hash.txt) 19 | (deps same_hash_old.atd same_hash_new.atd) 20 | (action 21 | (with-accepted-exit-codes 22 | 0 23 | (with-outputs-to %{targets} 24 | (run %{bin:atddiff} %{deps} --exit-success --no-locations -f json))))) 25 | 26 | (rule 27 | (alias runtest) 28 | (deps same_hash.txt) 29 | (action (diff same_hash.expected.txt same_hash.txt))) 30 | 31 | (rule 32 | (targets simple.txt) 33 | (deps simple_old.atd simple_new.atd) 34 | (action 35 | (with-accepted-exit-codes 36 | 0 37 | (with-outputs-to %{targets} 38 | (run %{bin:atddiff} %{deps} --exit-success --no-locations -f json))))) 39 | 40 | (rule 41 | (alias runtest) 42 | (deps simple.txt) 43 | (action (diff simple.expected.txt simple.txt))) 44 | 45 | -------------------------------------------------------------------------------- /atddiff/test/no_locations_text/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets ordering.txt) 5 | (deps ordering_old.atd ordering_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --no-locations -f text))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps ordering.txt) 15 | (action (diff ordering.expected.txt ordering.txt))) 16 | 17 | (rule 18 | (targets same_hash.txt) 19 | (deps same_hash_old.atd same_hash_new.atd) 20 | (action 21 | (with-accepted-exit-codes 22 | 0 23 | (with-outputs-to %{targets} 24 | (run %{bin:atddiff} %{deps} --exit-success --no-locations -f text))))) 25 | 26 | (rule 27 | (alias runtest) 28 | (deps same_hash.txt) 29 | (action (diff same_hash.expected.txt same_hash.txt))) 30 | 31 | (rule 32 | (targets simple.txt) 33 | (deps simple_old.atd simple_new.atd) 34 | (action 35 | (with-accepted-exit-codes 36 | 0 37 | (with-outputs-to %{targets} 38 | (run %{bin:atddiff} %{deps} --exit-success --no-locations -f text))))) 39 | 40 | (rule 41 | (alias runtest) 42 | (deps simple.txt) 43 | (action (diff simple.expected.txt simple.txt))) 44 | 45 | -------------------------------------------------------------------------------- /atdd/src/lib/Indent.mli: -------------------------------------------------------------------------------- 1 | (** Simple indentation utility for code generators *) 2 | 3 | type node = 4 | | Line of string (** single line (not indented) **) 5 | | Block of node list (** indented sequence **) 6 | | Inline of node list (** in-line sequence (not indented) **) 7 | 8 | type t = node list 9 | 10 | val is_empty_node : node -> bool 11 | 12 | val to_buffer : ?offset:int -> ?indent:int -> Buffer.t -> t -> unit 13 | (** Write to a buffer. 14 | 15 | @param offset defines the number of space characters 16 | to use for the left margin. Default: 0. 17 | 18 | @param indent defines the number of space characters to use for 19 | indenting blocks. Default: 2. 20 | *) 21 | 22 | val to_string : ?offset:int -> ?indent:int -> t -> string 23 | (** Write to a string. See [to_buffer] for the options. *) 24 | 25 | val to_channel : ?offset:int -> ?indent:int -> out_channel -> t -> unit 26 | (** Write to a channel. See [to_buffer] for the options. *) 27 | 28 | val to_stdout : ?offset:int -> ?indent:int -> t -> unit 29 | (** Write to [stdout]. See [to_buffer] for the options. *) 30 | 31 | val to_file : ?indent:int -> string -> t -> unit 32 | (** Write to a file, overwriting it if it was already there. 33 | See [to_buffer] for the options. *) 34 | -------------------------------------------------------------------------------- /atdcpp/src/lib/Indent.mli: -------------------------------------------------------------------------------- 1 | (** Simple indentation utility for code generators *) 2 | 3 | type node = 4 | | Line of string (** single line (not indented) **) 5 | | Block of node list (** indented sequence **) 6 | | Inline of node list (** in-line sequence (not indented) **) 7 | 8 | type t = node list 9 | 10 | val is_empty_node : node -> bool 11 | 12 | val to_buffer : ?offset:int -> ?indent:int -> Buffer.t -> t -> unit 13 | (** Write to a buffer. 14 | 15 | @param offset defines the number of space characters 16 | to use for the left margin. Default: 0. 17 | 18 | @param indent defines the number of space characters to use for 19 | indenting blocks. Default: 2. 20 | *) 21 | 22 | val to_string : ?offset:int -> ?indent:int -> t -> string 23 | (** Write to a string. See [to_buffer] for the options. *) 24 | 25 | val to_channel : ?offset:int -> ?indent:int -> out_channel -> t -> unit 26 | (** Write to a channel. See [to_buffer] for the options. *) 27 | 28 | val to_stdout : ?offset:int -> ?indent:int -> t -> unit 29 | (** Write to [stdout]. See [to_buffer] for the options. *) 30 | 31 | val to_file : ?indent:int -> string -> t -> unit 32 | (** Write to a file, overwriting it if it was already there. 33 | See [to_buffer] for the options. *) 34 | -------------------------------------------------------------------------------- /atdpy/src/lib/Indent.mli: -------------------------------------------------------------------------------- 1 | (** Simple indentation utility for code generators *) 2 | 3 | type node = 4 | | Line of string (** single line (not indented) **) 5 | | Block of node list (** indented sequence **) 6 | | Inline of node list (** in-line sequence (not indented) **) 7 | 8 | type t = node list 9 | 10 | val is_empty_node : node -> bool 11 | 12 | val to_buffer : ?offset:int -> ?indent:int -> Buffer.t -> t -> unit 13 | (** Write to a buffer. 14 | 15 | @param offset defines the number of space characters 16 | to use for the left margin. Default: 0. 17 | 18 | @param indent defines the number of space characters to use for 19 | indenting blocks. Default: 2. 20 | *) 21 | 22 | val to_string : ?offset:int -> ?indent:int -> t -> string 23 | (** Write to a string. See [to_buffer] for the options. *) 24 | 25 | val to_channel : ?offset:int -> ?indent:int -> out_channel -> t -> unit 26 | (** Write to a channel. See [to_buffer] for the options. *) 27 | 28 | val to_stdout : ?offset:int -> ?indent:int -> t -> unit 29 | (** Write to [stdout]. See [to_buffer] for the options. *) 30 | 31 | val to_file : ?indent:int -> string -> t -> unit 32 | (** Write to a file, overwriting it if it was already there. 33 | See [to_buffer] for the options. *) 34 | -------------------------------------------------------------------------------- /atdts/src/lib/Indent.mli: -------------------------------------------------------------------------------- 1 | (** Simple indentation utility for code generators *) 2 | 3 | type node = 4 | | Line of string (** single line (not indented) **) 5 | | Block of node list (** indented sequence **) 6 | | Inline of node list (** in-line sequence (not indented) **) 7 | 8 | type t = node list 9 | 10 | val is_empty_node : node -> bool 11 | 12 | val to_buffer : ?offset:int -> ?indent:int -> Buffer.t -> t -> unit 13 | (** Write to a buffer. 14 | 15 | @param offset defines the number of space characters 16 | to use for the left margin. Default: 0. 17 | 18 | @param indent defines the number of space characters to use for 19 | indenting blocks. Default: 2. 20 | *) 21 | 22 | val to_string : ?offset:int -> ?indent:int -> t -> string 23 | (** Write to a string. See [to_buffer] for the options. *) 24 | 25 | val to_channel : ?offset:int -> ?indent:int -> out_channel -> t -> unit 26 | (** Write to a channel. See [to_buffer] for the options. *) 27 | 28 | val to_stdout : ?offset:int -> ?indent:int -> t -> unit 29 | (** Write to [stdout]. See [to_buffer] for the options. *) 30 | 31 | val to_file : ?indent:int -> string -> t -> unit 32 | (** Write to a file, overwriting it if it was already there. 33 | See [to_buffer] for the options. *) 34 | -------------------------------------------------------------------------------- /atdgen-codec-runtime/src/decode.mli: -------------------------------------------------------------------------------- 1 | type 'a t = Json.t -> 'a 2 | 3 | val make : (Json.t -> 'a) -> 'a t 4 | 5 | val decode : 'a t -> Json.t -> 'a 6 | 7 | val unit : unit t 8 | val bool : bool t 9 | val int : int t 10 | val float : float t 11 | val char : char t 12 | val string : string t 13 | 14 | val optional : 'a t -> 'a option t 15 | val list : 'a t -> 'a list t 16 | val array : 'a t -> 'a array t 17 | val obj_list : 'a t -> (string * 'a) list t 18 | val obj_array : 'a t -> (string * 'a) array t 19 | 20 | (* a field that should be present *) 21 | val field : string -> 'a t -> 'a t 22 | 23 | (* a field that turns into a an optional value when absent *) 24 | val fieldDefault : string -> 'a -> 'a t -> 'a t 25 | 26 | (* a field that returns None when is absent *) 27 | val fieldOptional : string -> 'a t -> 'a option t 28 | 29 | val map : ('a -> 'b) -> 'a t -> 'b t 30 | 31 | val tuple1 : 'a t -> 'a t 32 | val tuple2 : 'a t -> 'b t -> ('a * 'b) t 33 | val tuple3 : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t 34 | val tuple4 : 'a t -> 'b t -> 'c t -> 'd t -> ('a * 'b * 'c * 'd) t 35 | 36 | val enum : (string * [`Single of 'a | `Decode of 'a t]) list -> 'a t 37 | 38 | val option_as_constr : 'a t -> 'a option t 39 | 40 | val nullable : 'a t -> 'a option t 41 | 42 | val adapter: (Json.t -> Json.t) -> 'a t -> 'a t 43 | -------------------------------------------------------------------------------- /atdgen-codec-runtime/src/json_adapter.ml: -------------------------------------------------------------------------------- 1 | (* Json adapters. See .mli. *) 2 | 3 | module type S = sig 4 | val normalize : Json.t -> Json.t 5 | val restore : Json.t -> Json.t 6 | end 7 | 8 | module Type_field = struct 9 | module type Param = sig 10 | val type_field_name : string 11 | end 12 | 13 | module Make (Param : Param) : S = struct 14 | open Param 15 | 16 | let normalize (x : Json.t) : Json.t = 17 | match x with 18 | | `Assoc fields -> 19 | (match List.assoc type_field_name fields with 20 | | `String type_ -> `List [ `String type_; x ] 21 | | exception Not_found -> x 22 | | _ -> x (* malformed *) 23 | ) 24 | | `String _ as x -> x 25 | | malformed -> malformed 26 | 27 | let restore (x : Json.t) : Json.t = 28 | match x with 29 | | `List [ `String type_; `Assoc fields ] -> 30 | let fields = 31 | (type_field_name, `String type_) :: 32 | List.filter (fun (k, _) -> k <> type_field_name) fields 33 | in 34 | `Assoc fields 35 | | `String _ as x -> x 36 | | malformed -> malformed 37 | end 38 | 39 | module Default_param : Param = struct 40 | let type_field_name = "type" 41 | end 42 | 43 | include Make (Default_param) 44 | end 45 | -------------------------------------------------------------------------------- /atdj/test/expected/B.java: -------------------------------------------------------------------------------- 1 | // Automatically generated; do not edit 2 | package com.mylife.test; 3 | import org.json.*; 4 | 5 | /** 6 | * Construct objects of type b. 7 | */ 8 | 9 | public class B { 10 | Tag t = null; 11 | 12 | public B() { 13 | } 14 | 15 | public Tag tag() { 16 | return t; 17 | } 18 | 19 | /** 20 | * Define tags for sum type b. 21 | */ 22 | public enum Tag { 23 | B 24 | } 25 | 26 | public B(Object o) throws JSONException { 27 | String tag = Util.extractTag(o); 28 | if (tag.equals("B")) 29 | t = Tag.B; 30 | else 31 | throw new JSONException("Invalid tag: " + tag); 32 | } 33 | 34 | public void setB() { 35 | /* TODO: clear previously-set field and avoid memory leak */ 36 | t = Tag.B; 37 | } 38 | 39 | public void toJsonBuffer(StringBuilder _out) throws JSONException { 40 | if (t == null) 41 | throw new JSONException("Uninitialized B"); 42 | else { 43 | switch(t) { 44 | case B: 45 | _out.append("\"B\""); 46 | break; 47 | default: 48 | break; /* unused; keeps compiler happy */ 49 | } 50 | } 51 | } 52 | 53 | public String toJson() throws JSONException { 54 | StringBuilder out = new StringBuilder(128); 55 | toJsonBuffer(out); 56 | return out.toString(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets backward_incompatible_record_if_implicit_defaults.txt) 5 | (deps backward_incompatible_record_if_implicit_defaults_old.atd backward_incompatible_record_if_implicit_defaults_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --json-defaults))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps backward_incompatible_record_if_implicit_defaults.txt) 15 | (action (diff backward_incompatible_record_if_implicit_defaults.expected.txt backward_incompatible_record_if_implicit_defaults.txt))) 16 | 17 | (rule 18 | (targets forward_incompatible_record_if_implicit_defaults.txt) 19 | (deps forward_incompatible_record_if_implicit_defaults_old.atd forward_incompatible_record_if_implicit_defaults_new.atd) 20 | (action 21 | (with-accepted-exit-codes 22 | 0 23 | (with-outputs-to %{targets} 24 | (run %{bin:atddiff} %{deps} --exit-success --json-defaults))))) 25 | 26 | (rule 27 | (alias runtest) 28 | (deps forward_incompatible_record_if_implicit_defaults.txt) 29 | (action (diff forward_incompatible_record_if_implicit_defaults.expected.txt forward_incompatible_record_if_implicit_defaults.txt))) 30 | 31 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults_new/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets backward_incompatible_record_if_implicit_defaults.txt) 5 | (deps backward_incompatible_record_if_implicit_defaults_old.atd backward_incompatible_record_if_implicit_defaults_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --json-defaults-new))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps backward_incompatible_record_if_implicit_defaults.txt) 15 | (action (diff backward_incompatible_record_if_implicit_defaults.expected.txt backward_incompatible_record_if_implicit_defaults.txt))) 16 | 17 | (rule 18 | (targets forward_incompatible_record_if_implicit_defaults.txt) 19 | (deps forward_incompatible_record_if_implicit_defaults_old.atd forward_incompatible_record_if_implicit_defaults_new.atd) 20 | (action 21 | (with-accepted-exit-codes 22 | 0 23 | (with-outputs-to %{targets} 24 | (run %{bin:atddiff} %{deps} --exit-success --json-defaults-new))))) 25 | 26 | (rule 27 | (alias runtest) 28 | (deps forward_incompatible_record_if_implicit_defaults.txt) 29 | (action (diff forward_incompatible_record_if_implicit_defaults.expected.txt forward_incompatible_record_if_implicit_defaults.txt))) 30 | 31 | -------------------------------------------------------------------------------- /atddiff/test/json_defaults_old/dune: -------------------------------------------------------------------------------- 1 | ; Generated by ./generate-dune-rules 2 | ; For adding tests, read the instructions in the Makefile. 3 | (rule 4 | (targets backward_incompatible_record_if_implicit_defaults.txt) 5 | (deps backward_incompatible_record_if_implicit_defaults_old.atd backward_incompatible_record_if_implicit_defaults_new.atd) 6 | (action 7 | (with-accepted-exit-codes 8 | 0 9 | (with-outputs-to %{targets} 10 | (run %{bin:atddiff} %{deps} --exit-success --json-defaults-old))))) 11 | 12 | (rule 13 | (alias runtest) 14 | (deps backward_incompatible_record_if_implicit_defaults.txt) 15 | (action (diff backward_incompatible_record_if_implicit_defaults.expected.txt backward_incompatible_record_if_implicit_defaults.txt))) 16 | 17 | (rule 18 | (targets forward_incompatible_record_if_implicit_defaults.txt) 19 | (deps forward_incompatible_record_if_implicit_defaults_old.atd forward_incompatible_record_if_implicit_defaults_new.atd) 20 | (action 21 | (with-accepted-exit-codes 22 | 0 23 | (with-outputs-to %{targets} 24 | (run %{bin:atddiff} %{deps} --exit-success --json-defaults-old))))) 25 | 26 | (rule 27 | (alias runtest) 28 | (deps forward_incompatible_record_if_implicit_defaults.txt) 29 | (action (diff forward_incompatible_record_if_implicit_defaults.expected.txt forward_incompatible_record_if_implicit_defaults.txt))) 30 | 31 | -------------------------------------------------------------------------------- /atdgen-cppo/cppo-json: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | usage () { 4 | echo "\ 5 | Usage: cppo-json [cppo arguments] 6 | 7 | cppo-json processes an OCaml file written with embedded type definitions 8 | directives and replaces them by OCaml type definitions and JSON 9 | serialization/deserialization code. 10 | 11 | Sample input: 12 | 13 | \$ cat example.ml 14 | #ext json 15 | type mytype = string list 16 | #endext 17 | let data = [ \"Hello\"; \"world\" ] 18 | let () = print_endline (J.string_of_mytype data) 19 | 20 | How to view the OCaml code produced by cppo-json: 21 | 22 | \$ cppo-json < example.ml | less 23 | 24 | How to compile an OCaml program: 25 | 26 | \$ ocamlfind opt -o example \\ 27 | -pp cppo-json \\ 28 | -package atdgen -linkpkg \\ 29 | example.ml 30 | 31 | cppo-json ships with atdgen-cppo and is shorthand for the following command: 32 | 33 | cppo -x \"json:atdgen-cppo t j v\" 34 | 35 | where 't' stands for 'type definitions', 'j' stands for 'JSON', and 36 | 'v' stands for \"validators\". 37 | 38 | See also: 39 | atdgen-cppo --help 40 | cppo --help 41 | " >&2 42 | } 43 | 44 | case "$1" in 45 | --help|-help) usage; exit 0 ;; 46 | *) 47 | esac 48 | 49 | cppo -x "json:atdgen-cppo t j v" "$@" 50 | 51 | case $? in 52 | 0) ;; 53 | *) 54 | echo "cppo-json failed" >&2 55 | exit 2 56 | esac 57 | -------------------------------------------------------------------------------- /atdts/src/lib/TS_annot.mli: -------------------------------------------------------------------------------- 1 | (** 2 | TypeScript-specific ATD annotations. 3 | 4 | This interface serves as a reference of which TypeScript-specific 5 | ATD annotations are supported. Atdts also honors JSON-related annotations 6 | defined in [Atd.Json]. 7 | *) 8 | 9 | (** Whether an association list of ATD type [(string * foo) list] 10 | must be represented in TypeScript as an array of pairs or as a map. 11 | This is independent of the JSON representation. 12 | *) 13 | type assoc_repr = 14 | | Array 15 | | Map 16 | 17 | (** Extract ["42"] from []. 18 | The provided default must be a well-formed TypeScript expression. 19 | *) 20 | val get_ts_default : Atd.Annot.t -> string option 21 | 22 | (** Inspect annotations placed on arrays of pairs such as 23 | [(string * foo) list ]. 24 | Permissible values for the [repr] field are ["map"] and ["array"]. 25 | The default is ["array"]. 26 | *) 27 | val get_ts_assoc_repr : Atd.Annot.t -> assoc_repr 28 | 29 | (** Extract ["ModuleName"] from []. 30 | This is used to identify the source module for imported types. 31 | *) 32 | val get_ts_from : Atd.Annot.t -> string option 33 | 34 | (** Extract ["TypeName"] from []. 35 | This is used to identify the original type name in the source module. 36 | *) 37 | val get_ts_type : Atd.Annot.t -> string option 38 | -------------------------------------------------------------------------------- /atdgen/example/example.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | echo "Running script $0, look inside for comments." 4 | 5 | # Exit on error 6 | set -e 7 | 8 | # Produce format_v1.mli and format_v1.ml from type definition 9 | atdgen format_v1.atd 10 | 11 | # Produce format_v2.mli and format_v2.ml from type definition 12 | atdgen format_v2.atd 13 | 14 | # Compile and link all OCaml code, producing upgrade_demo 15 | ocamlfind ocamlopt -g -dtypes -package atdgen -linkpkg \ 16 | format_v1.mli format_v1.ml \ 17 | format_v2.mli format_v2.ml \ 18 | upgrade_demo.ml -o upgrade_demo 19 | 20 | # Save biniou sample in the old format 21 | ./upgrade_demo old > old_sample.dat 22 | 23 | # Save the same data after conversion to the new format 24 | ./upgrade_demo new > new_sample.dat 25 | 26 | # Use our sample data in the old format for the next test 27 | cp old_sample.dat old_data.dat 28 | 29 | # Read data in the old format with code assuming the new format 30 | ./upgrade_demo up < old_data.dat > new_data.dat 31 | 32 | # Dump a text representation of old and new data. 33 | # The -w option specifies a list of candidate field names required for 34 | # converting hashed field names into the original names. 35 | echo "Data in format v1:" 36 | bdump old_data.dat -w a,b,c,d 37 | echo "Converted to format v2:" 38 | bdump new_data.dat -w a,c,d,e 39 | echo "Same, displayed using incomplete name dictionary:" 40 | bdump new_data.dat -w a,b 41 | -------------------------------------------------------------------------------- /atdgen/test/spec_js/spec.atd: -------------------------------------------------------------------------------- 1 | type r1 = { r1: string } 2 | type r2 = { r2: int option } 3 | type r3 = { ?r3: int option } 4 | type r4 = { ~r4: bool } 5 | type r5 = { ~r5: int option } 6 | type r6 = { ~r6 : int } 7 | type r7 = { ~r7 : int } 8 | type r8 = { ~r8 : int list } 9 | 10 | type j1 = string list 11 | type j2 = unit 12 | type j3 = int list 13 | type j4 = int 14 | 15 | type o1 = (string * int) list 16 | type o2 = (string * int) list 17 | 18 | type t1 = (int * string) 19 | type t2 = (int * int * : int) 20 | 21 | type v1 = 22 | [ V1 23 | | V2 24 | | V3 of string 25 | | V4 of int 26 | | V5 of bool option] 27 | 28 | type v1list = v1 list 29 | 30 | type v2 = 31 | { v2 : [ A | B of int ] 32 | } 33 | 34 | type v3 = [ C1 | C2 of bool] 35 | 36 | type v3list = v3 list 37 | 38 | type age = int wrap 39 | 43 | 44 | type ages = age list 45 | 46 | type open_enum = [ 47 | | Alpha 48 | | Beta 49 | | Other of string 50 | ] 51 | 52 | type open_enum_list = open_enum list 53 | -------------------------------------------------------------------------------- /atdd/README.md: -------------------------------------------------------------------------------- 1 | Atdd 2 | == 3 | 4 | Atdd takes type definitions in the ATD format and derives `dlang` 5 | classes that can read and write JSON data. This saves the developer the 6 | labor writing boilerplate that converts between dicts and classes. 7 | 8 | This allows safe interoperability with other languages supported by 9 | ATD such as OCaml, Java, Python or Scala. 10 | 11 | See the sample input type definitions 12 | [everything.atd](test/atd-input/everything.atd) and 13 | the D output [everything.d](test/dlang-expected/everything.d). 14 | 15 | Requirements 16 | -- 17 | 18 | Requirements for building and testing `atdd`: 19 | * Opam and dependencies installed from the [`atd` project root](..) 20 | with `make setup`. 21 | * ldc >= 1.27.0 22 | 23 | Requirements for generating D code: 24 | * the `atdd` executable 25 | 26 | Requirements for compiling the generated D code: 27 | * ldc >= 1.27.0 28 | 29 | Documentation 30 | -- 31 | 32 | * TODO 33 | 34 | Development notes 35 | -- 36 | 37 | Build or rebuild with `make`. Test with `make test`. This requires 38 | ldc2. 39 | 40 | Running the tests is done from the `atdd/` main folder with `make 41 | test`. 42 | 43 | We have two kinds of tests for atdd: 44 | * code generation and D tests: 45 | * they generate D code from ATD files and compare the D output 46 | against the [expectations](dlang-expected). 47 | * the generated code is executed by some tests. 48 | -------------------------------------------------------------------------------- /atdd/src/lib/Dlang_annot.mli: -------------------------------------------------------------------------------- 1 | (** 2 | Dlang-specific ATD annotations. 3 | 4 | This interface serves as a reference of which Dlang-specific 5 | ATD annotations are supported. Atdd also honors JSON-related annotations 6 | defined in [Atd.Json]. 7 | *) 8 | 9 | (** Extract ["42"] from []. 10 | The provided default must be a well-formed Dlang immutable expression. 11 | *) 12 | val get_dlang_default : Atd.Annot.t -> string option 13 | 14 | (** Whether an association list of ATD type [(string * foo) list] 15 | must be represented in Dlang as a list of pairs or as a dictionary. 16 | This is independent of the JSON representation. 17 | *) 18 | type assoc_repr = 19 | | List 20 | | Dict 21 | 22 | (** Inspect annotations placed on lists of pairs such as 23 | [(string * foo) list ]. 24 | Permissible values for the [repr] field are ["dict"] and ["list"]. 25 | The default is ["list"]. 26 | *) 27 | val get_dlang_assoc_repr : Atd.Annot.t -> assoc_repr 28 | 29 | (** Returns text the user wants to be inserted at the beginning of the 30 | Dlang file such as imports. *) 31 | val get_dlang_import : Atd.Annot.t -> string list 32 | 33 | 34 | 35 | type atd_dlang_wrap = { 36 | dlang_wrap_t : string; 37 | dlang_wrap : string; 38 | dlang_unwrap : string; 39 | } 40 | 41 | val get_dlang_wrap : Atd.Ast.loc -> 42 | Atd.Annot.t -> atd_dlang_wrap option 43 | -------------------------------------------------------------------------------- /atdgen/test/melange/dune: -------------------------------------------------------------------------------- 1 | (rule 2 | (targets melangespec_mel.ml melangespec_mel.mli) 3 | (deps melangespec.atd) 4 | (action (run atdgen %{deps} -mel))) 5 | 6 | (rule 7 | (targets melangespec_t.ml melangespec_t.mli) 8 | (deps melangespec.atd) 9 | (action (run atdgen %{deps} -t))) 10 | 11 | (rule 12 | (targets melangespec_j.ml melangespec_j.mli) 13 | (deps melangespec.atd) 14 | (action (run atdgen %{deps} -j -j-std))) 15 | 16 | (library 17 | (name melangespec_types) 18 | (wrapped false) 19 | (libraries atdgen-codec-runtime) 20 | (modules melangespec_t a_t a_mel)) 21 | 22 | (library 23 | (name melangespec_mel) 24 | (wrapped false) 25 | (libraries atdgen-codec-runtime melangespec_types) 26 | (modules melangespec_mel)) 27 | 28 | (executable 29 | (name melangespec_roundtrip) 30 | (modules melangespec_roundtrip melangespec_j a_j) 31 | (libraries melangespec_types melangespec_mel atdgen-runtime atdgen-codec-runtime biniou yojson)) 32 | 33 | (rule 34 | (alias runtest) 35 | (package atdgen) 36 | (action (diff melangespec_mel.expected.ml melangespec_mel.ml))) 37 | 38 | (rule 39 | (alias runtest) 40 | (package atdgen) 41 | (action (diff melangespec_mel.expected.mli melangespec_mel.mli))) 42 | 43 | (rule 44 | (alias runtest) 45 | (package atdgen) 46 | (action (diff melangespec_j.expected.ml melangespec_j.ml))) 47 | 48 | (rule 49 | (alias runtest) 50 | (package atdgen) 51 | (action (run ./melangespec_roundtrip.exe))) 52 | -------------------------------------------------------------------------------- /atdgen/src/indent.ml: -------------------------------------------------------------------------------- 1 | 2 | (* 3 | Atd.Indent extended with annnotations allowing some postprocessing. 4 | *) 5 | 6 | type t = 7 | | Line of string 8 | | Block of t list 9 | | Inline of t list 10 | | Annot of string * t 11 | 12 | let rec strip = function 13 | | Line _ as x -> x 14 | | Block l -> Block (List.map strip l) 15 | | Inline l -> Inline (List.map strip l) 16 | | Annot (_, x) -> strip x 17 | 18 | let paren l = 19 | Inline 20 | [ Line "(" 21 | ; l 22 | ; Line ")" 23 | ] 24 | 25 | let rec concat t = function 26 | | [] -> [] 27 | | [x] -> [x] 28 | | x::xs -> x::t::(concat t xs) 29 | 30 | let to_buffer ?(offset = 0) ?(indent = 2) buf l = 31 | let rec print n = function 32 | | Annot (_, _) -> assert false 33 | | Block l -> List.iter (print (n + indent)) l 34 | | Inline l -> List.iter (print n) l 35 | | Line s -> 36 | for _ = 1 to n do 37 | Buffer.add_char buf ' ' 38 | done; 39 | Buffer.add_string buf s; 40 | Buffer.add_char buf '\n'; 41 | in 42 | List.iter (print offset) l 43 | 44 | let to_string ?offset ?indent l = 45 | let buf = Buffer.create 1000 in 46 | to_buffer ?offset ?indent buf l; 47 | Buffer.contents buf 48 | 49 | let to_channel ?offset ?indent oc l = 50 | let buf = Buffer.create 1000 in 51 | to_buffer ?offset ?indent buf l; 52 | Buffer.output_buffer oc buf 53 | 54 | let to_stdout ?offset ?indent l = 55 | to_channel ?offset ?indent stdout l 56 | -------------------------------------------------------------------------------- /atd/src/predef.ml: -------------------------------------------------------------------------------- 1 | (* 2 | Table of predefined types. 3 | *) 4 | 5 | open Ast 6 | 7 | let list_def : type_def = 8 | let loc = dummy_loc in 9 | ( 10 | loc, 11 | ("list", ["a"], []), 12 | List (loc, Tvar (loc, "a"), []) 13 | ) 14 | 15 | let option_def : type_def = 16 | let loc = dummy_loc in 17 | ( 18 | loc, 19 | ("option", ["a"], []), 20 | Option (loc, Tvar (loc, "a"), []) 21 | ) 22 | 23 | let nullable_def : type_def = 24 | let loc = dummy_loc in 25 | ( 26 | loc, 27 | ("nullable", ["a"], []), 28 | Nullable (loc, Tvar (loc, "a"), []) 29 | ) 30 | 31 | let shared_def : type_def = 32 | let loc = dummy_loc in 33 | ( 34 | loc, 35 | ("shared", ["a"], []), 36 | Shared (loc, Tvar (loc, "a"), []) 37 | ) 38 | 39 | let wrap_def : type_def = 40 | let loc = dummy_loc in 41 | ( 42 | loc, 43 | ("wrap", ["a"], []), 44 | Wrap (loc, Tvar (loc, "a"), []) 45 | ) 46 | 47 | 48 | let list = [ 49 | "unit", 0, None; 50 | "bool", 0, None; 51 | "int", 0, None; 52 | "float", 0, None; 53 | "string", 0, None; 54 | "abstract", 0, None; 55 | "list", 1, Some list_def; 56 | "option", 1, Some option_def; 57 | "nullable", 1, Some nullable_def; 58 | "shared", 1, Some shared_def; 59 | "wrap", 1, Some wrap_def; 60 | ] 61 | 62 | let make_table () = 63 | let tbl = Hashtbl.create 20 in 64 | List.iter ( 65 | fun (k, n, opt_t) -> 66 | Hashtbl.add tbl k (n, opt_t) 67 | ) list; 68 | tbl 69 | --------------------------------------------------------------------------------