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