register_transformation name
registers a code transformation.
name
is a logical name for the transformation (such as sexp_conv
or bin_prot
). It is mostly used for debugging purposes.
rules
is a list of context independent rewriting rules, such as extension point expanders. This is what most code transformation should use. Rules from all registered transformations are all applied at the same time, before any other transformations. Moreover they are applied in a top-down manner, giving more control to extensions on how they interpret their payload.
For instance:
- some extensions capture a pretty-print of the payload in their expansion and using top-down ensures that the payload is as close as possible to the original code
- some extensions process other extension in a special way inside their payload. For instance
%here
(from ppx_here) will normally expand to a record of type Lexing.position
. However when used inside %sexp
(from ppx_sexp_value) it will expand to the human-readable sexp representation of a source code position.
extensions
is a special cases of rules
and is deprecated. It is only kept for backward compatibility.
enclose_impl
and enclose_intf
produces a header and footer for implementation/interface files. They are a special case of impl
and intf
. The header is placed after any initial module-level attributes; the footer is placed after everything else. Both functions receive a location that denotes all of the items between header and footer, or None
if the that list of items is empty.
impl
is an optional function that is applied on implementation files and intf
is an optional function that is applied on interface files. These two functions are applied on the AST of the whole file. They should only be used when the other mechanism are not enough. For instance if the transformation expands extension points that depend on the context.
If no rewriter is using impl
and intf
, then the whole transformation is completely independent of the order in which the various rewriter are specified. Moreover the resulting driver will be faster as it will do only one pass (excluding safety checks) on the whole AST.
lint_impl
and lint_intf
are applied to the unprocessed source. Errors they return will be reported to the user as preprocessor warnings.
instrument
can be used to instrument implementation files. Its transformation is applied to the AST of the whole file. The difference to impl
is that you can specify if it should be applied before or after all rewriters defined through rules
, impl
or intf
are applied.
Rewritings are applied in the following order:
- linters (
lint_impl
, lint_intf
) - preprocessing (
preprocess_impl
, preprocess_intf
) - "before" instrumentations (
instrument
, where instrument = Instrument.make ~position:Before (...)
) - context-independent rules (
rules
, extensions
) - non-instrumentation whole-file transformations (
impl
, intf
, enclose_impl
, enclose_intf
) - "after" instrumentations (
instrument
, where instrument = Instrument.make ~position:After (...)
)