1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
|
open Ppxlib
let string_pattern = Ast_pattern.(single_expr_payload (estring __))
let template_class_expr ~ctxt:_ class_expr payload =
match class_expr.pcl_desc with
| Pcl_constr ({ txt = Lident name; loc }, args) ->
{
class_expr with
pcl_desc =
Pcl_constr ({ txt = Lident (name ^ "__" ^ payload); loc }, args);
}
| _ -> class_expr
let () =
Driver.register_transformation "test.clx"
~rules:
[
Context_free.Rule.attr_replace "test.clx" Extension.Context.class_expr
(Attribute.declare "test.clx" Class_expr string_pattern Fun.id)
template_class_expr;
]
let template_class_field ~ctxt:_ class_field payload =
match class_field.pcf_desc with
| Pcf_val ({ txt = name; loc }, flag, kind) ->
{
class_field with
pcf_desc = Pcf_val ({ txt = name ^ "__" ^ payload; loc }, flag, kind);
}
| _ -> class_field
let () =
Driver.register_transformation "test.clf"
~rules:
[
Context_free.Rule.attr_replace "test.clf" Extension.Context.class_field
(Attribute.declare "test.clf" Class_field string_pattern Fun.id)
template_class_field;
]
let template_class_type ~ctxt:_ class_type payload =
match class_type.pcty_desc with
| Pcty_constr ({ txt = Lident name; loc }, args) ->
{
class_type with
pcty_desc =
Pcty_constr ({ txt = Lident (name ^ "__" ^ payload); loc }, args);
}
| _ -> class_type
let () =
Driver.register_transformation "test.clt"
~rules:
[
Context_free.Rule.attr_replace "test.clt" Extension.Context.class_type
(Attribute.declare "test.clt" Class_type string_pattern Fun.id)
template_class_type;
]
let template_class_type_field ~ctxt:_ class_type_field payload =
match class_type_field.pctf_desc with
| Pctf_val ({ txt = name; loc }, mut_flag, virt_flag, ty) ->
{
class_type_field with
pctf_desc =
Pctf_val
({ txt = name ^ "__" ^ payload; loc }, mut_flag, virt_flag, ty);
}
| _ -> class_type_field
let () =
Driver.register_transformation "test.ctf"
~rules:
[
Context_free.Rule.attr_replace "test.ctf"
Extension.Context.class_type_field
(Attribute.declare "test.ctf" Class_type_field string_pattern Fun.id)
template_class_type_field;
]
let template_core_type ~ctxt:_ core_type payload =
match core_type.ptyp_desc with
| Ptyp_constr ({ txt = Lident name; loc }, args) ->
{
core_type with
ptyp_desc =
Ptyp_constr ({ txt = Lident (name ^ "__" ^ payload); loc }, args);
}
| _ -> core_type
let () =
Driver.register_transformation "test.typ"
~rules:
[
Context_free.Rule.attr_replace "test.typ" Extension.Context.core_type
(Attribute.declare "test.typ" Core_type string_pattern Fun.id)
template_core_type;
]
let template_expression ~ctxt:_ expression payload =
match expression.pexp_desc with
| Pexp_ident { txt = Lident name; loc } ->
{
expression with
pexp_desc = Pexp_ident { txt = Lident (name ^ "__" ^ payload); loc };
}
| _ -> expression
let () =
Driver.register_transformation "test.exp"
~rules:
[
Context_free.Rule.attr_replace "test.exp" Extension.Context.expression
(Attribute.declare "test.exp" Expression string_pattern Fun.id)
template_expression;
]
let template_module_expr ~ctxt:_ module_expr payload =
match module_expr.pmod_desc with
| Pmod_ident { txt = Lident name; loc } ->
{
module_expr with
pmod_desc = Pmod_ident { txt = Lident (name ^ "__" ^ payload); loc };
}
| _ -> module_expr
let () =
Driver.register_transformation "test.mod_exp"
~rules:
[
Context_free.Rule.attr_replace "test.mod_exp"
Extension.Context.module_expr
(Attribute.declare "test.mod_exp" Module_expr string_pattern Fun.id)
template_module_expr;
]
let template_module_type ~ctxt:_ module_type payload =
match module_type.pmty_desc with
| Pmty_ident { txt = Lident name; loc } ->
{
module_type with
pmty_desc = Pmty_ident { txt = Lident (name ^ "__" ^ payload); loc };
}
| _ -> module_type
let () =
Driver.register_transformation "test.mod_typ"
~rules:
[
Context_free.Rule.attr_replace "test.mod_typ"
Extension.Context.module_type
(Attribute.declare "test.mod_typ" Module_type string_pattern Fun.id)
template_module_type;
]
let template_pattern ~ctxt:_ pattern payload =
match pattern.ppat_desc with
| Ppat_var { txt = name; loc } ->
{ pattern with ppat_desc = Ppat_var { txt = name ^ "__" ^ payload; loc } }
| _ -> pattern
let () =
Driver.register_transformation "test.pat"
~rules:
[
Context_free.Rule.attr_replace "test.pat" Extension.Context.pattern
(Attribute.declare "test.pat" Pattern string_pattern Fun.id)
template_pattern;
]
let template_sig_extension ~ctxt:_ sig_item payload =
match sig_item.psig_desc with
| Psig_extension ((ext, inner_payload), attrs) ->
{
sig_item with
psig_desc =
Psig_extension
(({ ext with txt = ext.txt ^ "__" ^ payload }, inner_payload), attrs);
}
| _ -> assert false
let () =
Driver.register_transformation "test.sig.ext"
~rules:
[
Context_free.Rule.attr_replace "test.sig.ext"
Extension.Context.signature_item
(Attribute.declare "test.sig.ext" Psig_extension string_pattern Fun.id)
template_sig_extension;
]
let template_str_extension ~ctxt:_ structure_item payload =
match structure_item.pstr_desc with
| Pstr_extension ((ext, inner_payload), attrs) ->
{
structure_item with
pstr_desc =
Pstr_extension
(({ ext with txt = ext.txt ^ "__" ^ payload }, inner_payload), attrs);
}
| _ -> assert false
let () =
Driver.register_transformation "test.str.ext"
~rules:
[
Context_free.Rule.attr_replace "test.str.ext"
Extension.Context.structure_item
(Attribute.declare "test.str.ext" Pstr_extension string_pattern Fun.id)
template_str_extension;
]
let template_str_eval ~ctxt:_ structure_item payload =
match structure_item.pstr_desc with
| Pstr_eval (expression, attributes) ->
let expression =
match expression.pexp_desc with
| Pexp_ident { txt = Lident name; loc } ->
{
expression with
pexp_desc =
Pexp_ident { txt = Lident (name ^ "__" ^ payload); loc };
}
| _ -> expression
in
{ structure_item with pstr_desc = Pstr_eval (expression, attributes) }
| _ -> assert false
let () =
Driver.register_transformation "test.str.evl"
~rules:
[
Context_free.Rule.attr_replace "test.str.evl"
Extension.Context.structure_item
(Attribute.declare "test.str.evl" Pstr_eval string_pattern Fun.id)
template_str_eval;
]
let template_ppx_import ~ctxt:_ _payload = assert false
let () =
Driver.register_transformation "test.ppx.import"
~rules:
[
Context_free.Rule.attr_replace "test.ppx.import"
Extension.Context.Ppx_import
(Attribute.declare "test.ppx.import" Type_declaration string_pattern
Fun.id)
template_ppx_import;
]
let attr_multi ~ctxt:_ expression
([ prefix; suffix ] :
_ Context_free.Rule.Attr_multiple_replace.Parsed_payload_list.t) =
match (prefix, suffix) with
| None, None -> assert false
| _ -> (
();
match expression.pexp_desc with
| Pexp_ident { txt = Lident name; loc } ->
let prefixed = Option.value ~default:"" prefix ^ name in
let suffixed = prefixed ^ Option.value ~default:"" suffix in
{
expression with
pexp_desc = Pexp_ident { txt = Lident suffixed; loc };
}
| _ -> expression)
let () =
Driver.register_transformation "test"
~rules:
[
Context_free.Rule.Attr_multiple_replace.attr_multiple_replace
"test.multi.exp" Extension.Context.expression
[
Attribute.declare "test.multi.exp.prefix" Expression string_pattern
Fun.id;
Attribute.declare "test.multi.exp.suffix" Expression string_pattern
Fun.id;
]
attr_multi;
]
let () = Driver.standalone ()
|