Releases: ahrefs/atd
4.2.0
CHANGES:
-
atdj: Top-level list aliases such as
type items = item listare now
supported. A wrapper class (e.g.Items) implementingAtdjis generated
with the same interface as record classes: a no-arg constructor, a
constructor fromArrayList<T>, a constructor from a JSON string, a
package-private constructor fromJSONArray,toJsonBuffer,toJson,
and a publicvaluefield of typeArrayList<T>. List aliases used as
record fields or sum-variant payloads are also handled correctly. -
atdml: Generate
jsonlike_of_fooserializer functions andFoo.to_jsonlike
submodule bindings, completing the OCaml ↔Atd_jsonlike.AST.tround-trip.
JSON adapters are also supported: if the adapter moduleMprovides
restore_jsonlike, it is called after serialization byjsonlike_of_foo. -
atd-jsonlike: Add
Pos.zeroandLoc.zero— zero-position / zero-location
constants useful for constructingAST.tnodes programmatically when source
location information is not available. -
atd-yamlx: Add
to_yamlx_value : Atd_jsonlike.AST.t -> YAMLx.value, the
reverse ofof_yamlx_value. Enables programmatic construction of YAML
documents from ATD-typed OCaml values viajsonlike_of_foo.
4.1.0
CHANGES:
-
Build: OCaml >= 4.14 is now required (previously 4.08). This aligns
all packages with theyamlxdependency ofatd-yamlx. -
Testing: Add a standard JSON round-trip test suite (
standard-tests/)
that any code generator can opt into. The harness generates code from an
ATD spec, compiles it, feeds JSON to stdin, and checks the output.
atdml is the first backend to run these tests. -
New package:
atd-yamlx. Translates a parsed YAML value
(YAMLx.valuefrom theyamlxlibrary) intoAtd_jsonlike.AST.t,
preserving source locations at every node so that ATD-generated reader
functions (foo_of_jsonlike) can report precise file/line/column error
messages when deserializing YAML configuration files.of_yamlx_valuereturns(AST.t, string) result; the raising variant
isof_yamlx_value_exn.atd-yamlx/examples/is a self-contained dune subproject demonstrating
a typed YAML config reader built withatdmlandatd-yamlx.
-
All backends: Add
<json repr="object">on sum types. Tagged variants are
encoded as single-key JSON objects{"Constructor": payload}instead of the
default["Constructor", payload]arrays. Unit variants are unaffected
("Constructor"strings). This matches Serde's externally-tagged
representation and produces idiomatic YAML (a single-key mapping rather than
a two-element sequence). Supported in: atdml (OCaml), atdpy (Python),
atdts (TypeScript), atdcpp (C++), atdd (D), atdj (Java), atds (Scala).
atdml additionally generatesof_jsonlikereaders automatically. -
New package:
atd-jsonlike. Defines a generic JSON-like AST
(Atd_jsonlike.AST.t) with source location information at every node.
Intended as a target type for code generated by ATD tools, so that
reader functions can report precise file/line/column error messages.
Supports JSON numbers viaAtd_jsonlike.Number.t, which stores all
available representations (int,float, andliteralstring) for
maximum flexibility. -
atdml: Generate
foo_of_jsonlikereader functions that accept an
Atd_jsonlike.AST.tvalue and return a typed OCaml value, with error
messages that include the original source location.- Default output is Yojson-based readers/writers only (no
atd-jsonlike
dependency unless explicitly requested). - New
--mode MODEoption (repeatable) selects what to generate.
MODEis a mode name or comma-separated list of mode names.
Valid modes:yojson,jsonlike,all(= yojson + jsonlike).
Example:atdml --mode yojson,jsonlike foo.atd - JSON adapters (
<json adapter.ocaml="M">) are supported for the jsonlike
path: if the adapter moduleMprovidesnormalize_jsonlike, it is called
before deserialization byfoo_of_jsonlike. Inline adapters
(adapter.to_ocaml/adapter.from_ocaml) do not support jsonlike.
- Default output is Yojson-based readers/writers only (no
4.0.0
CHANGES:
-
Build: Dune >= 3.18 (April 2025) is now required to build the ATD tools
from source. (#445) -
atdcat: read from stdin when no input file is given, like
cat. -
ATD: Experimental. Module support via new
from ... import ...syntax.
Types to be used must be listed explicitly; the full syntax is:from module.path <annots> [as alias] import type1 <annots>, type2, ...Key properties:
- Imported types must be listed explicitly
(e.g.from mylib import date, status). - Supported languages: OCaml (atdml, not atdgen), Python (atdpy),
TypeScript (atdts) - Parameterized types declare their arity:
from mylib import 'a list_ne. - The arity of each imported type is enforced at all use-sites within the
importing file. - Aliases are plain names without annotations:
from foo as f import t. - Language-specific name annotations go on the module path:
<python name="...">for atdpy,<ts name="...">for atdts,
<ocaml name="...">for atdml. - atdpy: alias names that are Python keywords are automatically suffixed
with_(e.g. aliasclass→class_in generated code). - atdts: Dotted module paths in
importdeclarations are now mapped to
path-separator form in the generated TypeScript import path.
For example,import long.module.pathgenerates
import * as path from "./long/module/path"rather than"./path". - A warning is printed to stderr when an imported type name is never
referenced in any type expression.
Examples:
(* Import specific types from a module *) from mylib.common import date, status (* Import with alias *) from long.module.path as ext import tag (* Override OCaml module name *) from mylib.common <ocaml name="Mylib_common"> import date - Imported types must be listed explicitly
-
atdml: Experimental. New tool. Generates a single self-contained OCaml module (
.ml+
.mli) from a single.atdfile, with JSON support viaYojson.Safe.t.
No separate runtime library is required; the runtime helpers are inlined
into each generated.ml. Atdml is the recommended successor to atdgen
for OCaml JSON support.
Supported features:- All primitive ATD types:
unit,bool,int,float,string abstracttype, represented asYojson.Safe.t'a list,'a option,'a nullable- Tuples:
('a * 'b * ...) - Records, including required fields, optional fields (
?foo),
and with-default fields (~foo) with implicit or explicit defaults
(<ocaml default="...">) <ocaml field_prefix="pre_">on record types: prepends the given prefix
to all OCaml record field names while keeping the labeled arguments of
create_unprefixed (e.g.create_point ~x ~y () : point). JSON field
names are unaffected.- Classic sum types (regular OCaml variants) and polymorphic variants
(<ocaml repr="poly">) - Parametric types
- Mutually recursive types (detected automatically via topological sort;
andis used only when strictly necessary) wrapconstruct with<ocaml module="M">or explicit
<ocaml t="..." wrap="..." unwrap="...">- JSON adapters via
<json adapter.ocaml="M">(module providingnormalize
andrestore) or<json adapter.to_ocaml="..." adapter.from_ocaml="...">
(inline expressions); supported on sum types and records <json name="...">to override JSON field or constructor names<ocaml name="...">to rename variant constructors in OCaml<ocaml attr="...">to attach ppx attributes (e.g.[@@deriving show])
to generated type definitions<ocaml private>on any type definition forcesprivatein the generated
.mli;<ocaml public>on a primitive alias suppresses the default
private, making the alias transparent to callers- Unparameterized aliases of primitive types (
unit,bool,int,
float,string) are generated asprivatein the.mli, preventing
direct construction outside the module. A constructor function
create_email : string -> emailis generated (also exposed as
val createin submoduleEmail). Coerce back with:>
(e.g.(x :> string)). <doc text="...">documentation annotations, translated into ocamldoc
(** ... *)comments in the generated code; supported on type definitions,
record fields, variant constructors, and module-level head annotations- Automatic renaming of ATD type names that conflict with OCaml keywords
or with thefoo_of_yojson/yojson_of_foonaming scheme - Automatic renaming of record fields and variant constructors that conflict
with OCaml keywords (e.g.end→end_) (string * 'a) list <json repr="object">: encode association lists as
JSON objects{"key": value, ...}rather than arrays- Graceful handling of atdgen annotations not supported by atdml:
<ocaml module="...">on type definitions and<ocaml name="...">on
record fields emit a warning and are otherwise ignored ~field: user_typewith no OCaml default: warns and treats the field as
required in JSON (nocreate_function generated for that type)- Record creation functions are named
create_foo(notmake_foo),
matching atdgen's convention - Stdin mode: reads ATD from stdin, writes a copy-pasteable
module type Types = sig ... end / module Types : Types = struct ... end
snippet to stdout - Each generated type gets a submodule (
module Foo) bundling the type
and its conversion functions
- All primitive ATD types:
3.0.1
3.0.0
CHANGES:
- atdgen: Add option
-j-gen-modulesto generate JSON generic submodules (#420) - atd-parser: improve (syntax) error messages (#426)
- atdts: Add support for
<ts from...>annotations - atdpy: Add support for
<doc text=...>annotations, turning them
into docstrings similar to the ocamldoc comments produced by atdgen. - atdgen: Remove option
-j-std, now it's the default, one cannot
generate extended-JSON (#425). Options-j-stdand-std-jsonare
still available as backward-compatibility no-ops unless
environment variableATDGEN_FAIL_DEPRECATED_OPTIONSis set totruein
which case their use results in an exception.
2.16.0
CHANGES:
- atdgen: Breaking change, migrate from Bucklescript to Melange (#375)
- atdd: Workaround d compiler bug regarding declaration order when using aliases (#393)
Algebraic data types (SumType) now usesalias thissyntax. - atdgen: Add support for
<json open_enum>in Melange (#401) - atdcpp: Initial Release (#404)
- atdcpp: Use
doublec++ type as default floating point type (#411) - atdgen: Fix JSON I/O for inline records (#419)
- atdgen: The deprecated
atdgenlibrary is no longer available.
Useatdgen-runtimeinstead (#421) - atddiff: To ensure that all the intended types are checked when new
type definitions are added to an ATD file, an--ignore
option is now available. It makes atddiff fail if some types
are neither selected via--typesnor ignored via--ignore.
2.15.0
CHANGES:
2.14.1
2.14.0
CHANGES:
- atdd: Fix various issues with the interoperability of user defined types,
used in or outside of records (#355) - atdd: Generated
.dfiles now have the suffix_atd.d(#355) - atddiff now supports options for filtering the findings based on the
direction of the incompatibility (--backward,--forward) or based on the
name of the affected types (--types) (#365) - atddiff: new option
--output-format jsonfor exporting the results to
JSON (#360)
2.13.0
CHANGES:
- atdts: Stop compiler errors on generated typescript (#348)
- atdts: Don't fail on
wrapconstructs (#353) - atdcat: New option
-remove-wrapswhich pretty-prints the type
definitions withoutwrapconstructs (#353) - atdd: Add
dlangbackend to generate D code from ATD definitions (#349) - new tool: atddiff. Compares two versions of an ATD file and reports
possible incompatibilities in the JSON data. Atddiff ships as part of the
atdpackage together withatdcat(#352, #358)