Source file renaming.ml
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
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
open Catala_utils
open Definitions
module DefaultBindlibCtxRename : Bindlib.Renaming = struct
type ctxt = int String.Map.t
let empty_ctxt = String.Map.empty
let split_name : string -> string * int =
fun name ->
let len = String.length name in
let i =
let is_digit c = '0' <= c && c <= '9' in
let first_digit = ref len in
let first_non_0 = ref len in
while !first_digit > 0 && is_digit name.[!first_digit - 1] do
decr first_digit;
if name.[!first_digit] <> '0' then first_non_0 := !first_digit
done;
!first_non_0
in
if
i = len || not (i >= 2 && name.[i - 1] = '_' && name.[i - 2] = '_')
then name, 0
else String.sub name 0 (i - 2), int_of_string (String.sub name i (len - i))
let get_suffix : string -> int -> ctxt -> int * ctxt =
fun name suffix ctxt ->
let n = try String.Map.find name ctxt with String.Map.Not_found _ -> -1 in
let suffix = if suffix > n then suffix else n + 1 in
suffix, String.Map.add name suffix ctxt
let merge_name : string -> int -> string =
fun prefix suffix ->
if suffix > 0 then
prefix ^ "__" ^ string_of_int suffix
else prefix
let new_name : string -> ctxt -> string * ctxt =
fun name ctxt ->
let prefix, suffix = split_name name in
let suffix, ctxt = get_suffix prefix suffix ctxt in
merge_name prefix suffix, ctxt
let reserve_name : string -> ctxt -> ctxt =
fun name ctxt ->
let prefix, suffix = split_name name in
try
let n = String.Map.find prefix ctxt in
if suffix <= n then ctxt else String.Map.add prefix suffix ctxt
with String.Map.Not_found _ -> String.Map.add prefix suffix ctxt
let reset_context_for_closed_terms = false
let skip_constant_binders = false
let constant_binder_name = None
end
module type BindlibCtxt = module type of Bindlib.Ctxt (DefaultBindlibCtxRename)
type config = {
reserved : string list;
sanitize_varname : string -> string;
skip_constant_binders : bool;
constant_binder_name : string option;
}
type context = {
bindCtx : (module BindlibCtxt);
bcontext : DefaultBindlibCtxRename.ctxt;
vars : string -> string;
scopes : ScopeName.t -> ScopeName.t;
topdefs : TopdefName.t -> TopdefName.t;
structs : StructName.t -> StructName.t;
fields : StructField.t -> StructField.t;
enums : EnumName.t -> EnumName.t;
constrs : EnumConstructor.t -> EnumConstructor.t;
}
let default_config =
{
reserved = [];
sanitize_varname = Fun.id;
skip_constant_binders = false;
constant_binder_name = None;
}
let patch_binder_name fname b =
let name = fname (Bindlib.binder_name b) in
let occurs = Bindlib.binder_occur b in
let rank = Bindlib.binder_rank b in
let mkfree v = EVar v in
let subst = Bindlib.subst b in
Bindlib.raw_binder name occurs rank mkfree subst
let patch_mbinder_names fname b =
let names = Array.map fname (Bindlib.mbinder_names b) in
let occurs = Bindlib.mbinder_occurs b in
let rank = Bindlib.mbinder_rank b in
let mkfree v = EVar v in
let msubst = Bindlib.msubst b in
Bindlib.raw_mbinder names occurs rank mkfree msubst
let unbind_in ctx b =
let module BindCtx = (val ctx.bindCtx) in
let b = patch_binder_name ctx.vars b in
let v, e, bcontext = BindCtx.unbind_in ctx.bcontext b in
v, e, { ctx with bcontext }
let unmbind_in ctx b =
let module BindCtx = (val ctx.bindCtx) in
let b = patch_mbinder_names ctx.vars b in
let vs, e, bcontext = BindCtx.unmbind_in ctx.bcontext b in
vs, e, { ctx with bcontext }
let set_rewriters ?scopes ?topdefs ?structs ?fields ?enums ?constrs ctx =
(fun ?(scopes = ctx.scopes) ?(topdefs = ctx.topdefs) ?(structs = ctx.structs)
?(fields = ctx.fields) ?(enums = ctx.enums) ?(constrs = ctx.constrs) () ->
{ ctx with scopes; topdefs; structs; fields; enums; constrs })
?scopes ?topdefs ?structs ?fields ?enums ?constrs ()
let new_id ctx name =
let module BindCtx = (val ctx.bindCtx) in
let var, bcontext =
BindCtx.new_var_in ctx.bcontext (fun _ -> assert false) name
in
Bindlib.name_of var, { ctx with bcontext }
let new_var_id ctx name = new_id ctx (ctx.vars name)
let reserve_name ctx name =
{ ctx with bcontext = DefaultBindlibCtxRename.reserve_name name ctx.bcontext }
let get_ctx cfg =
let module BindCtx = Bindlib.Ctxt (struct
include DefaultBindlibCtxRename
let skip_constant_binders = cfg.skip_constant_binders
let constant_binder_name = cfg.constant_binder_name
end) in
{
bindCtx = (module BindCtx);
bcontext =
List.fold_left
(fun ctx name -> DefaultBindlibCtxRename.reserve_name name ctx)
BindCtx.empty_ctxt cfg.reserved;
vars = cfg.sanitize_varname;
scopes = Fun.id;
topdefs = Fun.id;
structs = Fun.id;
fields = Fun.id;
enums = Fun.id;
constrs = Fun.id;
}
let typ ctx ty =
let rec aux = function
| TStruct n, m -> Bindlib.box (TStruct (ctx.structs n), m)
| TEnum n, m -> Bindlib.box (TEnum (ctx.enums n), m)
| ty -> Type.map aux ty
in
Bindlib.unbox (aux ty)
let rec expr : type k. context -> (k, 'm) gexpr -> (k, 'm) gexpr boxed =
fun ctx e ->
let fm m = Expr.map_ty (typ ctx) m in
match e with
| EExternal { name = External_scope s, pos }, m ->
Expr.eexternal ~name:(External_scope (ctx.scopes s), pos) (fm m)
| EExternal { name = External_value d, pos }, m ->
Expr.eexternal ~name:(External_value (ctx.topdefs d), pos) (fm m)
| EAbs { binder; tys; pos }, m ->
let vars, body, ctx = unmbind_in ctx binder in
let body = expr ctx body in
let binder = Expr.bind vars body in
Expr.eabs binder pos (List.map (typ ctx) tys) (fm m)
| ( EApp { f = EAbs { binder; pos; tys = tyabs }, mabs; args; tys = tyapp },
mapp ) ->
let vars, body, ctx = unmbind_in ctx binder in
let body = expr ctx body in
let binder = Expr.bind vars body in
Expr.eapp
~f:(Expr.eabs binder pos (List.map (typ ctx) tyabs) (fm mabs))
~args:(List.map (expr ctx) args)
~tys:(List.map (typ ctx) tyapp)
(fm mapp)
| EStruct { name; fields }, m ->
Expr.estruct ~name:(ctx.structs name)
~fields:
(StructField.Map.fold
(fun fld e -> StructField.Map.add (ctx.fields fld) (expr ctx e))
fields StructField.Map.empty)
(fm m)
| EStructAccess { name; field; e }, m ->
Expr.estructaccess ~name:(ctx.structs name) ~field:(ctx.fields field)
~e:(expr ctx e) (fm m)
| EInj { name; e; cons }, m ->
Expr.einj ~name:(ctx.enums name) ~cons:(ctx.constrs cons) ~e:(expr ctx e)
(fm m)
| EMatch { name; e; cases }, m ->
Expr.ematch ~name:(ctx.enums name)
~cases:
(EnumConstructor.Map.fold
(fun cons e ->
EnumConstructor.Map.add (ctx.constrs cons) (expr ctx e))
cases EnumConstructor.Map.empty)
~e:(expr ctx e) (fm m)
| e -> Expr.map ~typ:(typ ctx) ~f:(expr ctx) ~op:Fun.id e
let scope_name ctx s = ctx.scopes s
let topdef_name ctx s = ctx.topdefs s
let struct_name ctx s = ctx.structs s
let enum_name ctx e = ctx.enums e
(** Maps carrying around a naming context, enriched at each [unbind] *)
let rec boundlist_map_ctx ~f ~last ~ctx = function
| Last l -> Bindlib.box_apply (fun l -> Last l) (last ctx l)
| Cons (item, next_bind) ->
let var, next, ctx = unbind_in ctx next_bind in
let item = f ctx item in
let next = boundlist_map_ctx ~f ~last ~ctx next in
let next_bind = Bindlib.bind_var var next in
Bindlib.box_apply2
(fun item next_bind -> Cons (item, next_bind))
item next_bind
let rename_vars_in_lets ctx scope_body_expr =
boundlist_map_ctx scope_body_expr ~ctx
~last:(fun ctx e -> Expr.Box.lift (expr ctx e))
~f:(fun ctx scope_let ->
Bindlib.box_apply
(fun scope_let_expr ->
{
scope_let with
scope_let_expr;
scope_let_typ = typ ctx scope_let.scope_let_typ;
})
(Expr.Box.lift (expr ctx scope_let.scope_let_expr)))
let code_items ctx fty (items : 'e code_item_list) =
let rec aux ctx = function
| Last exports ->
( Bindlib.box_apply
(fun e -> Last e)
(Scope.map_exports (expr ctx) exports),
ctx )
| Cons (ScopeDef (name, body), next_bind) ->
let scope_body =
let scope_input_var, scope_lets, ctx =
unbind_in ctx body.scope_body_expr
in
let scope_lets = rename_vars_in_lets ctx scope_lets in
let scope_body_expr = Bindlib.bind_var scope_input_var scope_lets in
Bindlib.box_apply
(fun scope_body_expr ->
{
scope_body_input_struct =
struct_name ctx body.scope_body_input_struct;
scope_body_output_struct =
struct_name ctx body.scope_body_output_struct;
scope_body_expr;
scope_body_visibility = body.scope_body_visibility;
})
scope_body_expr
in
let scope_var, next, ctx =
match body.scope_body_visibility with
| Public ->
let name, _ = ScopeName.get_info (scope_name ctx name) in
let v = Bindlib.new_var (fun v -> EVar v) name in
let next = Bindlib.subst next_bind (EVar v) in
v, next, ctx
| Private ->
unbind_in ctx next_bind
in
let next_body, ctx = aux ctx next in
let next_bind = Bindlib.bind_var scope_var next_body in
( Bindlib.box_apply2
(fun body next_bind -> Cons (ScopeDef (name, body), next_bind))
scope_body next_bind,
ctx )
| Cons (Topdef (name, ty, visibility, e), next_bind) ->
let e = expr ctx e in
let ty = fty ty in
let topdef_var, next, ctx =
match visibility with
| Public ->
let name, _ = TopdefName.get_info (topdef_name ctx name) in
let v = Bindlib.new_var (fun v -> EVar v) name in
let next = Bindlib.subst next_bind (EVar v) in
v, next, ctx
| Private ->
unbind_in ctx next_bind
in
let next_body, ctx = aux ctx next in
let next_bind = Bindlib.bind_var topdef_var next_body in
( Bindlib.box_apply2
(fun e next_bind ->
Cons (Topdef (name, ty, visibility, e), next_bind))
(Expr.Box.lift e) next_bind,
ctx )
in
let items, ctx = aux ctx items in
Bindlib.unbox items, ctx
module PathMap = Map.Make (Uid.Path)
type type_renaming_ctx = {
path_ctx : context PathMap.t;
toplevel_module : ModuleName.t option;
prefix_module : bool;
modnames_conflict : bool;
structs_map : StructName.t StructName.Map.t;
fields_map : StructField.t StructField.Map.t;
enums_map : EnumName.t EnumName.Map.t;
constrs_map : EnumConstructor.t EnumConstructor.Map.t;
ctx_structs : struct_ctx;
ctx_enums : enum_ctx;
namespaced_fields : bool;
namespaced_constrs : bool;
f_struct : string -> string;
f_field : string -> string;
f_enum : string -> string;
f_constr : string -> string;
}
let add_module_prefix ctx path str =
let pfx =
match List.rev path, ctx.toplevel_module with
| [], None -> []
| [], Some md | md :: _, _ -> [ModuleName.to_string md]
in
String.concat "." (pfx @ [str])
let get_path_ctx decl_ctx tctx ctx0 path =
try tctx.path_ctx, PathMap.find path tctx.path_ctx
with PathMap.Not_found _ ->
let ctx =
if tctx.modnames_conflict then
let rec get_used_modules modtree path =
match path with
| [] ->
Option.to_list tctx.toplevel_module @ ModuleName.Map.keys modtree
| [m] -> m :: ModuleName.Map.keys (ModuleName.Map.find m modtree).deps
| m :: path ->
get_used_modules (ModuleName.Map.find m modtree).deps path
in
List.fold_left
(fun ctx mname -> reserve_name ctx (ModuleName.to_string mname))
ctx0
(get_used_modules decl_ctx.ctx_modules path)
else ctx0
in
PathMap.add path ctx tctx.path_ctx, ctx
let process_type_ident
(decl_ctx : decl_ctx)
ctx0
type_ident
(tctx : type_renaming_ctx) =
match type_ident with
| TypeIdent.Struct name ->
let fields = StructName.Map.find name decl_ctx.ctx_structs in
let path = StructName.path name in
let add_prefix =
if
tctx.prefix_module
&& TypeIdent.Set.mem (Struct name) decl_ctx.ctx_public_types
then add_module_prefix tctx path
else Fun.id
in
let path_ctx, ctx = get_path_ctx decl_ctx tctx ctx0 path in
let str, pos = StructName.get_info name in
let str = add_prefix str in
let id, ctx = new_id ctx (tctx.f_struct str) in
let new_name = StructName.fresh path (id, pos) in
let ctx1, fields_map, ctx_fields =
StructField.Map.fold
(fun name ty (ctx, fields_map, ctx_fields) ->
let str, pos = StructField.get_info name in
let str = add_prefix str in
let id, ctx = new_id ctx (tctx.f_field str) in
let new_name = StructField.fresh (id, pos) in
( ctx,
StructField.Map.add name new_name fields_map,
StructField.Map.add new_name ty ctx_fields ))
fields
( (if tctx.namespaced_fields then ctx0 else ctx),
tctx.fields_map,
StructField.Map.empty )
in
let ctx = if tctx.namespaced_fields then ctx else ctx1 in
{
tctx with
path_ctx = PathMap.add path ctx path_ctx;
structs_map = StructName.Map.add name new_name tctx.structs_map;
fields_map;
ctx_structs = StructName.Map.add new_name ctx_fields tctx.ctx_structs;
}
| TypeIdent.Enum name when EnumName.equal name Expr.option_enum ->
let constrs = EnumName.Map.find name decl_ctx.ctx_enums in
let ctx = PathMap.find [] tctx.path_ctx in
let ctx1, constrs_map =
EnumConstructor.Map.fold
(fun name _ (ctx, constrs_map) ->
let str, _ = EnumConstructor.get_info name in
let ctx = reserve_name ctx str in
ctx, EnumConstructor.Map.add name name constrs_map)
constrs
((if tctx.namespaced_constrs then ctx0 else ctx), tctx.constrs_map)
in
let ctx = if tctx.namespaced_constrs then ctx else ctx1 in
{
tctx with
path_ctx = PathMap.add [] ctx tctx.path_ctx;
enums_map = EnumName.Map.add name name tctx.enums_map;
constrs_map;
ctx_enums = EnumName.Map.add name Expr.option_enum_config tctx.ctx_enums;
}
| TypeIdent.Enum ename ->
let constrs = EnumName.Map.find ename decl_ctx.ctx_enums in
let path = EnumName.path ename in
let add_prefix =
if
tctx.prefix_module
&& TypeIdent.Set.mem (Enum ename) decl_ctx.ctx_public_types
then add_module_prefix tctx path
else Fun.id
in
let str, pos = EnumName.get_info ename in
let str = add_prefix str in
let path_ctx, ctx = get_path_ctx decl_ctx tctx ctx0 path in
let id, ctx = new_id ctx (tctx.f_enum str) in
let new_name = EnumName.fresh path (id, pos) in
let ctx1, constrs_map, ctx_constrs =
EnumConstructor.Map.fold
(fun name ty (ctx, constrs_map, ctx_constrs) ->
let str, pos = EnumConstructor.get_info name in
let str =
if tctx.namespaced_constrs then str
else EnumName.base ename ^ "." ^ str
in
let str = add_prefix str in
let id, ctx = new_id ctx (tctx.f_constr str) in
let new_name = EnumConstructor.fresh (id, pos) in
( ctx,
EnumConstructor.Map.add name new_name constrs_map,
EnumConstructor.Map.add new_name ty ctx_constrs ))
constrs
( (if tctx.namespaced_constrs then ctx0 else ctx),
tctx.constrs_map,
EnumConstructor.Map.empty )
in
let ctx = if tctx.namespaced_constrs then ctx else ctx1 in
{
tctx with
path_ctx = PathMap.add path ctx path_ctx;
enums_map = EnumName.Map.add ename new_name tctx.enums_map;
constrs_map;
ctx_enums = EnumName.Map.add new_name ctx_constrs tctx.ctx_enums;
}
let cap s = String.to_id s |> String.capitalize_ascii
let uncap s = String.to_id s |> String.uncapitalize_ascii
let program
~reserved
~skip_constant_binders
~constant_binder_name
~namespaced_fields
~namespaced_constrs
~prefix_module
~modnames_conflict
?(f_var = String.to_snake_case)
?(f_struct = cap)
?(f_field = uncap)
?(f_enum = cap)
?(f_constr = cap)
p =
let cfg =
{
reserved;
sanitize_varname = f_var;
skip_constant_binders;
constant_binder_name;
}
in
let ctx = get_ctx cfg in
let type_renaming_ctx =
{
path_ctx = PathMap.empty;
toplevel_module = Option.map fst p.module_name;
prefix_module;
modnames_conflict;
structs_map = StructName.Map.empty;
fields_map = StructField.Map.empty;
enums_map = EnumName.Map.empty;
constrs_map = EnumConstructor.Map.empty;
ctx_structs = StructName.Map.empty;
ctx_enums = EnumName.Map.empty;
namespaced_fields;
namespaced_constrs;
f_struct;
f_field;
f_enum;
f_constr;
}
in
let type_renaming_ctx =
{
type_renaming_ctx with
path_ctx = fst (get_path_ctx p.decl_ctx type_renaming_ctx ctx []);
}
in
let type_renaming_ctx =
TypeIdent.Set.fold
(process_type_ident p.decl_ctx ctx)
p.decl_ctx.ctx_public_types type_renaming_ctx
in
let path_ctx = type_renaming_ctx.path_ctx in
let path_ctx, scopes_map =
ScopeName.Map.fold
(fun name info (path_ctx, scopes_map) ->
let path = ScopeName.path name in
if info.visibility = Private then
path_ctx, scopes_map
else
let str, pos = ScopeName.get_info name in
let str =
if prefix_module then add_module_prefix type_renaming_ctx path str
else str
in
let path_ctx, ctx =
try path_ctx, PathMap.find path path_ctx
with PathMap.Not_found _ -> PathMap.add path ctx path_ctx, ctx
in
let id, ctx = new_id ctx (f_var str) in
let new_name = ScopeName.fresh path (id, pos) in
( PathMap.add path ctx path_ctx,
ScopeName.Map.add name new_name scopes_map ))
p.decl_ctx.ctx_scopes
(path_ctx, ScopeName.Map.empty)
in
let path_ctx, topdefs_map, ctx_topdefs =
TopdefName.Map.fold
(fun name (typ, visibility) (path_ctx, topdefs_map, ctx_topdefs) ->
let path = TopdefName.path name in
if visibility = Private then
( path_ctx,
topdefs_map,
TopdefName.Map.add name (typ, visibility) ctx_topdefs )
else
let str, pos = TopdefName.get_info name in
let str =
if prefix_module then add_module_prefix type_renaming_ctx path str
else str
in
let path_ctx, ctx =
try path_ctx, PathMap.find path path_ctx
with PathMap.Not_found _ -> PathMap.add path ctx path_ctx, ctx
in
let id, ctx = new_id ctx (f_var str) in
let new_name = TopdefName.fresh path (id, pos) in
( PathMap.add path ctx path_ctx,
TopdefName.Map.add name new_name topdefs_map,
TopdefName.Map.add new_name (typ, visibility) ctx_topdefs ))
p.decl_ctx.ctx_topdefs
(path_ctx, TopdefName.Map.empty, TopdefName.Map.empty)
in
let type_renaming_ctx =
let remaining_type_ids =
TypeIdent.Set.diff
(StructName.Map.fold
(fun s _ -> TypeIdent.Set.add (Struct s))
p.decl_ctx.ctx_structs
@@ EnumName.Map.fold
(fun e _ -> TypeIdent.Set.add (Enum e))
p.decl_ctx.ctx_enums TypeIdent.Set.empty)
p.decl_ctx.ctx_public_types
in
TypeIdent.Set.fold
(process_type_ident p.decl_ctx ctx)
remaining_type_ids
{ type_renaming_ctx with path_ctx }
in
let ctx_scopes =
ScopeName.Map.fold
(fun name info ctx_scopes ->
let name =
try ScopeName.Map.find name scopes_map
with ScopeName.Map.Not_found _ -> name
in
let info =
{
in_struct_name =
StructName.Map.find info.in_struct_name
type_renaming_ctx.structs_map;
out_struct_name =
StructName.Map.find info.out_struct_name
type_renaming_ctx.structs_map;
out_struct_fields =
ScopeVar.Map.map
(fun fld ->
StructField.Map.find fld type_renaming_ctx.fields_map)
info.out_struct_fields;
visibility = info.visibility;
}
in
ScopeName.Map.add name info ctx_scopes)
p.decl_ctx.ctx_scopes ScopeName.Map.empty
in
let ctx = PathMap.find [] path_ctx in
let ctx =
set_rewriters ctx
~scopes:(fun n ->
Option.value ~default:n @@ ScopeName.Map.find_opt n scopes_map)
~topdefs:(fun n ->
Option.value ~default:n @@ TopdefName.Map.find_opt n topdefs_map)
~structs:(fun n -> StructName.Map.find n type_renaming_ctx.structs_map)
~fields:(fun n -> StructField.Map.find n type_renaming_ctx.fields_map)
~enums:(fun n -> EnumName.Map.find n type_renaming_ctx.enums_map)
~constrs:(fun n ->
EnumConstructor.Map.find n type_renaming_ctx.constrs_map)
in
let ctx_public_types =
TypeIdent.Set.map
(function
| Struct s ->
Struct (StructName.Map.find s type_renaming_ctx.structs_map)
| Enum s -> Enum (EnumName.Map.find s type_renaming_ctx.enums_map))
p.decl_ctx.ctx_public_types
in
let decl_ctx =
{
p.decl_ctx with
ctx_enums = type_renaming_ctx.ctx_enums;
ctx_structs = type_renaming_ctx.ctx_structs;
ctx_scopes;
ctx_topdefs;
ctx_public_types;
}
in
let decl_ctx = Program.map_decl_ctx ~f:(typ ctx) decl_ctx in
let code_items, ctx = code_items ctx (typ ctx) p.code_items in
{ p with decl_ctx; code_items }, ctx
module type Renaming = sig
val apply : 'e program -> 'e program * context
end
type t = (module Renaming)
let apply (module R : Renaming) = R.apply
let program
~reserved
~skip_constant_binders
~constant_binder_name
~namespaced_fields
~namespaced_constrs
~prefix_module
~modnames_conflict
?f_var
?f_struct
?f_field
?f_enum
?f_constr
() =
let module M = struct
let apply p =
program ~reserved ~skip_constant_binders ~constant_binder_name
~namespaced_fields ~namespaced_constrs ~prefix_module ~modnames_conflict
?f_var ?f_struct ?f_field ?f_enum ?f_constr p
end in
(module M : Renaming)
let default =
program () ~reserved:default_config.reserved
~skip_constant_binders:default_config.skip_constant_binders
~constant_binder_name:default_config.constant_binder_name
~f_var:String.to_snake_case ~f_struct:Fun.id ~f_field:Fun.id ~f_enum:Fun.id
~f_constr:Fun.id ~namespaced_fields:true ~namespaced_constrs:true
~prefix_module:false ~modnames_conflict:false