1Ast_mapper(3) OCaml library Ast_mapper(3)
2
3
4
6 Ast_mapper - The interface of a -ppx rewriter
7
9 Module Ast_mapper
10
12 Module Ast_mapper
13 : sig end
14
15
16 The interface of a -ppx rewriter
17
18 A -ppx rewriter is a program that accepts a serialized abstract syntax
19 tree and outputs another, possibly modified, abstract syntax tree.
20 This module encapsulates the interface between the compiler and the
21 -ppx rewriters, handling such details as the serialization format, for‐
22 warding of command-line flags, and storing state.
23
24
25 Ast_mapper.mapper allows to implement AST rewriting using open recur‐
26 sion. A typical mapper would be based on Ast_mapper.default_mapper , a
27 deep identity mapper, and will fall back on it for handling the syntax
28 it does not modify. For example:
29
30
31 open Asttypes open Parsetree open Ast_mapper let test_mapper argv = {
32 default_mapper with expr = fun mapper expr -> match expr with | {
33 pexp_desc = Pexp_extension ({ txt = test }, PStr [])} ->
34 Ast_helper.Exp.constant (Const_int 42) | other -> default_mapper.expr
35 mapper other; } let () = register ppx_test test_mapper
36
37 This -ppx rewriter, which replaces [%test] in expressions with the con‐
38 stant 42 , can be compiled using ocamlc -o ppx_test -I +compiler-libs
39 ocamlcommon.cma ppx_test.ml .
40
41
42
43
44
45
46
47 === A generic Parsetree mapper ===
48
49
50 type mapper = {
51 attribute : mapper -> Parsetree.attribute -> Parsetree.attribute ;
52 attributes : mapper -> Parsetree.attribute list -> Parsetree.attribute
53 list ;
54 case : mapper -> Parsetree.case -> Parsetree.case ;
55 cases : mapper -> Parsetree.case list -> Parsetree.case list ;
56 class_declaration : mapper -> Parsetree.class_declaration -> Parse‐
57 tree.class_declaration ;
58 class_description : mapper -> Parsetree.class_description -> Parse‐
59 tree.class_description ;
60 class_expr : mapper -> Parsetree.class_expr -> Parsetree.class_expr ;
61 class_field : mapper -> Parsetree.class_field -> Parsetree.class_field
62 ;
63 class_signature : mapper -> Parsetree.class_signature -> Parse‐
64 tree.class_signature ;
65 class_structure : mapper -> Parsetree.class_structure -> Parse‐
66 tree.class_structure ;
67 class_type : mapper -> Parsetree.class_type -> Parsetree.class_type ;
68 class_type_declaration : mapper -> Parsetree.class_type_declaration ->
69 Parsetree.class_type_declaration ;
70 class_type_field : mapper -> Parsetree.class_type_field -> Parse‐
71 tree.class_type_field ;
72 constructor_declaration : mapper -> Parsetree.constructor_declaration
73 -> Parsetree.constructor_declaration ;
74 expr : mapper -> Parsetree.expression -> Parsetree.expression ;
75 extension : mapper -> Parsetree.extension -> Parsetree.extension ;
76 extension_constructor : mapper -> Parsetree.extension_constructor ->
77 Parsetree.extension_constructor ;
78 include_declaration : mapper -> Parsetree.include_declaration ->
79 Parsetree.include_declaration ;
80 include_description : mapper -> Parsetree.include_description ->
81 Parsetree.include_description ;
82 label_declaration : mapper -> Parsetree.label_declaration -> Parse‐
83 tree.label_declaration ;
84 location : mapper -> Location.t -> Location.t ;
85 module_binding : mapper -> Parsetree.module_binding -> Parsetree.mod‐
86 ule_binding ;
87 module_declaration : mapper -> Parsetree.module_declaration -> Parse‐
88 tree.module_declaration ;
89 module_expr : mapper -> Parsetree.module_expr -> Parsetree.module_expr
90 ;
91 module_type : mapper -> Parsetree.module_type -> Parsetree.module_type
92 ;
93 module_type_declaration : mapper -> Parsetree.module_type_declaration
94 -> Parsetree.module_type_declaration ;
95 open_description : mapper -> Parsetree.open_description -> Parse‐
96 tree.open_description ;
97 pat : mapper -> Parsetree.pattern -> Parsetree.pattern ;
98 payload : mapper -> Parsetree.payload -> Parsetree.payload ;
99 signature : mapper -> Parsetree.signature -> Parsetree.signature ;
100 signature_item : mapper -> Parsetree.signature_item -> Parsetree.sig‐
101 nature_item ;
102 structure : mapper -> Parsetree.structure -> Parsetree.structure ;
103 structure_item : mapper -> Parsetree.structure_item -> Parse‐
104 tree.structure_item ;
105 typ : mapper -> Parsetree.core_type -> Parsetree.core_type ;
106 type_declaration : mapper -> Parsetree.type_declaration -> Parse‐
107 tree.type_declaration ;
108 type_extension : mapper -> Parsetree.type_extension -> Parse‐
109 tree.type_extension ;
110 type_kind : mapper -> Parsetree.type_kind -> Parsetree.type_kind ;
111 value_binding : mapper -> Parsetree.value_binding -> Parse‐
112 tree.value_binding ;
113 value_description : mapper -> Parsetree.value_description -> Parse‐
114 tree.value_description ;
115 with_constraint : mapper -> Parsetree.with_constraint -> Parse‐
116 tree.with_constraint ;
117 }
118
119
120 A mapper record implements one "method" per syntactic category, using
121 an open recursion style: each method takes as its first argument the
122 mapper to be applied to children in the syntax tree.
123
124
125
126 val default_mapper : mapper
127
128 A default mapper, which implements a "deep identity" mapping.
129
130
131
132
133 === Apply mappers to compilation units ===
134
135
136 val tool_name : unit -> string
137
138 Can be used within a ppx preprocessor to know which tool is calling it
139 ocamlc , ocamlopt , ocamldoc , ocamldep , ocaml , ... Some global
140 variables that reflect command-line options are automatically synchro‐
141 nized between the calling tool and the ppx preprocessor:
142 Clflags.include_dirs , Config.load_path , Clflags.open_modules ,
143 Clflags.for_package , Clflags.debug .
144
145
146
147 val apply : source:string -> target:string -> mapper -> unit
148
149 Apply a mapper (parametrized by the unit name) to a dumped parsetree
150 found in the source file and put the result in the target file. The
151 structure or signature field of the mapper is applied to the implemen‐
152 tation or interface.
153
154
155
156 val run_main : (string list -> mapper) -> unit
157
158 Entry point to call to implement a standalone -ppx rewriter from a map‐
159 per, parametrized by the command line arguments. The current unit name
160 can be obtained from Location.input_name . This function implements
161 proper error reporting for uncaught exceptions.
162
163
164
165
166 === Registration API ===
167
168
169 val register_function : (string -> (string list -> mapper) -> unit)
170 Pervasives.ref
171
172
173
174
175 val register : string -> (string list -> mapper) -> unit
176
177 Apply the register_function . The default behavior is to run the map‐
178 per immediately, taking arguments from the process command line. This
179 is to support a scenario where a mapper is linked as a stand-alone exe‐
180 cutable.
181
182 It is possible to overwrite the register_function to define "-ppx driv‐
183 ers", which combine several mappers in a single process. Typically, a
184 driver starts by defining register_function to a custom implementation,
185 then lets ppx rewriters (linked statically or dynamically) register
186 themselves, and then run all or some of them. It is also possible to
187 have -ppx drivers apply rewriters to only specific parts of an AST.
188
189 The first argument to register is a symbolic name to be used by the ppx
190 driver.
191
192
193
194
195 === Convenience functions to write mappers ===
196
197
198 val map_opt : ('a -> 'b) -> 'a option -> 'b option
199
200
201
202
203 val extension_of_error : Location.error -> Parsetree.extension
204
205 Encode an error into an 'ocaml.error' extension node which can be
206 inserted in a generated Parsetree. The compiler will be responsible
207 for reporting the error.
208
209
210
211 val attribute_of_warning : Location.t -> string -> Parsetree.attribute
212
213 Encode a warning message into an 'ocaml.ppwarning' attribute which can
214 be inserted in a generated Parsetree. The compiler will be responsible
215 for reporting the warning.
216
217
218
219
220 === Helper functions to call external mappers ===
221
222
223 val add_ppx_context_str : tool_name:string -> Parsetree.structure ->
224 Parsetree.structure
225
226 Extract information from the current environment and encode it into an
227 attribute which is prepended to the list of structure items in order to
228 pass the information to an external processor.
229
230
231
232 val add_ppx_context_sig : tool_name:string -> Parsetree.signature ->
233 Parsetree.signature
234
235 Same as add_ppx_context_str , but for signatures.
236
237
238
239 val drop_ppx_context_str : restore:bool -> Parsetree.structure ->
240 Parsetree.structure
241
242 Drop the ocaml.ppx.context attribute from a structure. If restore is
243 true, also restore the associated data in the current process.
244
245
246
247 val drop_ppx_context_sig : restore:bool -> Parsetree.signature ->
248 Parsetree.signature
249
250 Same as drop_ppx_context_str , but for signatures.
251
252
253
254
255 === Cookies ===
256
257
258 === Cookies are used to pass information from a ppx processor to a fur‐
259 ther invocation of itself, when called from the OCaml toplevel (or
260 other tools that support cookies). ===
261
262
263 val set_cookie : string -> Parsetree.expression -> unit
264
265
266
267
268 val get_cookie : string -> Parsetree.expression option
269
270
271
272
273
274
275OCamldoc 2019-02-02 Ast_mapper(3)