All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vertx.codegen.package-info Maven / Gradle / Ivy

There is a newer version: 3.6.3
Show newest version
/**
 * = Vert.x Codegen
 *
 * Vert.x Codegen is an annotation processing tool for processing Vert.x API and create API in different JVM lauguages.
 *
 * Vert.x polyglot langs use code generation for creating https://en.wikipedia.org/wiki/Shim_(computing)[shim] for APIs,
 * that are thin wrappers in front of the API type.
 *
 * A shim is the adaptation of a Vert.x API to a JVM language. A shim uses code generation to generate
 * wrappers in its own language delegating to the Vert.x API, code generation is based on Java annotation
 * processing.
 *
 * == Vert.x API
 *
 * A Vert.x API is a collection of Java types annotated with Codegen annotations that respect a set of constraints to
 * ensure easy portability of the API to most languages and enable an asynchronous programming model. Such collection
 * of API types are grouped in modules.
 *
 * === Modules
 *
 * A module contains a collection of Vert.x API and data objects declarations, some shim uses modules for organizing
 * and loading the Vert.x api:
 *
 * - the JavaScript shim uses https://en.wikipedia.org/wiki/CommonJS[CommonJS] modules
 * - the Ruby shim uses Ruby modules
 * - Ceylon uses Ceylon native modules
 *
 * NOTE: so far in Java or Groovy the notion of module is not used because it delegates loading to classloaders.
 *
 * Modules are declared by annotating a Java package with a {@link io.vertx.codegen.annotations.ModuleGen @ModuleGen}
 * annotation.
 *
 * [source,java]
 * ----
 * @ModuleGen(name = "acme", groupPackage="com.acme")
 * package com.acme.myservice;
 *
 * import io.vertx.codegen.annotations.ModuleGen;
 * ----
 *
 * The module _name_ is a namespace for shims that don't support package like naming, like JavaScript `acme-js`
 * or Ruby `acme`, whereas the _group package_ determines the created package, for instance
 * `com.acme.groovy.myservice` in Groovy. The group package must be a prefix of the annotated module.
 *
 * Vert.x modules use the reserved name _vertx-XYZ_ and the reserved group package _io.vertx_.
 *
 * An API module contains various Vert.x types annotated with {@link io.vertx.codegen.annotations.VertxGen}
 * or {@link io.vertx.codegen.annotations.DataObject}.
 *
 * NOTE: using Maven coordinates for name and group package is encouraged: the name corresponding to the
 * Maven _artifactId_ and the group package corresponding to the `groupId`.
 *
 * === Data objects
 *
 * A Data object_ is a Java class with the only purpose to be a container for data. They are transformed
 * to and from Json.
 *
 * In its simplest form, a data object is a Java class following these rules:
 *
 * 1. the class is annotated with {@link io.vertx.codegen.annotations.DataObject}
 * 2. provide a zero argument constructor
 * 3. provide a constructor with the `io.vertx.core.json.JsonObject` argument
 * 4. provide a copy constructor with the exact same type
 *
 * A data object can also be an interface annotated with `@DataObject`, this is useful when multiple inheritance
 * is needed. For instance Vert.x Core defines the `KeyCertOptions` and `TrustOptions` data object interfaces and the
 * `JksOptions` is a data object class that implements both of them because a Java keystore provides support for both.
 *
 * Data object can also inherit from other data objects. It inherits from the properties of the parent classes.
 *
 * ==== Data object properties
 *
 * DataObject properties are declared via _getters_, _setters_ or _adders_:
 *
 * .a getter and a setter
 * [source,java]
 * ----
 * public String getHost() {
 *   return host;
 * }
 *
 * public WebServerOptions setHost(String host) {
 *   this.host = host;
 *   return this;
 * }
 * ----
 *
 * Here is the list of supported property single valued types:
 *
 * 1. any primitive or boxed primitive type
 * 2. `java.lang.String`
 * 3. `io.vertx.core.json.JsonObject` and `io.vertx.core.json.JsonArray`
 * 4. the specific `io.vertx.core.buffer.Buffer` type providing support for byte array
 * 5. Java enums
 * 6. another data object
 *
 * In addition a data object can also have multi-valued properties as a `java.util.List`/`java.util.Set` or a
 * `java.util.Map` where the `` is a supported single valued type or `java.lang.Object`
 * that stands for anything converted by `io.vertx.core.json.JsonObject` and `io.vertx.core.json.JsonArray`.
 *
 * List/set multi-valued properties can be declared via a _setter_ :
 *
 * .a multi valued setter
 * [source,java]
 * ----
 * public WebServerOptions setCertificates(List certificates) {
 *   this.certificates = certificates;
 *   return this;
 * }
 * ----
 *
 * Or an _adder_ :
 *
 * .a multi valued adder
 * [source,java]
 * ----
 * public WebServerOptions addCertificate(String certificate) {
 *   this.certificates.add(certificate);
 *   return this;
 * }
 * ----
 *
 * Map properties can only be declared with a _setter_.
 *
 * NOTE: these examples uses a _fluent_ return types for providing a better API, this is not mandatory but
 * encouraged.
 *
 * ==== Json conversion
 *
 * Vert.x requires data object to be convertible from json with the json argument constructor. Altough there
 * is no strict rules of mapping between the data object properties and the json structure, it is a good thing
 * to follow a common mapping for users using json data objects (like in JavaScript shim).
 *
 * Json properties should be named after properties according to JavaBean conversion rules:
 *
 * - a single valued property follows the JavaBean convention
 * - a multi valued property declared with a list setter follows the same convention
 * - a multi valued property declared with an adder must use a singular form and the json property name gets a trailing _s_
 *
 * In all case, property names are _normalized_, i.e:
 *
 * - _red_ -> _red_
 * - _Red_ -> _red_
 * - _URL_ -> _url_
 * - _URLFactory_ -> _urlFactory_
 *
 * ==== Jsonifiable data object
 *
 * When a data object declares a `public JsonObject toJson()` method it can be converted to the json format
 * and is said _jsonifiable_. Vert.x API types have restriction in the declared method return types, a jsonifiable
 * data object can be used in Vert.x API method return types or handlers because it can be converted to a json
 * format, otherwise it is not permitted.
 *
 * ==== Data object converter
 *
 * Vert.x requires only the conversion from json, but the conversion to json can be useful when the API uses
 * data objects as return types. The implementation of the data object / json conversion can be tedious and
 * error prone.
 *
 * The data object / json conversion can be automated based on the rules given above. Vert.x Core allows to
 * generate auxilliary classes that implement the conversion logic. The generated converters handle the
 * type mapping as well as the json naming convention.
 *
 * Converters are generated when the data object is annotated with `@DataObject(generateConverter=true)`. The
 * generation happens for the data object properties, not for the ancestor properties, unless `inheritConverter`
 * is set: `@DataObject(generateConverter=true,inheritConverter=true)`.
 *
 * The converter is named by appending the `Converter` suffix to the data object class name, e.g,
 * `ContactDetails` -> `ContactDetailsConverter`. The generated converter has two static methods:
 *
 * - `public static void fromJson(JsonObject json, ContactDetails obj)`
 * - `public static void toJson(ContactDetails obj, JsonObject json)`
 *
 * The former should be used in the json constructor, the later in the `toJson` method.
 *
 * [source,java]
 * ----
 * public ContactDetails(JsonObject json) {
 *   this();
 *   ContactDetailsConverter.fromJson(json, this);
 * }
 *
 * public JsonObject toJson() {
 *   JsonObject json = new JsonObject();
 *   ContactDetailsConverter.toJson(this, json);
 *   return json;
 * }
 * ----
 *
 * === Building types
 *
 * A few types used throughout Vert.x API are not annotated with `@VertxGen` yet are used for building
 * the API:
 *
 * - `io.vertx.core.Handler`
 * - `io.vertx.core.AsyncResult`
 * - `io.vertx.core.json.JsonObject`
 * - `io.vertx.core.json.JsonArray`
 * - `java.lang.Object`
 * - `java.lang.Throwable`
 * - `java.lang.Void`
 * - `java.lang.String`
 * - `java.util.List`
 * - `java.util.Set`
 * - `java.util.Map`
 * - primitive and boxed primitives
 *
 * These types are usually handled natively by shims, for instance the `Handler` type is a function in JavaScript,
 * a block in Ruby, the same `Handler` in Groovy, a function in Ceylon, etc...
 *
 * === Generated types
 *
 * An API type is a Java interface annotated with {@link io.vertx.codegen.annotations.VertxGen}.
 *
 * Vert.x provides a async / non blocking / polyglot programming model, code generated API shall follow some
 * rules to make this possible:
 *
 * 1. the API must be described as a set of Java interfaces, classes are not permitted
 * 2. nested interfaces are not permitted
 * 3. all interfaces to have generation performed on them must be annotated with the `io.vertx.codegen.annotations.VertxGen` annotation
 * 4. fluent methods (methods which return a reference to `this`) must be annotated with the `io.vertx.codegen.annotations.Fluent` annotation
 * 5. methods where the return value must be cached in the API shim must be annotated with the `io.vertx.codegen.annotations.CacheReturn` annotation
 * 6. only certain types are allowed as parameter or return value types for any API methods
 * 7. custom enums should be annotated with `@VertxGen`, although this is not mandatory to allow the usage of existing Java enums
 * 8. nested enums are not permitted
 * 9. default implementations are allowed
 *
 * An API type can be generic or declare generic methods, type parameters must be unbounded, e.g
 * `` is forbidden.
 *
 * In the perspective of codegen, Java types can be categorized as follow:
 *
 * . _basic_ type : any primitive/boxed type or `java.lang.String`
 * . _json_ type : `io.vertx.core.json.JsonObject` or `io.vertx.core.json.JsonArray`
 * . _api_ type : any type annotated with `io.vertx.codegen.annotations.VertxGen`
 * . _data object_ type : any type annotated with `io.vertx.codegen.annotations.DataObject`
 * . _enum_ type : any Java enum
 * . _collection_ type : `java.util.List`, `java.util.Set` or `java.util.Map`
 *
 * Parameterized types are supported but wildcards are not, that is the following type arguments declarations
 * are *forbidden*:
 *
 * - `Foo`
 * - `Foo`
 * - `Foo`
 *
 * Parameterized types are only supported for _api_ generic types and _collection_ types.
 *
 * Type variables are allowed and carry a special meaning: a type variable is a dynamic form of a _basic_ type and
 * _json_ type.
 *
 * ==== Inheritance
 *
 * _api_ type can extend other _api_ types.
 *
 * An _api_ type can either be *concrete* or *abstract*, such information is important for languages not
 * supporting multiple class inheritance like Groovy:
 *
 * - _api_ types annotated with {@link io.vertx.codegen.annotations.VertxGen}`(concrete = false)` are meant to be
 * extended by *concrete* interfaces an can inherit from *abstract* interfaces only.
 * - _api_ types annotated with {@link io.vertx.codegen.annotations.VertxGen} or {@link io.vertx.codegen.annotations.VertxGen}`(concrete = true)`
 * are implemented directly by Vertx and can inherit at most one other *concrete* interface and any *abstract* interface
 *
 * ==== Method parameter types
 *
 * The following method parameter types are allowed:
 *
 * . any _basic_ type
 * . any _api_ type or parameterized _api_ type having type variable parameters
 * . any _json_ type
 * . the `java.lang.Throwable` type
 * . any _enum_ type
 * . any _data object_ type
 * . an https://docs.oracle.com/javase/tutorial/java/generics/bounded.html[unbounded type variable], i.e `T extends Number` or `T super Number` are not permitted
 * . `java.lang.Object`
 * . a `java.util.List`, `java.util.Set` or `java.util.Map` where `` can be a _basic_ type,
 * a _json_ type, an _API_ type. For list and set `V` can also be an _enum_ type or a _data object_ type
 *
 * In addition callback parameters are allowed, i.e types declaring `io.vertx.core.Handler` or
 * `io.vertx.core.Handler>` where `` can be:
 *
 * . the `java.lang.Void` type
 * . any _basic_ type
 * . any _API_ type
 * . any _json_ type
 * . the `java.lang.Throwable` type - only for `Handler`
 * . any _enum_ type
 * . any _data object_ type
 * . an https://docs.oracle.com/javase/tutorial/java/generics/bounded.html[unbounded type variable], i.e `T extends Number` or `T super Number` are not permitted
 * . a `java.util.List`, `java.util.Set` or `java.util.Map` where `` can be a _basic_ type,
 * a _json_ type. For list and set `V` can also be an _API_ type, an _enum_ type or a _data object_ type
 *
 * ==== Method return type
 *
 * The following return types are allowed:
 *
 * . `void` type
 * . any _basic_ type
 * . any _api_ type or parameterized _api_ type having type variable parameters
 * . any _json_ type
 * . the `java.lang.Throwable` type
 * . any _enum_ type
 * . any _data object_ type
 * . an https://docs.oracle.com/javase/tutorial/java/generics/bounded.html[unbounded type variable], i.e `T extends Number` or `T super Number` are not permitted
 * . a `java.util.List`, `java.util.Set` or `java.util.Map` where `` can be a _basic_ type,
 * a _json_ type. For list and set `V` can also be an _API_ type, an _enum_ type or a _data object_ type
 * . an `Handler` where T is is a among the method parameter types
 * . an `Handler>` where T is is a among the method parameter types
 *
 * ==== Method overloading
 *
 * Some languages don't support method overloading at all. Ruby, JavaScript or  Ceylon to name a few of them.
 * However the same restriction for Vert.x API would limit API usability.
 *
 * To accomodate both, overloading is supported when there are no ambiguities between overloaded signatures.
 * When an API is analyzed an _overload check_ is performed to ensure there is no ambiguity.
 *
 * Here is an example of possible ambiguity:
 *
 * .an overload check failure
 * [source,java]
 * ----
 * void add(int x, int y);
 * void add(double x, double y);
 * ----
 *
 * The JavaScript language use the type number in both cases: at runtime there is no possibility for the
 * JavaScript shim to know which method to use.
 *
 * ==== Nullable types
 *
 * Null values have an impact on shim design:
 *
 * - shims based on value types for dispatching overloaded methods fail for null values, for example a `foo(String)`
 * method overloaded by a `foo(Buffer)` method invoked with `foo(null)` cannot delegate to the correct underlying method in
 * JavaScript.
 * - some shims can leverage this information to provide a better API, for instance an `Optional` Java type or the
 * `String?` in Ceylon, etc...
 *
 * Codegen provides the {@link io.vertx.codegen.annotations.Nullable} annotations for annotating types.
 *
 * Method return type can be {@link io.vertx.codegen.annotations.Nullable}:
 *
 * [source,java]
 * ----
 * @Nullable String getAttribute(String name);
 * ----
 *
 * As well as method parameter type:
 *
 * [source,java]
 * ----
 * void close(@Nullable Handler closeHandler);
 * ----
 *
 * WARNING: type validation is a non goal of this feature, its purpose is to give hints to the shim
 * for generating correct code.
 *
 * These rules apply to {@link io.vertx.codegen.annotations.Nullable} types:
 *
 * . primitive types cannot be {@link io.vertx.codegen.annotations.Nullable}
 * . method parameter type can be {@link io.vertx.codegen.annotations.Nullable}
 * . method return type can be {@link io.vertx.codegen.annotations.Nullable} but not for {@link io.vertx.codegen.annotations.Fluent}
 * . `io.vertx.core.Handler` type argument can be {@link io.vertx.codegen.annotations.Nullable} but not for
 * `java.lang.Void` or `io.vertx.core.AsyncResult`
 * . `io.vertx.core.Handler` type argument can be {@link io.vertx.codegen.annotations.Nullable}
 * but not for `java.lang.Void`
 * . the `java.lang.Object` type is always nullable
 * . the `` in `` parameter/return, `Handler` or `Handler>` is implicitly nullable
 * . the `java.lang.Object` parameter is implicitly nullable
 * . a method overriding another method `inherits` the {@link io.vertx.codegen.annotations.Nullable} usage of the overriden method
 * . a method overriding another method cannot declare {@link io.vertx.codegen.annotations.Nullable} in its types
 *
 * In addition these rules apply to {@link io.vertx.codegen.annotations.Nullable} type arguments:
 *
 * . methods cannot declare generic api types with nullable type arguments, e.g ` void method(GenericApi api)` is not permitted
 * . methods can declare nullable collection, e.g `void method(List list)` is allowed
 *
 * Besides these rules, nullable types of method parameters have an impact on method overloading: the parameter
 * at the same position cannot be {@link io.vertx.codegen.annotations.Nullable} more than one time when the number
 * of method parameters is the same, e.g:
 *
 * [source,java]
 * ----
 * void write(@Nullable String s);
 * void write(@Nullable Buffer s);
 * ----
 *
 * is not permitted, however:
 *
 * [source,java]
 * ----
 * void write(@Nullable String s);
 * void write(@Nullable String s, String encoding);
 * ----
 *
 * is permitted because the number of parameters differs.
 *
 * === Static methods
 *
 * Vert.x generated types allow _static_ methods, such methods often plays the role of factory. For instance
 * `Buffer` instance are obtained by the static method `Buffer.buffer()`, this method is translated to an equivalent
 * in the shim.
 *
 * In Javascript:
 *
 * [source,javascript]
 * ----
 * var Buffer = require('vertx-js/buffer');
 * var buf = Buffer.buffer();
 * ----
 *
 * In Ruby:
 *
 * [source,ruby]
 * ----
 * require 'vertx/buffer'
 * buf = Vertx::Buffer.buffer()
 * ----
 *
 * In Groovy:
 *
 * [source,groovy]
 * ----
 * def buf = io.vertx.groovy.core.Buffer.buffer();
 * ----
 *
 * === Ignored methods
 *
 * Methods annotated with {@link io.vertx.codegen.annotations.GenIgnore} are simply ignored by codegen, this
 * is useful when the API provides Java specific methods, for instance a method uses a type not permitted
 * by codegen.
 *
 * == Shim proxies
 *
 * A code generated API creates shim proxies delegating method invocation to the API.
 *
 * .a simplified Buffer API
 * [source,java]
 * ----
 * @VertxGen
 * public interface Buffer {
 *
 *   static Buffer buffer(String s) {
 *     return new BufferImpl(s);
 *   }
 *
 *   int length();
 * }
 * ----
 *
 * A JavaScript generated shim could look like:
 *
 * .the JavaScript shim
 * [source,javascript]
 * ----
 * var JBuffer = io.vertx.core.buffer.Buffer;
 * var Buffer = function(j_val) {
 *
 *   // delegate object
 *   var j_buffer = j_val;
 *   var that = this;
 *
 *   this.length = function() {
 *     return j_buffer.length();
 *   };
 * }
 *
 * Buffer.buffer = function(s) {
 *   return new Buffer(JBuffer.buffer(s));
 * }
 *
 * module.exports = Buffer;
 * ----
 *
 * The static `buffer` method is translated into the `buffer` method of the `Buffer` module, this method
 * delegates the call to the Java static method and returns a `Buffer` proxy wrapping the returned buffer.
 *
 * The instance `length` method is translated into the `length` method of the proxy instance, this method
 * delegates the call to the Java instance method of the proxied buffer and simply returns the value. The
 * Nashorn interoperability takes care of converting the `int` type to a JavaScript `Number`.
 *
 * === Return values
 *
 * A shim implements several strategies when returning values from the Vert.x API:
 *
 * 1. a _basic_ value is usually handled by the shim interop
 * 2. an _API_ value creates a proxy to wrap the value
 * 3. a _json_ (object or array) value is translated to the shim equivalent
 * 4. a jsonifiable _data object_ is converted to json or an equivalent
 * 5. an _enum_ value is converted to a string or an equivalent
 * 6. a _collection_ is usually translated to the shim equivalent
 * 7. a `java.lang.Throwable` is usually translated to the shim equivalent
 * 8. a type variable is converted dynamically converted to a _basic_ type or a _json_ type
 * 9. an `Handler` value is what is used in the target language to represent an handler, when this handler is called
 * it invokes the handler with the value converted using the argument value rules
 * 10. an `Handler>` value is what is used in the target language to represent an async result handler, when this handler
 * is _succeeded_ it invokes the handler with the `AsyncResult` wrapping the converted value using the argument value rules,
 * otherwise it invokes the handler with the `AsyncResult` wrapping the throwable
 *
 * === Argument values
 *
 * A shim implements several strategies when passing values to the Vert.x API:
 *
 * 1. a _basic_ value is usually handled by the shim interop
 * 2. an _API_ value is unwrapped from the shim proxy
 * 3. a _json_ (object or array) value is translated from the shim equivalent
 * 4. a _data object_ is instantiated from the shim equivalent by its `JsonObject` constructor
 * 5. an _enum_ is converted from a string or an equivalent
 * 6. a _collection_ is usually translated from the shim equivalent
 * 7. a type variable or `java.lang.Object` is converted dynamically converted to a _basic_ type or a _json_ type
 *
 * === Argument handlers
 *
 * Argument handlers have a special treatment as the handlers gets a callback.
 *
 * Usually a shim creates a `io.vertx.core.Handler` instance whose `handle(E)` implementation
 * calls back the handler argument applying the return value conversion strategy.
 *
 * For instance the `HttpClient#getNow` method:
 *
 * [source,java]
 * ----
 * void getNow(int port, String host, String requestURI, Handler responseHandler);
 * ----
 *
 * Can be translated to
 *
 * [source,javascript]
 * ----
 * function(port, host, requestURI, responseHandler) {
 *   j_httpClient.getNow(port, host, requestURI, function(jVal) {
 *     responseHandler(new HttpClientResponse(jVal));
 *   }
 * }
 * ----
 *
 * The JavaScript code calling passes a `function(result)`:
 *
 * [source,javascript]
 * ----
 * vertx.setTimer(1000, function(id) {
 *   // Timer fired
 * });
 * ----
 *
 * `AsyncResult` types also gets a specific treatment, for instance the `HttpServer#listen` method:
 *
 * [source,java]
 * ----
 * void listen(int port, String host, Handler> listenHandler);
 * ----
 *
 * Can be translated to
 *
 * [source,javascript]
 * ----
 * function(port, host, listenHandler) {
 *   j_httpServer.listen(port, host, function(ar) {
 *     if (ar.succeeded()) {
 *       listenHandler(new HttpServer(ar.result()), null);
 *     } else {
 *       listenHandler(null, ar.cause());
 *     }
 *   }
 * }
 * ----
 *
 * The JavaScript code calling passes a `function(result, err)`:
 *
 * [source,javascript]
 * ----
 * server.listen(80, "localhost", function(result, err) {
 *   if (result != null) {
 *     // It worked
 *   } else {
 *     // It failed
 *   }
 * });
 * ----
 *
 * === Exceptions
 *
 * todo
 *
 * === Method dispatching
 *
 * When a shim does not support overloading, it needs to handle the dispatch itself to the Java method, usually
 * based on the argument types when invocation occurs.
 *
 * todo provide example ?
 *
 * == Codegen types
 *
 * The {@link io.vertx.codegen.type.TypeInfo} provides a codegen view of the Java type system.
 *
 * A type info has a {@link io.vertx.codegen.type.ClassKind} usually used to determine the conversion to apply:
 *
 * [cols="1,4"]
 * .Class kinds
 * |===
 * | {@link io.vertx.codegen.type.ClassKind#STRING}
 * | `java.lang.String`
 * | {@link io.vertx.codegen.type.ClassKind#PRIMITIVE}
 * | any Java primitive type
 * | {@link io.vertx.codegen.type.ClassKind#BOXED_PRIMITIVE}
 * | any Java boxed primitive type
 * | {@link io.vertx.codegen.type.ClassKind#ENUM}
 * | any Java enum
 * | {@link io.vertx.codegen.type.ClassKind#JSON_OBJECT}
 * | `io.vertx.core.json.JsonObject`
 * | {@link io.vertx.codegen.type.ClassKind#JSON_ARRAY}
 * | `io.vertx.core.json.JsonArray`
 * | {@link io.vertx.codegen.type.ClassKind#THROWABLE}
 * | `java.lang.Throwable`
 * | {@link io.vertx.codegen.type.ClassKind#VOID}
 * | `java.lang.Void`
 * | {@link io.vertx.codegen.type.ClassKind#OBJECT}
 * | `java.lang.Object` or an unbounded type variable
 * | {@link io.vertx.codegen.type.ClassKind#LIST}
 * | `java.util.List`
 * | {@link io.vertx.codegen.type.ClassKind#SET}
 * | `java.util.Set`
 * | {@link io.vertx.codegen.type.ClassKind#MAP}
 * | `java.util.Map`
 * | {@link io.vertx.codegen.type.ClassKind#API}
 * | any _api_ type
 * | {@link io.vertx.codegen.type.ClassKind#DATA_OBJECT}
 * | any _data object_ type
 * | {@link io.vertx.codegen.type.ClassKind#HANDLER}
 * | `io.vertx.core.Handler`
 * | {@link io.vertx.codegen.type.ClassKind#ASYNC_RESULT}
 * | `io.vertx.core.AsyncResult`
 * | {@link io.vertx.codegen.type.ClassKind#OTHER}
 * | anything else
 * |===
 *
 * The `TypeInfo` base class provides common type information
 *
 * - {@link io.vertx.codegen.type.TypeInfo#getKind} the type {@link io.vertx.codegen.type.ClassKind}
 * - {@link io.vertx.codegen.type.TypeInfo#getName()} the type name
 * - {@link io.vertx.codegen.type.TypeInfo#getSimpleName()} the simple name
 * - {@link io.vertx.codegen.type.TypeInfo#getErased()} returns the corresponding erased type
 * - {@link io.vertx.codegen.type.TypeInfo#getRaw()} returns the raw type of a parameter type or this type
 *
 * Besides it provides the {@link io.vertx.codegen.type.TypeInfo#translateName(java.lang.String)} method to
 * translate the type name using a shim identifier, this is useful for shim using a hierarchical naming, for
 * instance the translated name of `io.vertx.core.eventbus.EventBus` for the `groovy` identifier is
 * `io.vertx.groovy.core.eventbus.EventBus`. The position where the identifier is applied is
 * determined by the {@link io.vertx.codegen.annotations.ModuleGen#groupPackage()} value.
 *
 * Several subclasses of `TypeInfo` provides specialization when needed:
 *
 * - {@link io.vertx.codegen.type.ClassTypeInfo} : a java class
 * - {@link io.vertx.codegen.type.ApiTypeInfo} : `TypeInfo.Class` specialization for _api_ types
 * - {@link io.vertx.codegen.type.EnumTypeInfo} : `TypeInfo.Class` specialization for _enum_ types
 * - {@link io.vertx.codegen.type.ParameterizedTypeInfo} : a parameterized type
 * - {@link io.vertx.codegen.type.PrimitiveTypeInfo} : a primitive type
 * - {@link io.vertx.codegen.type.VoidTypeInfo} : `void` (and not `java.lang.Void`)
 * - {@link io.vertx.codegen.type.TypeVariableInfo} : an unbounded type variable
 *
 * == Codegen models
 *
 * The codegen processor _validates_ annotated Java program elements (i.e type declaration) and _transforms_  them into models:
 *
 * 1. `ClassModel`
 * 2. `DataObjectModel`
 * 3. `EnumModel`
 * 4. `PackageModel`
 * 5. `ModuleModel`
 * 6. `ProxyModel`
 *
 * Models are processed by https://en.wikisource.org/wiki/MVEL_Language_Guide[MVEL] templates, when a template is executed it gets access to implicit properties
 * (i.e properties that are declared by the model).
 *
 * === Class model
 *
 * For each Java interface annotated with {@link io.vertx.codegen.annotations.VertxGen} a `{@link io.vertx.codegen.ClassModel}` is created.
 *
 * [cols="1,4"]
 * .Template properties
 * |===
 * | `importedTypes`
 * | the full list of used types including `java.lang.*` types as `{@link io.vertx.codegen.type.ClassTypeInfo}` that are not in the same package
 * | `referencedTypes`
 * | the full list of used types including `java.lang.*` types as `{@link io.vertx.codegen.type.ClassTypeInfo}`
 * | `referencedDataObjectTypes`
 * | the full list of used _data object_ types as `{@link io.vertx.codegen.type.ClassTypeInfo}`
 * | `type`
 * | the type `{@link io.vertx.codegen.type.ClassTypeInfo}` or `{@link io.vertx.codegen.type.ParameterizedTypeInfo}`
 * | `typeParams`
 * | the list of class type params as `List<`{@link io.vertx.codegen.TypeParamInfo.Class}`>`
 * | `concrete`
 * | a boolean value indicating if the model is _abstract_ or _concrete_
 * | `superTypes`
 * | all direct super types
 * | `concreteSuperType`
 * |the concrete direct super type or null
 * | `abstractSuperTypes`
 * | a list of all abstract direct super types
 * | `handlerSuperType`
 * | the type `io.vertx.core.Handler` when the type implements directly the `Handler` interface
 * | `methods`
 * | all the methods as `List<`{@link io.vertx.codegen.MethodInfo}`>`
 * | `instanceMethods`
 * | all the instance methods as `List<`{@link io.vertx.codegen.MethodInfo}`>`
 * | `staticMethods`
 * | all the static methods as `List<`{@link io.vertx.codegen.MethodInfo}`>`
 * | `methodsByName`
 * | a map of methods keyed by name as `Map>`
 * | `doc`
 * | the documentation as {@link io.vertx.codegen.doc.Doc}
 * |===
 *
 * todo method info / param info / type param info
 *
 * === Data object model
 *
 * todo
 *
 * === Enum model
 *
 * todo
 *
 * === Package model
 *
 * todo
 *
 * === Module model
 *
 * todo
 *
 * === Proxy model
 *
 * todo
 *
 * == Code generation
 *
 * The {@link io.vertx.codegen.CodeGenProcessor} is a Java Annotation Processor that validates and applies
 * _code generators_ on codegen models.
 *
 * The processor is declared in the compiler configuration, here is a typical Maven configuration:
 *
 * [source,xml]
 * ----
 * 
 *   
 *     
 *       maven-compiler-plugin
 *       
 *         
 *           default-testCompile
 *           
 *             
 *               io.vertx.codegen.CodeGenProcessor
 *             
 *             
 *               -AoutputDirectory=${project.basedir}/src/test <1>
 *             
 *           
 *         
 *       
 *     
 *   
 * 
 * ----
 * <1> the base output directory for generated files
 *
 * Code generators are determined from the classpath by looking at the `codegen.json` descriptors, there can
 * be several generators executed in the same compilation phase. The configuration of a code generator is
 * quite simple:
 *
 * [source,json]
 * ----
 * {
 *   "name": "Groovy", <1>
 *   "generators": [ { <2>
 *     "kind": "class", <3>
 *     "fileName": "'groovy/' + module.translateQualifiedName(fqn, 'groovy').replace('.', '/') + '.groovy'", <4>
 *     "templateFileName": "vertx-groovy/template/groovy.templ" <5>
 *   } ]
 * }
 * ----
 * <1> the processor name
 * <2> an array of generators
 * <3> the kind of model the generator process : _class_, _dataObject_, _enum_, _package_, _module_, _proxy_
 * <4> the MVEL expression of the generated file
 * <5> the MVEL template file name
 *
 * === Templating
 *
 * Templates are written in the MVEL language, documented here.
 *
 * Some characters have a special meaning:
 *
 * - the tab char is used for formatting purpose and is removed
 * - the *\n* sequence has the same meaning than in a Java string literal
 *
 * === Incremental templating
 *
 * Incremental templating allows the same template to process several models and create a single result. This is
 * useful when several sources files needs to generate a same file and the output is the result of the models. To
 * achieve incremental processing, a generator must declares `"incremental": true` in its descriptor.
 *
 * During the processing phase, the codegen processors collects all the files generated by incremental templates
 * and groups them by file name. Obviously, the _fileName_ expression of the generator needs to return an appropriate
 * string.
 *
 * At the end of the processing phase, templates are invoked for each model, pretty much like the normal templating but
 * with the following differences:
 *
 * - the variable `incrementalIndex` gives the sequence number of the current model, starting at 0
 * - the variable `incrementalSize` gives the total number of models processed by the template
 * - the variable `session` is a map provided that allows the template to maintain state
 * - the generated content are appended instead of overwritten
 *
 * For instance the template:
 *
 * [source]
 * ----
 * @if{incrementalIndex==0}
 *   \n
 *     \n
 *       
    \n * @end{} *
  • @{type.name}
  • \n * @if{incrementalIndex==incrementalSize-1} *
\n * \n * \n * @end{} * ---- * * With `codegen.json`: * * [source,json] * ---- * { * "name": "index", * "generators": [ { * "kind": "class", * "incremental": true, * "fileName": "'index.html'", * "templateFileName": "html-index.templ" * } ] * } * ---- * * Generates an HTML page with the name of all the API classes. */ @Document(fileName = "index.adoc") package io.vertx.codegen; import io.vertx.docgen.Document;




© 2015 - 2025 Weber Informatics LLC | Privacy Policy